7 , 410 karakter, 154 byte dalam encoding 7, 0 huruf = skor 154
55104010504200144434451510201304004220120504005434473340353241135014335450302052254241052253052244241052335452241114014241310052340435303052335442302052335500302052335430302052313340435303135014243241310335514052312241341351052302245341351525755102440304030434030421030442030424030455733413512410523142410523030523112411350143355142410523414252410523102410523002410523413342411145257551220304010420030455741403
Cobalah online!
Dalam tantangan yang tidak suka menggunakan huruf, bahasa apa yang lebih baik untuk digunakan daripada yang hanya terdiri dari digit?
Ini adalah program lengkap yang keluar melalui crash, jadi ada output tambahan untuk stderr, tetapi stdout benar.
Penjelasan
Program 7, pada iterasi pertama, hanya mendorong sejumlah elemen ke stack (karena dari 12 perintah yang ada di 7, hanya 8 di antaranya yang dapat diwakili dalam program sumber, dan 8 yang khusus untuk menulis kode untuk mendorong struktur data tertentu ke stack). Program ini tidak menggunakan 6
perintah (yang merupakan cara paling sederhana untuk membuat struktur bersarang, tetapi sebaliknya cenderung tidak muncul secara harfiah dalam program sumber), jadi hanya 7
perintah yang menentukan struktur; 7
mendorong elemen kosong baru ke atas tumpukan (sedangkan 0
... 5
perintah hanya menambahkan ke atas tumpukan). Dengan demikian kami dapat menambahkan spasi putih ke program untuk menunjukkan strukturnya:
551040105042001444344515102013040042201205040054344 7
33403532411350143354503020522542410522530522442410523354522411140142413100523
40435303052335442302052335500302052335430302052313340435303135014243241310335
514052312241341351052302245341351525 7
55102440304030434030421030442030424030455 7
33413512410523142410523030523112411350143355142410523414252410523102410523002
41052341334241114525 7
551220304010420030455 7
41403
Elemen-elemen di dekat akhir program didorong terakhir, begitu juga di atas tumpukan pada awal iterasi kedua. Pada iterasi ini, dan semua iterasi yang akan datang, 7 juru bahasa secara otomatis membuat salinan bagian atas tumpukan dan menafsirkannya sebagai suatu program. Literal 41403
mendorong (non-literal, live code) 47463
(7 memiliki 12 perintah tetapi hanya 8 dari mereka memiliki nama; dengan demikian, saya menggunakan huruf tebal untuk menunjukkan kode, dan non-tebal untuk menunjukkan literal yang menghasilkan kode itu, yang berarti itu, mis. 4
adalah perintah yang ditambahkan 4
ke elemen tumpukan atas). Jadi program yang berjalan pada iterasi kedua adalah 47463
. Inilah yang dilakukan:
47463
4 Tukar dua elemen tumpukan teratas, tambahkan elemen kosong di antara
7 Tambahkan elemen tumpukan kosong ke atas tumpukan
4 Tukar dua elemen tumpukan teratas, tambahkan elemen kosong di antara
6 Berolahraga yang perintahnya akan menghasilkan elemen tumpukan atas;
menambahkan itu ke elemen di bawah ini (dan pop bagian atas tumpukan)
3 Keluarkan elemen tumpukan atas, pop elemen di bawah ini
Ini lebih mudah dipahami jika kita melihat apa yang terjadi pada stack:
- ... d c b a
47463
(kode untuk dijalankan 47463
:)
- ... d c b kosong a (kode untuk dijalankan :)
47463
7463
- ... d c b mengosongkan sebuah kosong (kode untuk menjalankan: )
47463
463
- ... d c b
47463
kosong kosong kosong a (kode untuk dijalankan 63
:)
- ... d c b
47463
kosong kosong " a " (kode untuk dijalankan 3
:)
- ... d c b kosong (kode untuk dijalankan: kosong )
47463
Dengan kata lain, kita mengambil bagian atas tumpukan sebuah , pekerjaan apa kode yang paling mungkin telah menghasilkan itu, dan output kode. 7 juru bahasa secara otomatis muncul elemen kosong dari atas tumpukan pada akhir iterasi, jadi kami berakhir dengan 47463
kembali di atas tumpukan, seperti dalam program aslinya. Seharusnya mudah untuk melihat apa yang terjadi selanjutnya: kita akhirnya mengaduk-aduk setiap elemen tumpukan satu demi satu, mengeluarkan semuanya, hingga tumpukan mengalir dan program macet. Jadi pada dasarnya kami telah membuat loop keluaran sederhana yang melihat kode sumber program untuk menentukan apa yang akan dikeluarkan (kami tidak mengeluarkan struktur data yang didorong ke stack oleh 0
…5
perintah, kami malah menciptakan kembali perintah apa yang digunakan dengan melihat struktur apa yang dibuat, dan mengeluarkannya). Dengan demikian, bagian pertama dari output data adalah 551220304010420030455
(kode sumber yang menghasilkan elemen tumpukan kedua-dari-atas), yang kedua adalah 3341351…114525
(kode sumber yang menghasilkan elemen tumpukan ketiga-dari-atas), dan seterusnya.
Namun, jelas, kode-kode sumber ini tidak sedang di-output. 7 berisi beberapa bahasa spesifik domain yang berbeda untuk output enkode; setelah bahasa khusus domain dipilih, tetap digunakan sampai dihapus secara eksplisit, tetapi jika belum ada bahasa yang dipilih, digit pertama dari kode yang dihasilkan menentukan bahasa mana yang akan digunakan. Dalam program ini, hanya dua bahasa yang digunakan: 551
dan 3
.
551
cukup sederhana: ini pada dasarnya Baudot / kode teletype lama yang digunakan untuk mengirimkan surat melalui teletype, sebagai rangkaian karakter 5-bit, tetapi dimodifikasi untuk membuat semua huruf menjadi huruf kecil. Jadi potongan kode pertama yang akan di-dekode output seperti ini:
551 22 03 04 01 04 20 03 04 55
c a SP e SP n a SP reset output format
Seperti yang dapat dilihat, kami menyesuaikan setiap karakter menjadi dua digit oktal, yang merupakan rasio kompresi yang cukup baik. Pasangan digit dalam rentang 0-5 memberi kita 36 kemungkinan, berbeda dengan 32 kemungkinan yang dibutuhkan Baudot, sehingga empat digit sisanya digunakan untuk perintah khusus; dalam hal ini, 55
pada akhirnya menghapus format output yang diingat, membiarkan kami menggunakan format berbeda untuk potongan output berikutnya yang kami hasilkan.
3
secara konseptual bahkan lebih sederhana, tetapi dengan twist. Ide dasarnya adalah untuk mengambil kelompok tiga digit (sekali lagi, dalam kisaran 0-5, karena itu adalah angka yang dapat kami jamin bahwa kami dapat membuat ulang kode sumber asli dari outputnya), menafsirkannya sebagai tiga digit nomor dalam basis 6, dan hanya output sebagai byte dalam biner (sehingga membiarkan kami menampilkan karakter multibyte dalam output yang diinginkan hanya dengan menghasilkan beberapa byte). Twist, meskipun, berasal dari fakta bahwa hanya ada 216 angka tiga digit (dengan kemungkinan nol terkemuka) di basis 6, tetapi 256 byte mungkin. 7 menyelesaikan ini dengan menghubungkan angka dari 332₆ = 128₁₀ ke atas ke dua byte yang berbeda;332
dapat menampilkan byte 128 atau 192, 333
byte 129 atau 193, dan seterusnya, hingga 515
output byte 191 atau 255.
Bagaimana program mengetahui mana dari dua kemungkinan untuk dihasilkan? Dimungkinkan untuk menggunakan kembar tiga digit dari520
atas untuk mengontrol ini secara eksplisit, tetapi dalam program ini kita tidak harus: default 7 adalah untuk memilih semua byte yang ambigu sedemikian rupa sehingga outputnya valid UTF-8! Ternyata selalu ada paling banyak satu cara untuk melakukan ini, jadi selama itu UTF-8 yang kita inginkan (dan kita lakukan dalam kasus ini), kita bisa membiarkannya ambigu dan program tetap bekerja.
Akhir dari masing-masing 3…
bagian adalah 525
, yang me-reset format output, membiarkan kita kembali ke 551
bagian selanjutnya.
a
s - atau tidak, tergantung pada berapa banyak dibutuhkan 20 huruf, karena 20 karakter adalah penalti yang sangat besar (walaupun ketika semuanya dicetak dengan byte, itu tidak didefinisikan dengan baik ...)!