Liczby pirackie

14

Pi jest liczbą nieracjonalną , co oznacza, że ​​jego reprezentacja dziesiętna nigdy się nie kończy ani się nie powtarza.

Pi jest obcięty do 41 cyfr dziesiętnych (40 miejsc) 3.1415926535897932384626433832795028841971.

Jeśli zignorujemy przecinek dziesiętny i wymienimy cyfry jako ciąg dodatnich liczb całkowitych, unikając duplikatów , otrzymamy 3 1 4 15 9 2 6 5 35 8 97 93 23 84 62 64 33 83 27 950 28 841 971( OEIS A064809 ).
(Zauważ, że 15pojawia się w sekwencji zamiast, 1 5ponieważ 1już wystąpił.
Zauważ też, że 0nie występuje, ponieważ nie jest dodatni; 950zawiera pierwsze zero.)

Aby skonstruować pierwszą liczbę piracyjną , używamy tej sekwencji do indeksowania cyfr Pi (pierwsza cyfra to 3, druga 1 itd.).

Pierwsza cyfra pierwszego numeru pirracyjnego to trzecia cyfra Pi,
druga cyfra to pierwsza cyfra Pi,
trzecia cyfra to czwarta cyfra Pi,
czwarta to piętnasta cyfra Pi
i tak dalej.
Kropka dziesiętna jest dodawana po pierwszej cyfrze, aby naśladować Pi.

Tak więc jest to pierwsza liczba piracka licząca do 41 cyfr 4.3195195867462520687356193644029372991880.
(Zauważ, że dla 30 cyfry musiałem przejść do 974 cyfry Pi.)

Aby skonstruować drugą liczbę piracyjną, proces powtarza się przy użyciu pierwszej liczby piracyjnej zamiast Pi. (Sam Pi można nazwać zerową liczbą piracyjną.) Tak więc nowa sekwencja jest, 4 3 1 9 5 19 58 ...a pierwsza liczba piiracyjna jest indeksowana w celu uzyskania drugiej, która się rozpoczyna 9.14858....

Dalsze liczby pirackie są tworzone w ten sam sposób, a każda z nich jest generowana z poprzedniej.

Wyzwanie

Twoim zadaniem jest napisać najkrótszy program, który odbywa się w dwóch liczb całkowitych, Ni D, i wysyła Nth numer pirrational obciętyD dziesiętnej cyfry.

Djest zawsze dodatnia, ale Nnieujemna, a Dcyfry Pi powinny być wyprowadzane, gdy Nwynosi 0.
KiedyD wynosi 1, nie ma znaczenia, czy przecinek dziesiętny jest obecny, czy nie.

Dane wejściowe powinny pochodzić ze stdin lub wiersza poleceń, a dane wyjściowe powinny przejść do stdout (lub najbliższych alternatywnych języków).

Twój program powinien działać dla wszystkich wartości wejściowych Ni Dponiżej 2 16 , ale nie musi być aktualny ani wydajny.

Najkrótszy kod w bajtach wygrywa.

(Pamiętaj, że liczby pirackie wychodzą z innych baz, ale wszystko w tym wyzwaniu odbywa się w bazie 10.)

Hobby Calvina
źródło
Czy możemy użyć wbudowanych reprezentacji Pi o dowolnej dokładności, aby uzyskać jego cyfry?
Martin Ender
1
@ MartinBüttner Sure. Możesz nawet uzyskać cyfry pi online, jeśli chcesz, o ile tylko dostaniesz cyfry pi.
Calvin's Hobbies
@ Calvin'sHobbies: Ach miło, więc mogę mieć tylko 64-cyfrowe cyfry pi w pliku? Czy powinienem dodać +1 do nazwy pliku?
Claudiu
Czy ten zakres wejściowy jest prawidłowy? Dla N=1, D=13393na przykład, że trzeba cyfrę 31 milionowa PI
Claudiu
Pierwsze 1 miliard cyfr pi daje ci tylko 42 598 cyfr z 1. numeru piracyjnego
Claudiu

Odpowiedzi:

3

Python 292 bajtów

Dość nieefektywny, udało mi się uzyskać tylko kilka cyfr N = 3 i żadnej z N = 4.

import sympy
def P(N,D,s=''):
 if N<1:return'3'+`sympy.pi.evalf(D+9)`[2:-9]
 for i in range(D):
    h=[];l='';j=i;x=0
    while-~j:
     x+=1;d=P(N-1,x)[-1];l+=d
     while'1'>P(N-1,x+1)[-1]:x+=1;l+='0'
     if(l in h)<1:h+=[l];l='';j-=1
    s+=P(N-1,int(h[i]))[-1]
 return s
s=P(*input())
print s[0]+'.'+s[1:]

Przykładowe dane wejściowe:

0,20
3.1415926535897932384

1,20
4.3195195867462520687

2,10
9.148583196

3,5
9.9815
KSab
źródło
Golf: Zmień =="0"na <"1". Zrób pętlę while podczas jednej linii. Usuń spacje wokół x += 1. if l not in h-> if(l in h)<1: N==0->N<1
isaacg
@isaacg Dzięki za te, byłem w pośpiechu, kiedy pisałem i przegapiłem kilka oczywistych rzeczy. Prawdopodobnie nie zdawałbym sobie sprawy, że możesz zrobić porównanie ciągów i if(l in h)<1jest to również dość sprytne.
KSab
Trochę więcej: Zainicjuj sjako parametr P( def P(N,D,s=''):). str(...)można prawdopodobnie napisać za pomocą backticksa. while'1'>...oszczędza miejsce Zrób hzestaw i zainicjuj go h=l,={''}, a następnie napisz l in hjako {l}<h.
trzęsienie ziemi
@flornquake To całkiem sprytne, szczególnie sposób, w jaki go inicjujesz, aby python nie uważał go za dyktando. W tym momencie zdałem sobie sprawę z dość dużej optymalizacji, która niestety wymagała hzamówienia. Mimo to to fajna sztuczka, którą spróbuję zapamiętać.
KSab
@KSab To jeszcze lepiej. :) while j+1:można skrócić do while-~j, przy okazji.
trzęsienie ziemi
4

Haskell, 431 400 369

import Data.List
g(q,r,t,k,n,l)|4*q+r-t<n*t=n:g(q#0,(r-n*t)#0,t,k,div(r#(30*q))t-n#0,l)|1<2=g(q*k,(2*q+r)*l,t*l,k+1,div(q*(7*k+2)+r*l)(t*l),l+2)
u w@(x:y:xs)=x:v y xs 0 w
v a(r:s)n w|a`elem`take n(u w)||r==0=v(a#r)s n w|1<2=a:v r s(n+1)w
m p=map(genericIndex p.pred)$u p
a#b=a*10+b
(x:s)%n=show x++'.':show(foldl1(#)$n`take`s)
f n d=print$iterate m(g(1,0,1,1,3,3))!!n%d

Uwielbiam nieskończone listy! Biorąc pod uwagę wystarczającą ilość czasu i pamięci, ten program ostatecznie obliczy właściwą odpowiedź dla dowolnego N i D (zakładam).

Generuję cyfry pi za gpomocą algorytmu czopowego (bezwstydnie skradzionego facetowi o nazwisku Stanley Rabinowitz), grupując cyfry / tworząc sekwencję za pomocą vi generując z nich liczbę piracyjnąm .

Oto jest w akcji:

λ> f 0 10
"3.1415926535"
λ> f 1 10
"4.3195195867"
λ> f 2 10
"9.Interrupted. --didn't have the time to wait for this to finish
λ> f 2 4
"9.1485"
Flonk
źródło
1
Myślałem „Haskell!” kiedy zobaczyłem pytanie, przewinąłem w dół i uśmiechnąłem się.
Soham Chowdhury,