Doğal sayıların satır


22

Tanım

Sonsuz birleştirilmiş doğal sayı dizisi vardır (1 ile başlayan pozitif tamsayılar):

1234567891011121314151617181920212223...

Meydan okuma

  • Herhangi bir dilde program yazınız, pozisyon numarasını bir giriş olarak kabul eder ve yukarıda belirtilen satırda bu pozisyondan rakam çıkarır.
  • Konum numarası rastgele boyut pozitif tamsayıdır. Bu birinci konum 1, çıkış basamağı '1'
  • Giriş, ondalık sayıya (örn., 13498573249827349823740000191) ya da pozitif tamsayıya karşılık gelen e-notasyonda (örn. 1.2e789).
  • Programın giriş süresi olarak çok büyük bir indeks verilmiş olarak (modern PC / Mac'te 10 saniye) makul bir süre içinde bitmesi gerekir (örn. 1e123456 - bu, 123456 sıfıra sahip 1'dir). Bu nedenle, basit yineleme döngüsü kabul edilemez.
  • Herhangi bir geçersiz giriş yapılırsa, Program 1 sn'de bir hatayla sonlandırılmalıdır. Örneğin. 1.23e (geçersiz) veya 1.23e1 (12.3'e eşittir - bir tamsayı değil)
  • Sayıları ayrıştırmak / saklamak ve üzerlerinde basit matematiksel işlemler yapmak için herkese açık BigNum kütüphanesini kullanmak sorun değil (+ - * / exp). Bayt cezası uygulanmadı.
  • En kısa kod kazanır.

TL; DR

  • Giriş: bignum tamsayı
  • Çıktı: sonsuz satırda bu konumda rakam 123456789101112131415...

Bazı kabul testi durumları

gösterimde "Giriş: Çıkış". Hepsi geçmeli.

  • 1: 1
  • 999: 9
  • 10000000: 7
  • 1e7: 7 (yukarıdaki satırla aynı)
  • 13498573249827349823740000191: 6
  • 1.1e10001: 5
  • 1e23456: 5
  • 1.23456e123456: 4
  • 1e1000000: 0
  • 1.23e: hata (geçersiz sözdizimi)
  • 0: hata (sınırların dışında)
  • 1.23e1: hata (bir tamsayı değil)

Bonus!

Sayının içindeki çıktı hanesi konum numarası ve çıktı sayısının kendisi. Örneğin:

  • 13498573249827349823740000191: 6 24 504062383738461516105596714
    • Bu, '50406238373846151610559 6 714' sayısının 24 konumundaki '6' rakamıdır.
  • 1e1000000: 0 61111 1000006111141666819445...933335777790000
    • Rakam '0' konumundaki 61111 999995 basamaklı uzun sayı Buraya dahil olmayacağım.

Bonus görevi yerine getirirseniz, kodunuzun boyutunu 0,75 ile çarpın

Kredi

Bu görev, 2012 yılında devclub.eu toplantılarından birinde çok sayıda gereklilik olmaksızın verilmiştir. Bu nedenle, gönderilen cevapların çoğu önemsiz döngüler oldu.

İyi eğlenceler!


Gerçekten zorluğun ne olduğunu anlamadım. Girdiyi almamız ve sayıyı o konumda çıkarmamız mı gerekiyor?
The_Basset_Hound


2
@vihan Bazı halk bignum kütüphanelerini kullanmak kabul edilebilir. Penaltı yok. Elbette çözümü kütüphaneye dahil etmek ve kütüphaneyi tek astarda kullanmak hile yapmaktır. Burada sağduyu geçerlidir.
metalim

1
Sadece şaşırtıcı bir şekilde özlü bir F # çözümü göstermek istedim , 44 byte'da. Verilmişse, yalnızca 2 ^ 31-1'e kadar olan endeksleri kullanabilir (ve hala bunu yazarken bu değeri hesaplamaya çalışıyor). Yine de bunu göndermiyorum çünkü gerçekten kuralları çiğniyor, ama F # için oldukça iyi olduğunu söyleyebilirim!
Jwosty

7
Girişleri kullanma gibi gereksinimler, 1.23456e123456bu tür değerleri doğal olarak işleyemeyen dilleri keyfi bir şekilde cezalandırır ve zorlu görev için teğet olan dizgi işlemleri yapmalarını gerektirir.
xnor

Yanıtlar:


12

CJam , 78 bayt

r_A,s-" e . .e"S/\a#[SSS"'./~'e/~i1$,-'e\]s"0]=~~_i:Q\Q=Qg&/
s,:L{;QAL(:L#9L*(*)9/-_1<}g(L)md_)p\AL#+_ps=

Program 104 byte uzunluğunda ve bonusa hak kazanıyor.

Newline tamamen kozmetik. İlk satır girdiyi ayrıştırır, ikincisi çıktıyı oluşturur.

Çevrimiçi deneyin!

Fikir

Herhangi bir pozitif tam sayı için k vardır 9 x 10 k-1 tam pozitif tamsayılardır k basamağı (öncü sıfır hariç). Böylece, hepsini birleştirirsek, 9 × n × 10 k-1 tamsayısı elde ederiz .

Şimdi, n veya daha az basamaklı tüm tamsayıları birleştirmek bir tamsayı verir

formül

basamak.

Belirli bir girdi için q , tespit deneyin en n yukarıda ifade daha küçük olacak şekildedir q . Bu set , n: = ⌈log 10 q⌉-1 , daha sonra n = = ⌈log 10 q⌉-2 , vb arzu edilen ekspresyon daha küçük hale gelene kadar q , elde edilen ifade çıkarma q elde edildi ( R ) ve en son kaydet değeri n olarak l .

r, hemen tüm pozitif tamsayılar birleştirme indeksler belirtir , l + 1 , istenen çıkış olduğu anlamına gelir basamağı, R% (i + 1) inci rakamı / (l + 1) r inci tamsayı l + 1 basamak.

Kod (giriş ayrıştırma)

r_          e# Read from STDIN and duplicate.
A,s-        e# Remove all digits.
" e . .e"S/ e# Push ["" "e" "." ".e"].
\a#         e# Compute the index of the non-digit part in this array.

[SSS"'./~'e/~i1$,-'e\]s"0]

            e# Each element corresponds to a form of input parsing:
            e#   0 (only digits): noop
            e#   1 (digits and one 'e'): noop
            e#   2 (digits and one '.'): noop
            e#   3 (digits, one '.' then one 'e'):
            e#     './~    Split at dots and dump the chunks on the stack.
            e#     'e/~    Split the and chunks at e's and dump.
            e#     i       Cast the last chunk (exponent) to integer.
            e#     1$      Copy the chunk between '.' and 'e' (fractional part).
            e#     ,-      Subtract its length from the exponent.
            e#     'e\     Place an 'e' between fractional part and exponent.
            e#     ]s      Collect everything in a string.
            e#   -1 (none of the above): push 0

~           e# For s string, this evaluates. For 0, it pushes -1.
~           e# For s string, this evaluates. For -1, it pushes 0.
            e# Causes a runtime exception for some sorts of invalid input.
_i:Q        e# Push a copy, cast to Long and save in Q.
\Q=         e# Check if Q is numerically equal to the original.
Qg          e# Compute the sign of Q.
&           e# Logical AND. Pushes 1 for valid input, 0 otherwise.
/           e# Divide by Q the resulting Boolean.
            e# Causes an arithmetic exception for invalid input.

Kod (çıktı üretimi)

s,:L     e# Compute the number of digits of Q and save in L.
{        e# Do:
  ;      e#   Discard the integer on the stack.
  Q      e#   Push Q.
  AL(:L# e#   Push 10^(L=-1).
  9L*(   e#   Push 9L-1.
  *)     e#   Multiply and increment.
  9/     e#   Divide by 9.
  -      e#   Subtract from Q.
  _1<    e#   Check if the difference is non-positive.
}g       e# If so, repeat the loop.
(        e# Subtract 1 to account for 1-based indexing.
L)md     e# Push quotient and residue of the division by L+1.
_)p      e# Copy, increment (for 1-based indexing) and print.
\AL#+    e# Add 10^L to the quotient.
_p       e# Print a copy.
s        e# Convert to string.
2$=      e# Retrieve the character that corresponds to the residue.

5

CJam, 75 * 0.75 = 56.25

Bu oldukça hızlı, istenen konumu içeren sayının basamağı başına bir yineleme. Çok daha fazla golf oynayabileceğine eminim, olduğu gibi çok kaba.

q~_i_@<{0/}&:V9{VT>}{T:U;_X*T+:T;A*X):X;}w;U-(_X(:X/\X%10X(#@+s_2$\=S+@)S+@

Konumu giriş olarak verin, çıkış:

<digit> <position> <full number>

Çevrimiçi deneyin .


@Dennis Tüm girdilerle şimdi çalışma :)
Andrea Biondo 17

Bu hala (olması gerektiği gibi) için bir hata yaratmıyor 1.23e1. Bununla birlikte, 1.23456e123456giriş, bir Double ile temsil edilemeyeceğinden hata yapar . Ayrıca, son test durumları 3 dakika sürer.
Dennis,

2
@Dennis Şimdi hatayı yükseltir. Büyük sınav davası gelince ... Kahretsin. Her şeyi yeniden yazmak zorunda kalabilirim.
Andrea Biondo
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.