Mengingat bilangan bulat positif n dan sejumlah satu , yang n th tetration dari sebuah didefinisikan sebagai suatu ^ ( a ^ ( a ^ (... ^ a ))), di mana ^ menunjukkan exponentiation (atau kekuasaan) dan ekspresi berisi angka yang tepat n kali.
Dengan kata lain, tetrasi adalah eksponensiasi iterasi yang diasosiasikan dengan benar. Untuk n = 4 dan a = 1.6 tetrasi adalah 1.6 ^ (1.6 ^ (1.6 ^ 1.6)) ≈ 3.5743.
Fungsi kebalikan dari tetrasi terhadap n adalah super-logaritma . Pada contoh sebelumnya, 4 adalah super-logaritma 3.5743 dengan "super-base" 1.6.
Tantangan
Dengan bilangan bulat positif n , temukan x sedemikian rupa sehingga n adalah super-logaritma itu sendiri dalam super-basis x . Yaitu, temukan x sedemikian sehingga x ^ ( x ^ ( x ^ (... ^ x )))) (dengan x muncul n kali) sama dengan n .
Aturan
Program atau fungsi diizinkan.
Format input dan output fleksibel seperti biasa.
Algoritme secara teoritis harus bekerja untuk semua bilangan bulat positif. Dalam praktiknya, input mungkin terbatas pada nilai maksimum karena batasan memori, waktu atau tipe data. Namun, kode harus bekerja untuk input hingga 100
setidaknya dalam waktu kurang dari satu menit.
Algoritme secara teoritis harus memberikan hasil dengan 0.001
presisi. Dalam praktiknya, ketepatan output mungkin lebih buruk karena akumulasi kesalahan dalam perhitungan numerik. Namun, hasilnya harus akurat hingga 0.001
untuk kasus uji yang ditunjukkan.
Kode terpendek menang.
Uji kasus
1 -> 1
3 -> 1.635078
6 -> 1.568644
10 -> 1.508498
25 -> 1.458582
50 -> 1.448504
100 -> 1.445673
Implementasi referensi
Berikut ini adalah implementasi referensi di Matlab / Oktaf (coba di Ideone ).
N = 10; % input
t = .0001:.0001:2; % range of possible values: [.0001 .0002 ... 2]
r = t;
for k = 2:N
r = t.^r; % repeated exponentiation, element-wise
end
[~, ind] = min(abs(r-N)); % index of entry of r that is closest to N
result = t(ind);
disp(result)
Untuk N = 10
ini memberi result = 1.5085
.
Kode berikut adalah pemeriksaan dari presisi keluaran, menggunakan aritmatika presisi-variabel:
N = 10;
x = 1.5085; % result to be tested for that N. Add or subtract 1e-3 to see that
% the obtained y is farther from N
s = num2str(x); % string representation
se = s;
for n = 2:N;
se = [s '^(' se ')']; % build string that evaluates to iterated exponentiation
end
y = vpa(se, 1000) % evaluate with variable-precision arithmetic
Ini memberi:
- Untuk
x = 1.5085
:y = 10.00173...
- Untuk
x = 1.5085 + .001
:y = 10.9075
- Untuk
x = 1.5085 - .001
itu memberiy = 9.23248
.
begitu 1.5085
juga solusi yang valid dengan .001
presisi.
x
konvergenn
mendekati infinity?Jawaban:
Dyalog APL ,
3325 byteKebutuhan
⎕IO←0
yang standar pada banyak sistem.Secara teoritis menghitung untuk semua bilangan bulat, tetapi praktis terbatas pada yang sangat kecil saja.
TryAPL online!
sumber
Haskell,
555452 bytePemakaian:
Terima kasih kepada @nimi untuk 1 byte!
Terima kasih kepada @xnor untuk 2!
sumber
[ ]!!0
bukannyahead[ ]
menyimpan bytes n=[x|x<-[2,1.9999..],n>iterate(x**)1!!n]!!0
akan lebih pendek jika Anda bisa membuat Haskell menerima tipenya.Javascript, ES6: 77 byte / ES7:
5753 byteES6
ES7
Menggunakan
**
seperti yang disarankan oleh DanTheMan:Contoh
sumber
**
sebagai gantinyaMath.pow
.Mathematica,
4033 byteBerkat murphy untuk penghematan hampir 20%!
Nest[x^#&,1,n]
menghasilkan tetrasi ke-n x. JadiNest[x^#&,1,#]<#
menguji apakah (input) tetrasi x kurang dari (input). Kita cukup mulai dari x = 1 dan menambahkan 0,001 berulang kali hingga tetrasinya terlalu besar, kemudian mengeluarkan nilai x terakhir (jadi jawabannya dijamin lebih besar dari nilai yang tepat, tetapi dalam 0,001).Karena saya perlahan-lahan belajar:
//.x_:>y/;z
atau//.x_/;z:>y
berarti "mencari apa pun yang cocok dengan templat x, tetapi hanya hal-hal di mana tes z mengembalikan true; dan kemudian beroperasi pada x oleh aturan y; berulang kali sampai tidak ada perubahan". Di sini templatnyax_
hanyalah "angka apa pun yang saya lihat", meskipun dalam konteks lain hal itu dapat dibatasi lebih lanjut.Ketika input minimal 45, tetrasi meningkat begitu cepat sehingga langkah terakhir menyebabkan kesalahan overflow; tetapi nilai x masih diperbarui dan dikeluarkan dengan benar. Mengurangi ukuran langkah dari 0,001 menjadi 0,0001 memperbaiki masalah ini untuk input hingga 112, dan memberikan jawaban yang lebih tepat untuk mem-boot (dan masih berjalan cepat, dalam sekitar seperempat detik). Tapi itu satu byte tambahan, jadi lupakan itu!
Versi asli:
sumber
1//.x_:>x+.001/;Nest[x^#&,1,#]<#&
//.
tanpa bantuan :)J,
393128 byteBerdasarkan implementasi referensi. Hanya akurat untuk tiga tempat desimal.
Disimpan 8 byte menggunakan metode dari solusi @ Adám .
Pemakaian
Perintah tambahan digunakan untuk memformat beberapa input / output.
Penjelasan
sumber
Python, 184 byte
Hasil uji (melewatkan pernyataan cetak yang sebenarnya):
sumber
s(1000000)
cukup cepatRacket 187 byte
Pengujian:
Keluaran:
Versi detail:
sumber
Perl 6 , 42 byte
(Terjemahan kode Matlab misalnya)
Uji:
sumber
PHP, 103 Bytes
sumber
Aksioma 587 byte
lebih sedikit nomor + golf
sumber
Gangguan Umum, 207 byte
Menggunakan
reduce
dengan:from-end t
menghindari perlunya melakukan lambda antara "membalikkan eksponensial" (pada dasarnya(lambda (x y) (expt y x))
, menghemat 14 byte (12, jika Anda menghapus ruang yang dapat dilepas).Kita masih perlu menangani float overflow, tetapi suatu
ignore-errors
formulir kembalinil
jika terjadi kesalahan, sehingga kita dapat menggunakanor
untuk memberikan nilai default.sumber