Terinspirasi oleh http://xkcd.com/710/ berikut ini adalah kode golf untuk itu.
Tantangan
Diberikan bilangan bulat positif yang lebih besar dari 0, cetak urutan batu es untuk nomor itu.
Urutan Hailstone
Lihat Wikipedia untuk detail lebih lanjut ..
- Jika angkanya genap, bagi dengan dua.
- Jika angkanya ganjil, tiga kali lipat dan tambahkan satu.
Ulangi ini dengan angka yang dihasilkan hingga mencapai 1. (jika berlanjut setelah 1, itu akan masuk dalam putaran tak terbatas 1 -> 4 -> 2 -> 1...
)
Terkadang kode adalah cara terbaik untuk menjelaskan, jadi ini beberapa dari Wikipedia
function collatz(n)
show n
if n > 1
if n is odd
call collatz(3n + 1)
else
call collatz(n / 2)
Kode ini berfungsi, tetapi saya menambahkan tantangan tambahan. Program tidak boleh rentan terhadap luapan tumpukan . Jadi itu harus menggunakan iterasi atau rekursi ekor.
Juga, poin bonus jika dapat menghitung angka besar dan bahasanya belum diterapkan. (atau jika Anda menerapkan kembali dukungan angka besar menggunakan bilangan bulat panjang tetap)
Kasus cobaan
Number: 21
Results: 21 -> 64 -> 32 -> 16 -> 8 -> 4 -> 2 -> 1
Number: 3
Results: 3 -> 10 -> 5 -> 16 -> 8 -> 4 -> 2 -> 1
Juga, kode golf harus menyertakan input dan output pengguna secara penuh.
Jawaban:
perakitan x86, 1337 karakter
sumber
int 23h
.Befunge
sumber
LOLCODE: 406 CHARAKTERZ
TESTD UNDR INTERPRETR JUSTIN J. MEZA . KTHXBYE!
sumber
Python -
95645146 karakterJelas tidak menghasilkan stack overflow.
sumber
input
tidak melakukaneval
.n=input()*2
Perl
Saya memutuskan untuk menjadi sedikit anti persaingan, dan menunjukkan bagaimana Anda biasanya mengkodekan masalah seperti itu di Perl.
Ada juga entri golf kode karakter 46 (total) di akhir.
Tiga contoh pertama ini semuanya dimulai dengan tajuk ini.
Versi rekursif sederhana
Versi iteratif sederhana
Versi iteratif yang dioptimalkan
Sekarang saya akan menunjukkan bagaimana Anda akan melakukan contoh terakhir dengan versi Perl sebelum v5.10.0
Tolok ukur
Pertama, IO akan selalu menjadi bagian yang lambat. Jadi, jika Anda benar-benar membandingkannya apa adanya, Anda harus mendapatkan kecepatan yang sama dari masing-masing.
Untuk mengujinya, saya membuka pegangan file ke
/dev/null
($null
), dan mengedit setiap filesay $n
untuk dibacasay {$null} $n
. Ini untuk mengurangi ketergantungan pada IO.Setelah menjalankannya 10 kali, berikut adalah contoh keluaran yang representatif:
Akhirnya, entri kode-golf nyata:
46 total karakter
Jika Anda tidak perlu mencetak nilai awal, Anda dapat menghapus 5 karakter lagi.
41 karakter total
31 karakter untuk bagian kode sebenarnya, tetapi kode tidak akan berfungsi tanpa
-n
sakelar. Jadi saya memasukkan seluruh contoh dalam hitungan saya.sumber
$i + 1
adalah selalu Selain (respon ke entri blog). Juga menggunakanSub::Call::Recur
juga merupakan optimasi. Kalau tidak, saya akan menggunakan@_=$n;goto &Collatz
. (Ini 10-20% lebih lambat jika Anda mengubahstate @next
kemy @next
Haskell, 62 karakter
637683,86,97,137Input pengguna, output tercetak, menggunakan memori dan tumpukan konstan, bekerja dengan bilangan bulat besar yang sewenang-wenang.
Contoh kode ini, diberi nomor 80 digit dari semua '1 (!) Sebagai masukan, cukup menyenangkan untuk dilihat.
Asli, versi hanya fungsi:
Haskell 51 karakter
Siapa @ & ^ # yang membutuhkan persyaratan?
(edit: Saya menjadi "pintar" dan menggunakan perbaikan. Tanpa itu, kode turun menjadi 54 karakter. edit2: turun menjadi 51 dengan memfaktorkan keluar
f()
)sumber
c 1=[1];c n=n:(c$div(n
mod2*(5*n+2)+n)2)
- 41 karakter, ini menggunakan fakta bahwa ini adalah k * (3n + 1) + (1-k) * n / 2 di mana k = n mod 2Script golf: 20 karakter
Ini sama dengan
sumber
21
dengan~
akan menyebabkan program menggunakan nomor dari stdin(eval):1:in
inisialisasi ': metode tidak ditentukanleftparen' for nil:NilClass (NoMethodError)
saat mengganti21
dengan~
.echo 21 | ruby golfscript.rb collatz.gs
bc 41 karakter
Saya kira masalah seperti
bc
inilah yang diciptakan untuk:Uji:
Kode yang tepat:
bc
menangani angka hinggaINT_MAX
digitEdit: The artikel Wikipedia menyebutkan dugaan ini telah diperiksa untuk semua nilai hingga 20X2 58 (aprox. 5.76e18 ). Program ini:
menguji 2 20.000 +1 (aprox. 3.98e6.020 ) dalam 68 detik, 144.404 siklus.
sumber
cat /dev/urandom | tr -dc '0-9' | head -c 10000 | bc collatz-conjecture.bc
bc
Perl: 31 karakter
Diedit untuk menghapus 2 spasi yang tidak perlu.
Diedit untuk menghapus 1 ruang yang tidak perlu.
sumber
MS Excel, 35 karakter
Diambil langsung dari Wikipedia :
Hanya perlu menyalin / menempel rumus 111 kali untuk mendapatkan hasil untuk angka awal 1000.;)
sumber
C: 64 karakter
Dengan dukungan integer besar: 431 karakter (perlu)
Catatan : Jangan dilepas
#include <stdlib.h>
tanpa setidaknya membuat prototipe malloc / realloc, karena hal itu tidak akan aman di platform 64-bit (64-bit void * akan diubah menjadi int 32-bit).Yang ini belum diuji dengan kuat. Ini bisa menggunakan beberapa shortening juga.
Versi sebelumnya:
(menghapus 12 karakter karena tidak ada yang mengikuti format keluaran ...: |)
sumber
Versi assembler lain. Yang ini tidak terbatas pada angka 32 bit, ini dapat menangani angka hingga 10 65534 meskipun format ".com" yang digunakan MS-DOS terbatas pada angka 80 digit. Ditulis untuk assembler A86 dan membutuhkan kotak DOS Win-XP untuk dijalankan. Merakit hingga 180 byte:
sumber
dc - 24 karakter
2528dc
adalah alat yang bagus untuk urutan ini:Juga 24 karakter menggunakan rumus dari entri Golfscript :
57 karakter untuk memenuhi spesifikasi:
sumber
Skema: 72
Ini menggunakan rekursi, tetapi panggilannya rekursif-ekor jadi saya pikir mereka akan dioptimalkan untuk iterasi. Dalam beberapa pengujian cepat, saya belum dapat menemukan nomor yang tumpukannya melimpah. Misalnya saja:
(c 9876543219999999999000011234567898888777766665555444433332222 777777777777777777777777777777777798797657657651234143375987342987 539870981237498252983098374329743298523099880983743297432985230938857398787308523852309387539878530853375987342987 539870981237498252983098374329743298523093885739878785238523093875398785
... berjalan dengan baik. [Itu semua adalah satu angka - Saya baru saja memecahkannya agar muat di layar.]
sumber
Mathematica, 45
50karaktersumber
OddQ[#]
denganOddQ@#
menghemat 1 karakter.c[n_]:=NestWhileList[If[OddQ@#,3#+1,#/2]&,n,#>1&]
Ruby, 50 karakter, tidak ada stack overflow
Pada dasarnya rip langsung dari solusi Python makapuf :
Ruby, 45 karakter, akan meluap
Pada dasarnya rip langsung dari kode yang diberikan dalam pertanyaan:
sumber
n.odd??
tidak didefinisikan. Juga, itu rentan terhadap tumpukan overflows dengan jumlah yang besar.p n=[n/2,n*3+1][n%2]
sumber
Python 45 Char
Mencukur sedikit pun dari jawaban makapuf.
sumber
TI-BASIC
Bukan yang terpendek, tapi pendekatan baru. Dipastikan akan sangat melambat dengan urutan yang besar, tetapi seharusnya tidak meluap.
sumber
Haskell: 50
sumber
c 1=[1];c n=n:(c$[n
div2,3*n+1]!!(n
mod2))
, 44 charsbukan yang terpendek, tapi solusi clojure yang elegan
sumber
C #: 216 Karakter
dalam bentuk panjang:
Versi Baru, menerima satu nomor sebagai masukan yang diberikan melalui baris perintah, tanpa validasi masukan.
173154karakter.dalam bentuk panjang:
Saya dapat mencukur beberapa karakter dengan merobek ide dalam jawaban ini untuk menggunakan for loop daripada sementara. 150 karakter.
sumber
Ruby, 43 karakter
bignum didukung, dengan kerentanan stack overflow:
... dan 50 karakter, didukung bignum, tanpa stack overflow:
Kudos to Jordan. Saya tidak tahu tentang 'p' sebagai pengganti put.
sumber
nroff 1
Jalankan dengan
nroff -U hail.g
1. versi groff
sumber
groff -U hail.g
dan Anda mendapatkan PostScript! :-)Scala + Scalaz
Dan beraksi:
Scala 2.8.0
Ini juga termasuk trailing 1.
Dengan implisit berikut
ini dapat disingkat menjadi
Edit - 58 karakter (termasuk input dan output, tetapi tidak termasuk nomor awal)
Bisa dikurangi 2 jika Anda tidak membutuhkan baris baru ...
sumber
F #, 90 karakter
Atau jika Anda tidak menggunakan F # interaktif untuk menampilkan hasilnya, 102 karakter:
sumber
Lisp umum, 141 karakter:
Uji coba:
sumber
Program dari Jerry Coffin memiliki integer over flow, coba yang ini:
diuji dengan
Jumlahnya kurang dari 100 juta dengan total waktu henti terlama 63.728.127 dengan 949 anak tangga.
Jumlahnya kurang dari 1 Milyar dengan total waktu henti terpanjang 670.617.279 anak tangga dengan 986 anak tangga.
sumber
unsigned long long
.ruby, 43, mungkin memenuhi persyaratan I / O
Jalankan dengan
ruby -n hail
sumber
C #: 659 karakter dengan dukungan BigInteger
Ungolfed
sumber