Saya menyadari bahwa ini sedikit matematika-y, tetapi - begini saja.
Dalam matematika, urutan hiperoperasi adalah urutan tak terbatas dari operasi aritmatika (disebut hiperoperasi) yang dimulai dengan operasi penerus unary, kemudian dilanjutkan dengan operasi biner penambahan, perkalian, dan eksponensial, setelah itu urutan dilanjutkan dengan operasi biner lebih lanjut yang melampaui eksponensial, menggunakan asosiatif-kanan.
Tujuan Anda adalah untuk menulis sebuah program yang mengambil tiga bilangan bulat x, y dan n sebagai input dan output hasil dari n operasi ke-n pada x dan y.
Misalnya
1 1 1
output 2
2 4 4
keluaran 65536
3 3 4
keluaran 7625597484987
- Program harus ditulis dalam bit kode terpendek.
- Anda dapat mengambil input baik dari
STDIN
atau dari file. - Fungsi perpustakaan tidak diizinkan.
- Batasan input: n akan menjadi ≥ 1.
http://en.wikipedia.org/wiki/Tetration memiliki penjelasan yang baik jika Anda tidak dapat memahami hal ini.
sumber
n=1
? Jikax+y
ataux+1
,1 1 1
harus kembali2
Jawaban:
Ruby, lambat,
86 8483 karakterRuby, cepat,
96 9493 karakterVersi pertama adalah cara terlalu lambat dengan kasus tes terakhir, jadi saya menambahkan versi yang menggunakan perkalian sebagai kasus dasar bukan penambahan. Versi pertama membutuhkan waktu lama untuk menghitung
3 3 4
; yang kedua adalah instan (di konsol IRB asli; versi web sedikit lebih lambat).Beberapa keindahan Ruby muncul di sini:
Hampir setiap pernyataan adalah ekspresi dalam ruby. Dengan demikian, Anda dapat memasukkan titik koma di dalam operator ternary, asalkan Anda memiliki cukup tanda kurung di sekitarnya. Coffeescript meminjam yang itu. Itu juga meminjam sintaks panggilan "tidak perlu paren" Ruby.
Pengembalian tersirat: ini adalah fitur keren, dan mengikuti dari sebelumnya. Memang, memulai baris terakhir dari suatu fungsi dengan
return
dianggap lumpuh, bahkan ketika tidak bermain golf.Bilangan adalah objek dalam ruby (bahkan
null
objek). Dalam ruby, integer memiliki metodetimes
, yang mengeksekusi blok yang diteruskan ke sana beberapa kali. Ini hanyalah salah satu dari banyak metode iterator Ruby. Di sini,upto
metode ini memungkinkan kita menyimpan dua karakter lebih dari apa yangtimes
memungkinkan kita.unary
*
adalah operator percikan di sini. Itu mengubah array menjadi daftar argumen. Sama seperti JavascriptFunction#apply
, tetapi lebih pendek dan lebih baik.unary
&
mengubah prosedur menjadi blok. Meskipun:to_i
merupakan simbol, itu dikonversi menjadi prosedur yang cukup baik. Yaitu, itu berubah menjadi prosedur yang memanggilto_i
argumennya dan mengembalikan hasilnya. Informasi lebih lanjut tentang Stack Overflow.Mungkin saja untuk membuatnya lebih cepat dengan menggunakan
n=3
sebagai alas, tapi saya khawatir tidak diperlukan. Namun, ini hanya membutuhkan 11 karakter, berkat keindahan ruby lainnya: operator eksponensial**
. Python memiliki operator ini, tetapi ini bukan yang pertama (seperti yang dicatat @ alias.nice - terima kasih -, Fortran sudah memiliki operator ini).juru ruby online tersedia di sini: http://repl.it/Ikj/1
sumber
3 3 4
:) sangat lambat.APL, 62
{...}⎕
: Mengambil input yang dievaluasi (angka-angka yang dipisahkan spasi mengevaluasi ke array numerik) dan menerapkan fungsinya.1=3⌷⍵:
: Jika n sama dengan 1 ...2⌷+\⍵
: Kembalikan jumlah dari 2 elemen pertama (x + y) ...⋄0=2⌷⍵:
: Lain jika y sama dengan 0 ...(⍵[3]⌊3)⌷⍵[1],0,1
: Buat array numerik [x, 0,1] dan indeks pengembalianmin(n,3)
...⋄∇⍵[1],(∇⍵-0 1 0),3⌷⍵-1
: Kembalikan ∇ (x, ∇ (x, y-1, n), n-1). (∇ adalah referensi diri)Saya telah mendapatkan operator "penambah-hiper", yang mengambil fungsi dan mengembalikan hiperoperasi berikutnya
Misalnya,
+{⍺⍺/⊃⍴/⌽⍵}
akan menjadi fungsi perkalian dan+{⍺⍺/⊃⍴/⌽⍵}5 3
keluaran 15.Tapi tidak bisa kambuh lagi. Mungkin orang lain bisa melakukannya.
sumber
Python, 83
(Berdasarkan jawaban flornquake )
Sangat lambat untuk hasil yang besar.
Untuk
2, 4, 4
outputnya adalah65536
.sumber
Python,
9692Input:
3, 3, 4
Keluaran:
7625597484987
Dipersingkat menggunakan beberapa ide @ WolframH .
sumber
Skrip golf, lambat, 39 karakter
(tautan langsung)
Ini adalah algoritma rekursif standar dengan kasus dasar n = 1 (penambahan) (yaitu lambat). Hal yang sama saya gunakan dalam solusi Ruby saya
Berikut ini adalah versi dengan anotasi saya (kebanyakan penumpukan). Itu tidak termasuk satu optimasi yang saya tambahkan nanti:
~
adalah operator eval. Dalam hal string, ini memperlakukan string sebagai program GolfScript. Untungnya, daftar bilangan bulat yang dipisahkan oleh ruang adalah program GolfScript yang valid yang mendorong bilangan bulat tersebut di tumpukan. Dibandingkan dengan ini, versi rutin input saya sebelumnya (" "/{~}/
masing-masing dipisahkan oleh spasi dan eval) cukup timpang. Dalam hal fungsi, ini memanggil fungsi. Ketika didahului oleh.
(klon), ia memanggil fungsi itu sendiri sebagai argumen pertama.Golfscript tampaknya tidak cocok untuk membuat algoritma rekursif. Jika Anda menginginkan algoritme rekursif yang tidak dapat dioptimalkan dengan tail-call, Anda perlu membuat dan memusnahkan frame stack untuk menjaga variabel Anda. Dalam sebagian besar bahasa, ini dilakukan secara otomatis. Dalam skrip golf, Anda harus benar-benar mengkloning variabel (sebenarnya, entri tumpukan), dan menghancurkan entri tumpukan yang tidak lagi Anda perlukan. Golfscript tidak memiliki konsep stack frames. Sudahkah saya mengatakan GolfScript adalah bahasa berbasis stack?
Persyaratan pertama bisa dimengerti. Anda harus menentukan argumennya entah bagaimana. Hanya baik jika mereka mempertahankan posisi asli mereka juga. Persyaratan kedua sangat disayangkan, terutama karena nilai kembali berada di atas tumpukan, dan skrip golf tidak memiliki kemampuan untuk menghapus sembarang elemen tumpukan. Anda dapat memutar tumpukan dan membuang elemen teratas baru, tetapi itu dengan cepat menumpuk.
\;
baik-baik saja.\;\;\;\;\;
bukan. Anda dapat melakukannya\;
dalam satu lingkaran ({\;}9*
; biaya: 6 karakter untuk membuang hingga 9 elemen, atau 7 karakter untuk membuang hingga 99 elemen), tetapi kami dapat melakukan yang lebih baik:Golfscript memiliki array kelas satu. Ia juga memiliki sintaks literal array
[1 2 3 4]
. Yang tidak terduga adalah itu[
dan]
sebenarnya bukan bagian dari sintaksis. Mereka hanyalah dua operator:[
menandai posisi saat ini di tumpukan, dan]
mengumpulkan setiap elemen hingga menemukan tanda awal array atau kehabisan tumpukan, dan membuang tanda. Anda bahkan dapat memisahkan keduanya dan melihat apa yang terjadi. Nah, hal yang cukup menarik:Apakah saya mengatakan golfscript tidak memiliki konsep stack frames? Aku berbohong. Ini adalah stack frame:
[
. Anda bisa membuang semuanya sekaligus:];
. Tetapi bagaimana jika kita ingin mempertahankan nilai pengembalian? Anda dapat menutup bingkai tumpukan pada entri fungsi (maka kami memiliki versi pass-by-array yang sedikit rusak - bukan konsep yang menarik), atau kami dapat menutup bingkai tumpukan dan mengambil elemen terakhir alih-alih membuangnya sepenuhnya:]-1=
atau kami dapat uncons elemen terakhir sebaliknya, dan kemudian membuang frame:])\;
. Panjangnya sama, tetapi yang terakhir sedikit lebih dingin, jadi saya menggunakannya.Jadi, alih-alih 6 atau 7 karakter untuk melakukan pembersihan, kita bisa melakukannya dengan 5. Saya masih merasa ini bisa lebih golf, tapi hei, kami sudah menyelamatkan satu karakter.
sumber
Smalltalk Squeak 4.x rasa banyak byte!
Saya bisa menerapkan salah satu bentuk rekursif dalam Integer di 71 char
Kemudian membaca dari file atau FileStream stdin akan dikenakan biaya lengan saya ... Mencicit jelas tidak dirancang sebagai bahasa scripting. Jadi saya akan menghabiskan banyak byte untuk membuat utilitas keperluan umum saya sendiri yang tidak terkait dengan masalah:
Terapkan metode 21 char ini di Stream (untuk melewati pelaut)
Terapkan metode 20 karakter ini dalam Perilaku (untuk membaca sebuah instance dari Stream)
Kemudian 28 karakter dalam String (untuk membuat file handle)
Kemudian 59 karakter di FileDirectory (untuk membuat readStream)
Kemudian 33 karakter di BlockClosure (untuk mengevaluasinya n kali)
Kemudian 63 karakter dalam Array (mengevaluasi argumen dengan penerima dan argumen yang diambil dari Array)
kemudian selesaikan masalahnya dengan mengevaluasi 31 char snippet ini di mana saja untuk dibaca dari file bernama x
Bahkan tanpa menghitung utilitas, itu 71 + 31 = 102 karakter sudah ...
Sekarang, karena saya yakin akan kehilangan codeGolf, saya memiliki implementasi yang lebih lucu di Integer:
Metode ini akan mendefinisikan (kompilasi) pesan biner yang terbuat dari n + jika tidak ada (tidak dipahami oleh penerima pesan m), dan akan memulai kembali eksekusi di awal konteks pengirim. Saya memasukkan tambahan carriage return dan ruang untuk keterbacaan.
Perhatikan bahwa itu
(m selector size-2min:1)hex last
adalah bentuk kependekan dari(m selector size>2)asBit printString
.Jika bukan untuk menunjukkan kekuatan super Smalltalk jahat, pernyataan terakhir bisa digantikan oleh lebih pendek dan lebih sederhana
Sekarang mengimplementasikan utilitas 28 karakter dalam Karakter (untuk mengulanginya n kali dalam sebuah String)
Kemudian evaluasi ungkapan 43 karakter ini:
Kami dapat mempercepat dengan 10 karakter lagi dengan menerapkan Integer:
dan dalam hal ini kami juga memiliki kode yang lebih pendek karena kami dapat mengganti
^',(m selector size-2min:1)hex last
dengan^1'
Untuk harga setinggi itu, kodenya bekerja dengan integer kedua = 0 :)
sumber
Groovy - 77
Catatan: memerlukan sejumlah tumpukan (dan waktu) yang tidak senonoh untuk argumen yang tidak kecil.
sumber
Sistem Aljabar Komputer AXIOM, byte 69
uji:
Ini akan menghilangkan beberapa rekursi ... Kemungkinan saya menukar di x dan y di beberapa pengembalian ... apakah ada nilai tes lainnya?
sumber
APL (NARS), karakter 61, byte 122
uji:
sumber