Hitung A (N) / B (N) dengan digit C (N)

15

Pertimbangkan tiga urutan nomor A,, Bdan C:

  • A: Urutan berdasarkan hubungan perulangan f(n) = f(n-1)+f(n-2),, dimulai dengan f(1) = 3, f(2) = 4. Jadi, urutannya dimulai seperti ini:3 4 7 11 18 29 47 76 ...
  • B: Angka komposit , yaitu semua bilangan bulat yang bukan bilangan prima (atau 1):4 6 8 9 10 12 14 15 16 ...
  • C: Digit Pi: 3 1 4 1 5 9 2 6 5 ...

Diberikan bilangan bulat positif N < 50, baik sebagai argumen fungsi atau STDIN, kembalikan nilai desimal fraksi A(N)/B(N)dengan C(N)angka setelah titik desimal. Aturan normal untuk pembulatan berlaku (bulatkan jika digit N +1 adalah 5 atau lebih tinggi). Jika digit ke-N piadalah nol, bilangan bulat harus dicetak. notasi ilmiah / bentuk Standar diterima untuk angka yang lebih tinggi dari 1000.

Ini kode golf, jadi jawaban tersingkat dalam byte menang.

Beberapa contoh:

N = 1: 0.750
N = 2: 0.7
N = 3: 0.8750
N = 4: 1.2
N = 6: 2.416666667
N = 10: 11.056
N = 20: 764.8750

Tentu saja, aturan golf kode standar berlaku.

Fungsi ini harus berakhir dalam waktu kurang dari dua menit pada laptop modern mana pun.

Stewie Griffin
sumber
Ketika Anda mengatakan C(n)angka, apakah kita harus menyertakan trailing 0?
Maltysen
Untuk input mana batasan waktu berlaku?
Dennis
@ Dennis, maksud Anda yang mana N? Jika demikian, hingga N = 49. Atau yang lain?
Stewie Griffin
JavaScript memiliki akurasi floating point terbatas 16. Sebelumnya Anda akan mulai mendapatkan hasil yang tidak akurat. Apakah ini baik?
Downgoat
1
@vihan Solusi saya (ATM tidak dipublikasikan) menyimpan 49 digit pi pertama dalam sebuah string. Dan Anda tidak perlu lebih dari 9 digit akurasi dalam hasilnya, jika Anda khawatir tentang itu.
ETHproduk

Jawaban:

9

Pyth, 60 57 58 byte

.[K`.Rchu,eGsGQjT7e.ftPZQ)Je/u+/*GHhyHy^TQr^T3ZZT\0+xK\.hJ

Uji harness

Ini cukup mudah - menghitung pi, deret fibonacci dan komposit, bulat ke C (n) digit, pad ke C (n) digit plus lokasi angka titik desimal, selesai.

Sebuah): hu,eGsGQjT7

B (n): e.ftPZQ)

C (n): e/u+/*GHhyHy^TQr99ZZT

60 -> 57: Membersihkan n = 1 kasus khusus dalam perhitungan pi.

57 -> 58: Tidak menggunakan precsion yang cukup tinggi untuk pi untuk seluruh rentang input - meningkatkan 99 iterasi menjadi 1000 iterasi.

Catatan tentang pembulatan: Ini menggunakan sistem pembulatan "bahkan terdekat" Python, daripada OP yang ditentukan sistem "menuju tak terhingga". Namun, perbedaannya hanya penting jika digit segera setelah titik pembulatan 5000..., misalnya 1,25 dibulatkan menjadi 1 digit. Saya memeriksa rentang input, dan ini tidak pernah terjadi, sehingga hasil yang benar selalu dikembalikan.

isaacg
sumber
2

PowerShell, 420 Bytes (ayyyyyyyy) 378 Bytes

param($n);[int[]]$p="03141592653589793238462643383279502884197169399375"-Split'';$a=@(0,3,4);for($i=3;$i-lt50;$i++){$a+=$a[$i-1]+$a[$i-2]};$c=[char[]]"00001010111010111010111011111010111110111010111011111011111010111110111";$b=@(0);for($i=4;$i-le70;$i++){if($c[$i]-eq'1'){$b+=$i}};[double]$r=$a[$n]/$b[$n];$q=$p[$n+1];$s="";(0..($q-1))|%{$s+="0"};([math]::Round($r,$q,[MidpointRounding]::AwayFromZero)).ToString("0.$s")

Terima kasih kepada isaacg untuk menghemat 41 byte, karena menghitung bagaimana pertanyaannya membulatkan. Berarti saya tidak harus memasukkan yang menghebohkan [MidpointRounding]::AwayFromZerodan tidak perlu secara eksplisit berperan sebagai a [double].

Yang ini sangat menyenangkan!

Diperluas:

# Take input N
param($n)

# First digits of pi, stored as integer array
[int[]]$p="03141592653589793238462643383279502884197169399375"-Split''

# Fibonacci sequence A(N)
$a=@(0,3,4)
for($i=3;$i-lt50;$i++){
  $a+=$a[$i-1]+$a[$i-2]
}

# Zero-indexed bitmask for if the n-th integer is composite (1) or not (0)
$c=[char[]]"00001010111010111010111011111010111110111010111011111011111010111110111"

# Populate B(N) as an array using the $c mask
$b=@(0)
for($i=4;$i-le70;$i++){
  if($c[$i]-eq'1'){
    $b+=$i
  }
}

# Calculation Time!
$r=(a($n))/$b[$n]

# A small golf, as $p[$n+1] gets used a couple times
$q=$p[$n+1]

# Need to generate a string of zeroes for padding
$s=""
(0..($q-1))|%{$s+="0"}

# Round the number, then send it to a string so we get the necessary number of zeroes
([math]::Round($r,$q)).ToString("0.$s")

Rekursi dalam PowerShell adalah ... lambat, haruskah kita katakan, jadi kita harus membangun A(N)arah lain dan menyimpannya ke dalam array, lalu mengindeksnya.


TUA

Juga, sapi suci, apakah persyaratan output membunuh ini. PowerShell secara default adalah pembulatan ke / a / k / pembulatan bankir, yang mengharuskan penggunaan verbose luar biasa [MidpointRounding]::AwayFromZerountuk mengubah gaya pembulatan . Di atas semua itu, kita kemudian perlu untuk membuntuti angka nol, jika ada. Kedua persyaratan tersebut digabungkan untuk mengubah beberapa baris terakhir dari 20 Bytes [math]::Round($r,$q) menjadi 102 Bytes (dari $s=""ke +$s)) ... wow.

AdmBorkBork
sumber
Deskripsi / komentar hebat! 32 karakter [MidpointRounding]::AwayFromZerosendirian hampir terlalu baik / buruk untuk menjadi kenyataan ... =)
Stewie Griffin
1
Lihat catatan saya pada pembulatan jawaban saya. Pembulatan default PowerShell harus baik-baik saja.
isaacg
1

Javascript (ES6), 302 byte

Satu kata: Belum Selesai.

x=>{a=[0,3,4],b=[0],c='03141592653589793238462643383279502884197169399375';for(i=1;i<x;a[i+2]=a[i]+a[++i]);for(i=1,p=[];++i<70;v=p.every(x=>i%x),(v?p:b).push(i));r=''+Math.round(a[x]/b[x]*(l=Math.pow(10,c[x])))/l;if(x==33)return r;r.indexOf`.`<0&&(r+='.');while(!r[r.indexOf`.`+ +c[x]])r+='0';return r}

49 digit pi pertama disimpan dalam string, dan dua urutan lainnya dihasilkan secara otomatis. Ini telah golf sekitar setengahnya; Saya (hampir) yakin saya bisa memeras 50 byte lagi dari itu.

Bekerja untuk semua kasus uji, dan harus bekerja untuk yang lain. Gangguan pada sesuatu yang lebih dari 49 atau kurang dari 0 (toh seharusnya tidak pernah menghadapi situasi ini). Saya terutama menyukai hasilnya untuk 0:

NaN.
Produksi ETH
sumber
Mengapa ini belum selesai?
Beta Decay
@BetaDecay maksud saya saya belum selesai bermain golf. Saya akan segera setelah saya punya waktu.
ETHproduk
1

Oktaf, 276 236 Bytes

Pertama-tama saya pikir itu akan keren untuk menggunakan keakuratan tak terbatas dalam alat matematika ini (dan untuk menyegarkan pengetahuan tentang hal itu) jadi saya mulai menulis beberapa algoritma dan kemudian akhirnya menemukan bahwa pinilainya tidak begitu akurat sehingga saya harus menggunakan array lagi. Jadi sekali lagi, tidak ada kesuksesan besar:

function c(A)p="3141592653589793238462643383279502884197169399375";f=ones (1,50);f(1)=3;f(2)=4;for i=3:53f(i)=f(i-1)+f(i-2);end
i=0;x=1;while i<A
x++;for j=2:x/2
if mod(x,j)==0 i++;break;end end end
printf(["%." p(A) "f\n"],f(A)/x);end

Masih cukup mudah dibaca, bukan?

Pemakaian

fungsi copy-paste ke oktaf, fungsi panggilan cdengan argumen dari nilai yang diperlukan:

>>> c(1)
0.750
>>> c(49)
407880480.04348

Optimasi:

  • Pengganti endif, endfordan serupa dengan endyang bekerja dengan cara yang sama
  • mengurangi variabel idengan satu simpan satu byte
  • hapus num2str(str2num(p(A)))omong kosong :)
Jakuje
sumber
Saya suka bahwa Anda memposting solusi Octave (Saya seorang pria MATLAB sendiri!). Perhatikan bahwa kode ini hanya Oktaf, bukan MATLAB. MATLAB menggunakan end, tidak endif, banyak byte yang disimpan. Jika anda juga kebetulan memiliki toolbox simbolis untuk MATLAB, Anda dapat menggunakan vpauntuk mendapatkan poin yang cukup desimal untuk pi: vpa(sym(pi),49). Saya tidak memilikinya di laptop ini, jadi saya tidak yakin apakah symitu diperlukan di sana, tetapi harus menyimpan beberapa byte =) Dan dapat dibaca tidak selalu merupakan hal yang baik dalam kode golf =)
Stewie Griffin
x ++ juga bukan perintah MATLAB. Saya tidak tahu ada perbedaan besar antara keduanya ... IMO, seharusnya tidak. Saya pikir semua kode yang ditulis dalam Oktaf harus portabel untuk MATLAB (tetapi tidak harus sebaliknya karena MATLAB memiliki lebih banyak pilihan).
Stewie Griffin
Menyetujui hasil edit Anda. Saya tidak punya matlab di sini jadi saya tidak bisa mengujinya. Saya sedang mencari solusi untuk mendapatkan lebih banyak desimal pi dalam oktaf, tetapi tidak ada yang lebih pendek dari sekadar array, sayangnya. Tapi berhenti whiledari endwhiledan sejenisnya berfungsi dengan baik, jadi saya memperbarui jawabannya dengan beberapa karakter lebih sedikit :)
Jakuje