Bilangan Pirrasional

14

Pi adalah bilangan irasional , yang berarti bahwa representasi desimalnya tidak pernah berakhir atau terulang.

Pi terpotong menjadi 41 angka desimal (40 tempat) 3.1415926535897932384626433832795028841971.

Jika kita mengabaikan titik desimal dan mendaftar angka sebagai urutan bilangan bulat positif, menghindari duplikat , kita dapatkan 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 ).
(Perhatikan yang 15muncul dalam urutan bukan 1 5karena 1sudah terjadi.
Juga perhatikan yang 0tidak terjadi karena tidak positif; 950berisi nol pertama.)

Untuk membangun angka pirasional pertama, kami menggunakan urutan ini untuk mengindeks ke dalam digit Pi (digit pertama adalah 3, angka kedua 1, dll.).

Jadi digit pertama dari angka pirrasional pertama adalah digit ke-3 Pi,
digit kedua adalah digit pertama Pi,
digit ketiga adalah digit ke-4 Pi, digit
keempat adalah digit ke - 15 Pi,
dan seterusnya.
Titik desimal ditambahkan setelah digit pertama untuk meniru Pi.

Dengan demikian angka pirrasional pertama hingga 41 digit adalah 4.3195195867462520687356193644029372991880.
(Perhatikan bahwa untuk digit ke-30 saya harus terus ke digit ke-974 dari Pi.)

Untuk membangun bilangan pirasional kedua, prosesnya diulangi menggunakan bilangan pirasional pertama alih-alih Pi. (Pi itu sendiri dapat disebut angka pirerasional nol). Jadi urutan baru adalah 4 3 1 9 5 19 58 ...dan nomor piirasional pertama diindeks untuk menghasilkan yang kedua, yang dimulai 9.14858....

Bilangan pirasional lebih lanjut dibuat dengan cara yang sama, masing-masing dihasilkan dari yang sebelumnya.

Tantangan

Tugas Anda adalah menulis program sesingkat mungkin yang menggunakan dua bilangan bulat, Ndan D, dan menampilkan Nbilangan pirasional ke Dangka desimal.

Dselalu positif tetapi Ntidak negatif, dan Dangka-angka Pi harus dikeluarkan ketika N0.
Ketika D1 adalah tidak masalah apakah titik desimal ada atau tidak.

Input harus berasal dari stdin atau baris perintah dan output harus pergi ke stdout (atau alternatif terdekat bahasa Anda).

Program Anda harus bekerja untuk semua nilai input dari Ndan di Dbawah 2 16 , tetapi tidak harus tepat waktu atau efisien.

Kode terpendek dalam byte menang.

(Perhatikan bahwa angka-angka pembajakan keluar di pangkalan lain, tetapi segala sesuatu dalam tantangan ini dilakukan di pangkalan 10.)

Hobi Calvin
sumber
Bisakah kita menggunakan built-in representasi sewenang-wenang-presisi Pi untuk mendapatkan nya digit?
Martin Ender
1
@ MartinBüttner Tentu. Anda bahkan bisa mendapatkan digit pi online jika Anda mau selama Anda hanya mendapatkan digit pi.
Calvin Hobbies
@ Calvin'sHobbies: Ah bagus, jadi saya bisa mendapatkan 64ki digit pertama pi dalam sebuah file? Haruskah saya menambahkan +1 untuk nama file?
Claudiu
Apakah rentang input itu benar? Untuk N=1, D=13393misalnya, Anda akan perlu digit 31 sepersejuta PI
Claudiu
1 miliar digit pertama pi hanya memberi Anda 42.598 digit angka bajak laut pertama
Claudiu

Jawaban:

3

Python 292 byte

Cukup tidak efisien, saya hanya bisa mendapatkan beberapa digit N = 3 dan tidak ada 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:]

Input sampel:

0,20
3.1415926535897932384

1,20
4.3195195867462520687

2,10
9.148583196

3,5
9.9815
KSab
sumber
Golf: Ubah =="0"ke <"1". Buat bagian dalam sambil melingkar satu baris. Hapus spasi di sekitar x += 1. if l not in h-> if(l in h)<1: N==0->N<1
isaacg
@isaacg Terima kasih untuk itu, saya agak terburu-buru ketika saya memposting dan melewatkan beberapa hal yang jelas. Saya mungkin tidak akan menyadari Anda bisa melakukan perbandingan string dan if(l in h)<1juga cukup pintar.
KSab
Beberapa lainnya: Inisialisasi ssebagai parameter P( def P(N,D,s=''):). str(...)mungkin dapat ditulis dengan backticks. while'1'>...menghemat ruang. Buat hsatu set dan inisialisasi dengan h=l,={''}, lalu tulis l in hsebagai {l}<h.
flornquake
@flakequake Itu cukup pintar, terutama cara Anda menginisialisasi sehingga python tidak menganggapnya sebagai dict. Ketika saya memasukkan ini, saya menyadari optimasi yang cukup besar yang sayangnya perlu hdipesan. Tetap saja, itu trik yang rapi yang akan saya coba dan ingat.
KSab
@ KSab Itu bahkan lebih baik. :) while j+1:dapat disingkat menjadi while-~j, btw.
flornquake
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

Harus mencintai daftar yang tak terbatas! Diberi cukup waktu dan memori, program ini pada akhirnya akan menghitung jawaban yang tepat untuk N dan D (saya berasumsi).

Saya menghasilkan digit pi dengan gmenggunakan algoritma keran (tanpa malu dicuri dari seorang pria bernama Stanley Rabinowitz), mengelompokkan digit / membuat urutan menggunakan vdan menghasilkan nomor bajakan dari penggunaan ini m.

Ini dia sedang beraksi:

λ> 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
sumber
1
Saya pikir, "Haskell!" ketika saya melihat pertanyaan, gulir ke bawah, dan tersenyum.
Soham Chowdhury