Saya pikir ini akan menjadi tantangan yang menyenangkan bagi semua orang dan saya penasaran melihat solusi yang dihasilkan orang.
Cetak lirik "12 Days Of Christmas"
On the first day of Christmas,
my true love gave to me,
A partridge in a pear tree.
On the second day of Christmas,
my true love gave to me,
Two turtle doves,
And a partridge in a pear tree.
...
On the twelfth day of Christmas,
My true love gave to me,
Twelve drummers drumming,
Eleven pipers piping,
Ten lords-a-leaping,
Nine ladies dancing,
Eight maids-a-milking,
Seven swans-a-swimming,
Six geese-a-laying,
Five golden rings,
Four calling birds,
Three french hens,
Two turtle doves,
And a partridge in a pear tree.
Aturan
- Anda tidak perlu khawatir tentang kapitalisasi; seluruh teks dapat menjadi case-sensitive
- Anda dapat dengan bijaksana mengabaikan tanda baca apa pun: tanda hubung dapat berupa spasi, dan koma dan titik dapat diabaikan
- Harus ada garis kosong di antara setiap ayat
- Anda harus menyusun nomor Anda: " hari pertama Natal", " Empat burung pemanggil", dll
Jawaban:
Brainfuck - 2,974
Saya agak bangga dengan yang ini. Kedengarannya seperti angka yang cukup besar, tetapi perlu diingat, saya tidak menggunakan perpustakaan kompresi eksternal, dan tidak ada teks asli di program saya di mana pun. Tak satu pun dari kiriman lainnya yang bisa mengatakan itu. Ini semua kode tangan. Lebih banyak generator teks yang naif memberi lebih dari 39k untuk teks ini, jadi saya akan mengatakan ini adalah peningkatan yang signifikan.
Sayangnya, ini sekitar 600 karakter lebih panjang dari outputnya sendiri, tetapi apa pun itu. Itu membuat karakter c, h, m, r, w dalam array, dan menggunakannya untuk mencetak semua teks. Dua array di sebelah kanan dua belas spasi, masing-masing melacak hari apa kita menghitung, dan untuk item mana kita bisa menampilkan. Saya mungkin bisa mengoptimalkannya sedikit dengan mengatur ulang peta memori untuk membawa karakter pencetakan di antara dua array penghitungan untuk menghindari rantai panjang
<<<<<<<
dan>>>>>>
, tetapi itu akan banyak pekerjaan pada saat ini. Saya juga mungkin bisa memilih beberapa karakter seed yang lebih baik dengan analisis frekuensi untuk meminimalkan kenaikan / penurunan, tetapi apa pun.Ini tergantung pada sel pembungkus 8-bit untuk bekerja dengan baik.
Tidak Disatukan:
sumber
Perl,
438291 karakterTerinspirasi oleh Jeff Burdges yang menggunakan kompresi DEFLATE , kode Ruby terkompresi Ventero dan JB menggunakan Lingua :: EN :: Numbers , saya berhasil mengompres entri saya menjadi 291 karakter (yah, byte) termasuk kode dekompresi. Karena program ini mengandung beberapa karakter yang tidak dapat dicetak, saya telah menyediakannya dalam format MIME Base64 :
Untuk menghapus kode program, Anda dapat menggunakan skrip Perl pembantu berikut:
Simpan output dalam file bernama
12days.pl
dan jalankan denganperl -M5.01 12days.pl
. Seperti disebutkan, Anda harus menginstal modul Lingua :: EN :: Numbers agar kode dapat berfungsi.Jika Anda bertanya-tanya, bagian kode yang dapat dibaca terlihat seperti ini:
di mana
...
kepanjangan dari 254 byte dari RFC 1950 kode Perl terkompresi. Tanpa kompresi, kodenya panjangnya 361 karakter dan terlihat seperti ini:Menulis kode ini adalah jenis latihan golf yang aneh: ternyata pengulangan memaksimalkan dan meminimalkan jumlah karakter berbeda yang digunakan jauh lebih penting daripada meminimalkan jumlah karakter mentah ketika metrik yang relevan adalah ukuran setelah kompresi .
Untuk memeras beberapa karakter terakhir, saya menulis sebuah program sederhana untuk mencoba variasi kecil dari kode ini untuk menemukan kode yang paling kompres. Untuk kompresi, saya menggunakan utilitas KZIP Ken Silverman , yang biasanya menghasilkan rasio kompresi yang lebih baik (dengan biaya kecepatan) daripada Zlib standar bahkan pada pengaturan kompresi maksimum. Tentu saja, karena KZIP hanya membuat arsip ZIP, saya kemudian harus mengekstrak aliran DEFLATE mentah dari arsip dan membungkusnya dalam header dan checksum RFC 1950. Berikut kode yang saya gunakan untuk itu:
Jika ini terlihat seperti kluge yang mengerikan, itu karena memang seperti itu.
Untuk kepentingan sejarah, inilah solusi 438-char asli saya, yang menghasilkan output yang lebih bagus, termasuk jeda baris dan tanda baca:
Sorotan dari versi ini adalah sepasang regexps
s/e?t? .*/th/,s/vt/ft/
, yang menyusun tata cara untuk 4 hingga 12 dari para kardinal di awal garis hadiah.Kode ini, tentu saja, juga dapat dikompres menggunakan trik Zlib yang dijelaskan di atas, tetapi ternyata dengan mengompresi output lebih efisien, menghasilkan program 338-byte berikut (dalam format Base64, lagi):
Saya juga memiliki arsip gzip 312 byte lirik, dibangun dari aliran DEFLATE yang sama. Saya kira Anda bisa menyebutnya "skrip zcat". :)
sumber
rings
denganrGs
untuk menyimpan 2 karakterG
denganing,
, tetapi ternyata bahwa menambahkan koma kemudian memang lebih pendek. Terima kasih!$_
pembaruan saya di bawah.Common Lisp, 333
363Fasilitas builtin untuk memformat ordinal sangat membantu, tetapi sebagian besar kompresi berasal dari kemampuan untuk menggunakan daftar argumen yang sama berulang-ulang, melompati argumen yang semakin sedikit di setiap run.
Sebagaimana dibuktikan oleh coredump dalam komentar, fasilitas builtin masih dapat dimanfaatkan dengan baik untuk para kardinal.
sumber
(dotimes(n 12)(format t"on-the-~:R-day-of-christmas my-true-love-gave-to-me ~v*~@{~R-~A ~#[AND-~]~}A-PARTRIDGE-IN-A-PEAR-TREE "(1+ n)(- 22 n n)12'drummers-drumming 11'pipers-piping 10'lords-a-leaping 9'ladies-dancing 8'maids-a-milking 7'swans-a-swimming 6'geese-a-laying 5'golden-rings 4'calling-birds 3'french-hens 2'turtle-doves))
JavaScript 570
Ini adalah kali pertama saya bermain golf. JavaScript 570
sumber
Python 2.7 (465)
Namun, saya meletakkan tanda 'dan' di baris yang sama dengan merpati bukannya partridge.
sumber
Ruby (474)
atau dalam bentuk yang lebih mudah dibaca (486):
ada yang punya ide bagaimana untuk menghindari pembalikan? saya tidak bisa menemukan solusi
sumber
12.times
alih-alih(0..11).each
; lakukan satu put dengan dua argumen, bukan dua put dengan satu argumen; gunakan notasi% w () untuk susunan hari-Natal. Akhirnya, Anda dapat menyingkirkan yang terbalik dengan membalik daftar, menambahkan ^ tambahan di akhir string, dan kemudian menggunakan[-i..-1]
sebagai ganti [0..i].Perl,
500485Ini adalah upaya pertama saya, dan saya yakin itu bisa dibuat jauh lebih pendek. Jeda baris adalah untuk keterbacaan. Itu memiliki tiga susunan penting, satu di antaranya memegang nama untuk setiap hari
@s
, satu di antaranya mencantumkan semua hadiah (kecuali yang pertama)@a
, dan satu yang mencantumkan hadiah apa yang telah diberikan@b
. Mekanisme utamanya adalah bahwa setiap hari, ia mencetak@b
dan kemudian mentransfer satu hadiah tambahan dari@a
ke@b
.Terima kasih kepada Andrew untuk 500-> 485
sumber
rings
denganr$1s
untuk menyimpan 1 lagi chars
sebagai bagian dari nama variabel, dan variabel$is
tidak ada. (Mereka sebenarnya saya bukan yang, btw)eigth
->eighth
$i
dengan, katakanlah,$;
untuk menyiasatinya. Tidak ada yang menggunakan$;
untuk tujuan yang dimaksudkan pula.Vim - 578 penekanan tombol
Saya memutuskan untuk mencoba dan golf-vim ini, karena ini adalah jenis hal yang dapat golf-vim.
Mulailah dengan memasukkan kerangka kerja - garis "X hari Natal" sebanyak 12 kali (89 penekanan tombol):
Kemudian, lakukan serangkaian makro yang akan memasukkan angka 2 hingga 12 di masing-masing tempat yang mereka perlukan untuk liriknya (172 penekanan tombol):
"Dw" pada baris kedua adalah untuk menghilangkan yang pertama "dan", karena tidak pergi ke sana.
Kemudian, lakukan serangkaian penggantian untuk sejumlah hal yang diberikan cinta sejati (319 penekanan tombol):
Dan akhirnya, mengganti setiap kemunculan
X
dengan nomor urut:Dan kita selesai!
Saya yakin ada optimasi lain yang saya lewatkan, tapi saya pikir itu cukup bagus.
sumber
:%s/2/two turtle doves,
C (644)
Count tidak termasuk spasi putih yang digunakan untuk presentasi.
Outputnya seperti:
sumber
Powershell,
487453Terimakasih kepada Daan untuk gagasan memisahkan string yang digabungkan.
Saya awalnya menyertakan pernyataan switching untuk mendapatkan "dan" di partridge untuk semua kecuali ayat pertama. Tetapi, karena pertanyaan membebaskan kita dari tanda baca, kita bisa menambahkan "dan" ke merpati.
Ini menghasilkan umpan baris sebagai berikut:
sumber
Perl, 368
389(tidak ada kode / kompresi)Harnesses Lingua :: EN :: Numbers , meskipun saya tidak 100% yakin itu ide yang baik ketika saya melihat modul dan panjang nama pengenalnya. Membutuhkan Perl 5.10 atau lebih baru, jalankan dari baris perintah dengan sebuah
-E
saklar.Sunting: peningkatan kecil: berhenti menggunakan larik, gunakan
$_
spasi yang lebih baik dan tidak dibutuhkan.sumber
PowerShell, 440
Ini mencetak lirik seperti yang diberikan dalam pertanyaan dengan beberapa baris per ayat. Kami dapat menyimpan beberapa karakter jika persyaratan itu tidak ada.
sumber
C # (528)
sumber
Jawa, 2062
Saya tahu ini diposting beberapa waktu yang lalu, tetapi saya pikir saya akan mencoba. Saya seorang siswa dan masih baru dalam hal ini tetapi tampaknya berhasil.
sumber
Swift, 577
Anda bisa menempel ini di taman bermain.
Saya mencoba memindahkan
v
ke perintah cetak dan mendapatkan:sumber
Ruby 1.9.3, terkompresi, 321 karakter
Karena kode berisi karakter yang tidak dapat dicetak, saya akan memposting hexdump kode sebagai gantinya:
Untuk membuat kode aktual dari hexdump, masukkan ke dalam file dan jalankan
xxd -r hexdump > 12days.rb
. Kemudian mengeksekusiruby1.9.3 12.days.rb
akan menjalankan kode dan mencetak lirik. Perhatikan bahwa kode ini memerlukan Ruby 1.9.3 (karena menggunakanZlib.inflate
), sehingga tidak akan berfungsi dengan Ruby 1.8.x, 1.9.1 dan 1.9.2.Kode yang tidak terkompresi adalah 425 karakter:
sumber
Perl, 319/313
Ide: Buka kompresi dan evaluasi solusi Lingua :: EN :: Numbers JB.
Pertama, rekatkan blok teks ini ke dalam perintah
perl -e 'use MIME::Base64; print decode_base64 $_ while <>;' >12days.pl
. Selanjutnya, jalankan perintahperl -M5.01 12days.pl
.Script itu sendiri mengambil bentuk di
use Compress::Zlib;$_='...';eval uncompress$_;
mana...
solusi char 368 JB setelah dikompresi dengan perintah ini dan melarikan diri a'
.Skrip Ilmari mengeluh tentang memodifikasi nilai hanya baca tanpa
$_=...;
karakter tambahan , tetapi mungkin dia akan membuat ini 313 . Anda bisa menghemat beberapa byte lagi dengan mengubah kompresi secara manual seperti yang dilakukan Ilmari sebelumnya, mungkin mencapai 310 atau lebih , tapi saya tidak repot.Perl, 376 (menipu kiriman lain) [kiriman asli saya]
Pertama, buat skrip perl yang disebut
12days.pl
mengandung:Selanjutnya, masukkan output dari pengajuan lain ke
12days.txt
dan jalankan perintah:Vola
12days.pl
sekitar 376 byte dan mencetak lagu. ;) Mengasyikkan menggunakan gerakan rawinflate tepat enam byte dari data doc ke dalam kode mulai dari output Ilmari.Saya awalnya mulai mencari modul pengkodean Huffman secara langsung, yang hampir tidak jujur. Namun, sayangnya CPAN tidak memiliki modul dengan tabel entropi huruf bahasa Inggris, yang benar-benar Anda inginkan ketika mengompresi string yang sangat pendek.
Saya menemukan bahwa
fortune -m Days\ of\ Christmas
itu tidak berhasil, sayangnya.sumber
PHP, 548
Mengurangi panjang dengan kompresi, 502
sumber
VALA,
584, 574Tidak ada lagi peringatan saat kompilasi.
sumber
Java, 608
Posting pertama di Stack Exchange, upaya kedua untuk masalah ini.
Java sedikit rumit untuk tugas-tugas seperti ini, tetapi menggunakan split membantu mengurangi overhead String.
sumber
/// , 439 byte
Cobalah online!
Jika membuntuti baris baru diizinkan, Anda dapat menyimpan empat byte:
Cobalah online!
Penjelasan
/// adalah bahasa di mana satu-satunya operasi adalah substitusi yang memodifikasi sendiri. Secara khusus, instruksi
/abc/xyz/
menggantikan semua instanceabc
denganxyz
di sisa kode sumber, termasuk substitusi lain .. Karakter lain hanya output ke STDOUT.Meskipun ini cukup untuk penyelesaian Turing, bermain golf di /// umumnya terdiri dari mulai dengan output yang diinginkan dan mengidentifikasi substring yang berulang yang dapat diganti dengan pintasan satu karakter.
\
dapat digunakan sebagai karakter pelarian dalam pola, penggantian, dan karakter literal yang berarti literal/
atau\
.Instruksi pertama yang ditemui adalah
/|/\/\//
. Ini berarti "ganti semua|
dengan//
sisa program." Ini menghemat satu byte untuk setiap penggantian berikutnya dalam program.Setelah ini, serangkaian penggantian dibuat untuk mengompresi teks itu sendiri:
on the
menjadi^
.day of christmas \n my true love gave to me \n
menjadi%
.-a-
menjadi=
.ing
menjadi&
.even
menjadi*
.th%
menjadi+
.^
didahului oleh dua baris baru (yang muncul di setiap ayat tetapi yang pertama) menjadi:
.Setelah ini, kami menulis lirik sendiri. Ini dilakukan dengan menggunakan penggantian
A
melaluiK
. Setiap penggantian huruf menambahkan baris ke penggantian setelah itu. Misalnya,K
representasikana partridge in a pear tree
danJ
representasikantwo turtle doves \n and K
.Dengan cara ini, setiap bait lagu terdiri dari:
^
atau:
el*th
)%
A
melaluiK
yang mewakili lirik yang benar.Namun, karena sebagian besar tata cara berakhir
th
, kami menggunakan subtitusith%
→+
untuk menghemat beberapa byte.sumber
Ada kalanya solusi yang paling jelas juga merupakan yang terpendek, yaitu saya tidak bisa lagi menahan keinginan ini.
Bash di Mac OS X, 26
Perl, 111
Satu baris baru ditambahkan untuk dibaca.
sumber
eval compress
trik untuk mengklaim saya menemukan regex yang kompres dengan sangat baik, tetapi itu membengkak sekitar 200 karakter. lolJawa - 1329 karakter
Saya terlalu malas untuk ungolf, tetapi di sini: http://ideone.com/MU9IcP .
sumber
SEDERHANA , 1 byte
Catatan :
Bahasa dirancang setelah tantangan dan masih WIP.
Bagaimana:
Setiap arang akan menghasilkan 12 hari Natal.
sumber