Terima kasih kepada FryAmTheEggman untuk beberapa inspirasi yang diperlukan untuk solusi XOR.
0000 !@
0001 ?.|@!
0010 #?#!)@
0011 ?!@
0100 +?|@!?
0101 ??!@
0110 ?<@!!<_\~(
0111 ?<<@!
1000 )\!#?@{
1001 (~?/@#!
1010 ??|@!)
1011 \#??!1@
1100 ?(~!@
1101 ?.|@!)
1110 ?$@#)!<
1111 1!@
Semua program menggunakan 0
false dan 1
true.
Cobalah online! Ini bukan test suite, Anda harus menyalin di berbagai program dan memasukkan sendiri.
Solusi di atas adalah dalam 2-byte optimalitas (kecuali kita mengendurkan interpretasi yang benar / salah, saya kira). Aku telah membiarkan sebuah kasar pencarian kekuatan kabur dekat dengan dua hari atas semua program yang masuk ke dalam sisi-panjang 2, yaitu hingga 7 byte (tidak cukup semua program - Saya membuat beberapa asumsi tentang apa yang setiap kebutuhan program yang valid dan apa yang tidak ada program yang valid dapat memiliki). Pencarian menemukan solusi untuk 15 dari 16 kemungkinan gerbang - dan seringkali lebih dari satu. Anda dapat menemukan daftar semua solusi alternatif di pastebin ini di mana saya juga mengelompokkannya berdasarkan perilaku yang setara. Yang saya tunjukkan di atas saya pilih karena mereka adalah solusi paling sederhana atau paling menarik, dan saya akan menambahkan penjelasan untuk mereka besok.
Adapun gerbang ke-16: XOR adalah satu-satunya gerbang yang tampaknya tidak dapat diimplementasikan dalam 7 byte. Pencarian brute force melalui program yang lebih besar sayangnya tidak layak dengan kode yang saya miliki saat ini. Jadi XOR harus ditulis dengan tangan. Yang terpendek yang saya temukan sejauh ini adalah program 10-byte di atas, yang didasarkan pada upaya gagal (tapi sangat dekat) oleh FryAmTheEggman. Ada kemungkinan bahwa solusi 8-byte atau 9-byte ada, tetapi selain itu, semua solusi memang harus optimal.
Penjelasan
Peringatan: dinding teks. Jika ada yang tertarik bagaimana program Hexagony yang sangat padat ini benar-benar bekerja, saya telah menyertakan penjelasan untuk masing-masingnya di bawah ini. Saya telah mencoba untuk memilih solusi paling sederhana untuk setiap gerbang dalam kasus di mana ada lebih dari satu program optimal, agar penjelasannya cukup singkat. Namun, beberapa dari mereka masih merusakkan pikiran, jadi saya pikir mereka pantas mendapatkan penjelasan lebih lanjut.
0000
: Salah
Saya tidak berpikir kita akan membutuhkan diagram untuk yang ini:
! @
. . .
. .
Karena seluruh kotak memori diinisialisasi ke nol, !
cukup cetak nol dan @
akhiri program.
Ini juga satu-satunya solusi 2-byte.
0001
: Dan
? .
| @ !
. .
Ini pada dasarnya menerapkan hubungan arus pendek . Diagram abu-abu di bawah ini menunjukkan awal program, di mana input pertama dibaca dengan ?
dan penunjuk instruksi (IP) membungkus ke sudut kiri di mana |
cermin memantulkannya. Sekarang sudut bertindak sebagai kondisional, seperti ada dua jalur eksekusi yang berbeda tergantung pada nilai input pertama. Diagram merah menunjukkan aliran kontrol untuk A = 0
dan diagram hijau untuk A = 1
:
Seperti yang Anda lihat, ketika A
ada 0
, maka kita cukup mencetaknya dan mengakhiri (ingat bahwa semua .
adalah tanpa operasi). Tapi ketika A
adalah 1
, maka IP melintasi baris pertama lagi, membaca B
dan pencetakan yang sebaliknya.
Total ada enam belas solusi 5-byte untuk gerbang ini. Empat belas dari mereka pada dasarnya sama dengan yang di atas, baik menggunakan >
alih-alih |
atau mengganti .
dengan perintah yang secara efektif no-op, atau menempatkan ?
di posisi kedua:
?.|@! .?|@! ?=|@! =?|@! ?_|@! _?|@! ?0|@!
?.>@! .?>@! ?=>@! =?>@! ?_>@! _?>@! ?0>@!
Dan kemudian ada dua solusi lain (yang setara satu sama lain). Ini juga menerapkan logika hubungan pendek yang sama, tetapi jalur eksekusi agak lebih gila (dan dibiarkan sebagai latihan bagi pembaca):
?<!@|
?<!@<
0010
: A dan bukan B
# ?
# ! )
@ .
Ini juga mengimplementasikan bentuk hubungan arus pendek, tetapi karena penggunaan #
aliran kontrol jauh lebih sulit. #
adalah saklar IP bersyarat. Hexagony sebenarnya berasal dengan enam IP berlabel 0
untuk 5
, yang dimulai pada enam sudut grid, menunjuk sepanjang tepi searah jarum jam mereka (dan program selalu dimulai dengan IP 0
). Ketika a #
ditemui, nilai saat ini diambil modulo 6
, dan aliran kontrol berlanjut dengan IP yang sesuai. Saya tidak yakin apa yang cocok dengan kegilaan membuat saya menambahkan fitur ini, tetapi tentu saja memungkinkan untuk beberapa program mengejutkan (seperti ini).
Kami akan membedakan tiga kasus. Kapan A = 0
, program ini cukup sederhana, karena nilainya selalu 0
ketika #
ditemui sehingga tidak ada IP-switching yang terjadi:
#
tidak melakukan apa-apa, ?
membaca A
(yaitu juga tidak melakukan apa-apa), #
masih tidak melakukan apa-apa, !
mencetak 0
, )
menambahnya (ini penting, jika IP tidak akan melompat ke baris ketiga), @
mengakhiri program. Cukup sederhana. Sekarang mari kita perhatikan kasusnya (A, B) = (1, 0)
:
Jalur merah masih sesuai dengan IP 0
, dan saya telah menambahkan jalur hijau untuk IP 1
. Kami melihat bahwa setelah ?
membaca A
( 1
kali ini), #
beralih ke IP yang dimulai di sudut kanan atas. Itu artinya ?
bisa membaca B
( 0
). Sekarang )
menambahkan itu ke 1
, sehingga #
di sudut kiri atas tidak melakukan apa-apa dan kami tetap dengan IP 1
. The !
cetakan yang 1
dan IP membungkus di sekitar diagonal kiri. #
masih tidak melakukan apa-apa dan @
menghentikan program.
Akhirnya, kasus yang sangat aneh di mana kedua input adalah 1
:
Kali ini, input kedua juga 1
dan )
menambahnya 2
. Itu berarti #
di sudut kiri atas menyebabkan lain beralih IP ke IP 2
, menunjukkan warna biru. Di jalur itu, pertama-tama kita menambahnya lebih jauh 3
(meskipun itu tidak relevan) dan kemudian melewati yang ?
ketiga kalinya. Karena kita sekarang telah menekan EOF (yaitu input habis), ?
mengembalikan 0
, !
mencetak itu, dan @
mengakhiri program.
Khususnya, ini adalah satu-satunya solusi 6-byte untuk gerbang ini.
0011
: SEBUAH
? !
@ . .
. .
Ini cukup sederhana sehingga kita tidak memerlukan diagram: ?
membaca A
, !
mencetak, @
mengakhiri.
Ini adalah satu-satunya solusi 3-byte untuk gerbang ini. (Pada prinsipnya, itu juga mungkin dilakukan ,;@
, tetapi pencarian tidak termasuk ;
, karena saya tidak berpikir itu bisa menghemat byte !
untuk tugas ini.)
0100
: B dan bukan A
+ ?
| @ !
? .
Yang ini jauh lebih sederhana daripada "saudara" nya 0010
. Aliran kontrol sebenarnya sama seperti yang telah kita lihat di atas untuk 0001
(Dan). Jika A = 0
, maka IP akan melintasi garis bawah, membaca B
dan mencetaknya sebelum mengakhiri. Jika A = 1
kemudian IP melintasi baris pertama lagi, juga membaca B
, tetapi +
menambahkan dua tepi memori yang tidak digunakan sehingga semua yang dilakukannya adalah mereset nilai saat ini 0
, sehingga !
selalu dicetak 0
.
Ada cukup banyak alternatif 6-byte untuk ini (totalnya 42). Pertama, ada satu ton solusi yang setara dengan yang di atas. Kita dapat kembali memilih antara |
dan >
, dan +
dapat diganti dengan perintah lain yang memberi kita keunggulan kosong:
"?|@!? &?|@!? '?|@!? *?|@!? +?|@!? -?|@!? ^?|@!? {?|@!? }?|@!?
"?>@!? &?>@!? '?>@!? *?>@!? +?>@!? -?>@!? ^?>@!? {?>@!? }?>@!?
Selain itu, kita juga bisa menggunakan ]
bukan ?
. ]
pindah ke IP berikutnya (yaitu memilih IP 1
), sehingga cabang ini malah menggunakan kembali ?
di sudut kanan atas. Itu memberi 18 solusi lain:
"?|@!] &?|@!] '?|@!] *?|@!] +?|@!] -?|@!] ^?|@!] {?|@!] }?|@!]
"?>@!] &?>@!] '?>@!] *?>@!] +?>@!] -?>@!] ^?>@!] {?>@!] }?>@!]
Dan kemudian ada enam solusi lain yang semuanya bekerja secara berbeda dengan berbagai tingkat kegilaan:
/[<@!? ?(#!@] ?(#>@! ?/@#/! [<<@!? [@$\!?
0101
: B
? ?
! @ .
. .
Woohoo, satu lagi yang sederhana: baca A
, baca B
, cetak B
, hentikan. Sebenarnya ada alternatif untuk ini. Karena A
hanya satu karakter, kita juga dapat membacanya dengan ,
:
,?!@
Dan ada juga opsi untuk menggunakan satu ?
dan menggunakan cermin untuk menjalankannya dua kali:
?|@! ?>@!
0110
: Xor
? < @
! ! < _
\ ~ ( . .
. . . .
. . .
Seperti yang saya katakan di atas, ini adalah satu-satunya gerbang yang tidak akan cocok dengan sisi panjang 2, jadi ini solusi tulisan tangan oleh FryAmTheEggman dan saya sendiri, dan ada peluang bagus bahwa itu tidak optimal. Ada dua kasus untuk dibedakan. Jika A = 0
aliran kontrolnya cukup sederhana (karena dalam hal ini kita hanya perlu mencetak B
):
Kami mulai di jalur merah. ?
berbunyi A
, <
adalah cabang yang membelokkan nol kiri. IP membungkus ke bawah, lalu _
cermin lain, dan ketika IP menyentuh sudut, itu membungkus ke sudut kiri atas dan berlanjut di jalur biru. ?
membaca B
, !
mencetaknya. Sekarang (
dekrementasi. Ini penting karena memastikan nilainya tidak positif (baik sekarang 0
atau -1
sekarang). Itu membuat IP wrap ke sudut kanan, tempat @
mengakhiri program.
Ketika A = 1
segalanya menjadi sedikit rumit. Dalam hal ini kami ingin mencetak not B
, yang dengan sendirinya tidak terlalu sulit, tetapi jalur eksekusi agak trippy.
Kali ini, <
IP membelokkan ke kanan dan selanjutnya <
hanya bertindak sebagai cermin. Jadi IP melewati jalur yang sama secara terbalik, membaca B
ketika bertemu ?
lagi. IP membungkus ke sudut kanan dan melanjutkan di jalur hijau. Ini pertemuan berikutnya (~
yang "penurunan, kalikan dengan -1", yang swap 0
dan 1
dan karena itu menghitung not B
. \
hanyalah sebuah cermin dan !
mencetak hasil yang diinginkan. Kemudian ?
cobalah untuk mengembalikan nomor lain tetapi mengembalikan nol. IP sekarang berlanjut di sudut kiri bawah di jalur biru. (
decrements, <
mencerminkan,(
menurun lagi, sehingga nilai saat ini negatif ketika IP menyentuh sudut. Bergerak melintasi diagonal kanan bawah dan akhirnya hits @
untuk menghentikan program.
0111
: Atau
? <
< @ !
. .
Lebih banyak korsleting.
The A = 0
kasus (jalur merah) adalah sedikit membingungkan di sini. IP dibelokkan ke kiri, membungkus ke sudut kiri bawah, langsung tercermin oleh <
dan kembali ?
ke membaca B
. Kemudian membungkus ke sudut rigt, mencetak B
dengan !
dan berakhir.
The A = 1
kasus (jalur hijau) adalah sedikit lebih sederhana. The <
cabang mengalihkan IP yang tepat, jadi kami hanya mencetak !
, membungkus kembali ke kiri atas, dan berakhir pada @
.
Hanya ada satu solusi 5-byte lainnya:
\>?@!
Ini bekerja pada dasarnya sama, tetapi jalur eksekusi yang sebenarnya sangat berbeda dan menggunakan sudut untuk percabangan bukannya a <
.
1000
: Juga
) \
! # ?
@ {
Ini mungkin program favorit saya yang ditemukan dalam pencarian ini. Yang paling keren adalah implementasi ini nor
benar - benar berfungsi hingga 5 input. Saya harus masuk ke detail model memori sedikit untuk menjelaskan yang ini. Jadi sebagai penyegaran cepat, model memori Hexagony adalah kisi heksagonal terpisah, di mana setiap sisi memegang nilai integer (awalnya semuanya nol). Ada penunjuk memori (MP) yang menunjukkan tepi dan arah sepanjang tepi itu (sedemikian rupa sehingga ada dua tepi tetangga di depan dan di belakang tepi saat ini, dengan tetangga kiri dan kanan yang berarti). Berikut adalah diagram tepi yang akan kami gunakan, dengan MP dimulai seperti yang ditunjukkan dengan warna merah:
Pertama mari kita perhatikan kasus di mana kedua input berada 0
:
Kita mulai di jalur abu-abu, yang hanya menambah tepi A ke 1
sehingga #
beralih ke IP 1
yang merupakan jalur biru, mulai dari sudut kanan atas. \
tidak melakukan apa pun di sana dan ?
membaca input. Kami membungkus ke sudut kiri atas tempat )
penambahan input itu. Sekarang selama inputnya nol, ini akan menghasilkan a 1
, sehingga #
tidak melakukan apa-apa. Kemudian {
bergerak MP ke kiri, yaitu pada iterasi pertama dari A ke B . Karena tepi ini masih memiliki nol awal IP membungkus kembali ke sudut kanan atas dan di tepi memori baru. Jadi loop ini akan terus berlanjut selama ?
membaca nol, menggerakkan MP di sekitar segi enam dari Bke C ke D dan seterusnya. Tidak masalah apakah ?
mengembalikan nol karena input atau karena EOF.
Setelah enam iterasi melalui loop ini, {
kembali ke A . Kali ini, ujung sudah memegang nilai 1
dari iterasi pertama, sehingga IP membungkus ke sudut kiri dan melanjutkan pada jalur hijau sebagai gantinya. !
hanya mencetak itu 1
dan @
menghentikan program.
Sekarang bagaimana jika ada input 1
?
Kemudian ?
bacalah itu 1
di beberapa titik dan )
tambahkan ke 2
. Itu berarti #
sekarang akan beralih IP lagi dan kami akan melanjutkan di sudut kanan di jalur merah. ?
membaca input lain (jika ada), yang tidak terlalu penting dan {
bergerak lebih jauh. Ini harus menjadi tepi yang tidak digunakan, oleh karena itu ini berfungsi hingga 5 input. IP membungkus ke kanan atas di mana itu segera tercermin dan membungkus ke sudut kiri. !
mencetak 0
pada tepi yang tidak digunakan dan #
beralih kembali ke IP 0
. IP itu masih menunggu di sekitar #
, menuju barat daya (jalur abu-abu), sehingga segera menyentuh @
dan mengakhiri program.
Secara total ada tujuh solusi 7-byte untuk gerbang ini. 5 dari mereka bekerja sama seperti ini dan hanya menggunakan perintah lain untuk pindah ke tepi yang tidak digunakan (dan dapat berjalan di sekitar segi enam yang berbeda atau ke arah yang berbeda):
)\!#?@" )\!#?@' )\!#?@^ )\!#?@{ )\!#?@}
Dan ada satu kelas solusi lain yang hanya bekerja dengan dua input, tetapi jalur eksekusi yang sebenarnya lebih berantakan:
?]!|<)@ ?]!|<1@
1001
: Kesetaraan
( ~
? / @
# !
Ini juga sangat cerdas dalam menggunakan pemilihan IP bersyarat. Kita perlu membedakan lagi antara A = 0
dan A = 1
. Dalam kasus pertama kita ingin mencetak not B
, dalam kasus kedua kita ingin mencetak B
. Karena A = 0
kami juga membedakan dua kasus untuk B
. Mari kita mulai dengan A = B = 0
:
Kami mulai di jalur abu-abu. (~
dapat diabaikan, IP membungkus ke sudut kiri (masih di jalur abu-abu) dan membaca A
dengan ?
. (
decrements itu, jadi kita dapatkan -1
dan bungkus IP ke sudut kiri bawah. Sekarang seperti yang saya katakan sebelumnya, #
ambil modulo nilai 6
sebelum memilih dia IP, jadi nilai -1
IP benar-benar keluar 5
, yang dimulai di sudut kiri di jalur merah. ?
berbunyi B
, (
mengurangi itu juga sehingga kita tetap di IP 5
ketika kita menekan #
lagi. ~
meniadakan -1
sehingga IP membungkus ke sudut kanan bawah, mencetak 1
dan berakhir.
Sekarang jika B
adalah 1
sebaliknya, nilai saat akan 0
ketika kita memukul #
kedua kalinya, jadi kami beralih kembali ke IP 0
(sekarang jalan hijau). Itu memukul ?
untuk ketiga kalinya, menghasilkan 0
, !
mencetaknya, dan @
berakhir.
Akhirnya, kasusnya dimana A = 1
. Kali ini nilai saat ini sudah nol ketika kami menekan #
untuk pertama kalinya, jadi ini tidak pernah beralih ke IP 5
di tempat pertama. Kami hanya melanjutkan langsung di jalur hijau. ?
sekarang tidak hanya memberikan nol tetapi B
malah mengembalikannya . !
mencetaknya dan @
berakhir lagi.
Total ada tiga solusi 7-byte untuk gerbang ini. Dua lainnya bekerja sangat berbeda (bahkan dari satu sama lain), dan membuat penggunaan lebih aneh #
. Secara khusus mereka membaca satu atau lebih nilai dengan ,
(membaca kode karakter alih-alih bilangan bulat) dan kemudian menggunakan nilai itu modulo 6 untuk memilih IP. Ini sangat gila.
),)#?@!
?~#,~!@
1010
: Tidak b
? ?
| @ !
) .
Yang ini cukup sederhana. Jalur eksekusi adalah cabang horizontal yang sudah kita ketahui and
sebelumnya. ??
membaca A
dan kemudian segera B
. Setelah merefleksikan |
dan bercabang, karena B = 0
kita akan mengeksekusi cabang bawah, di mana )
menambah nilai 1
yang kemudian dicetak oleh !
. Di cabang atas (jika B = 1
) ?
cukup mengatur ulang tepi 0
yang kemudian dicetak oleh !
.
Ada delapan program 6-byte untuk gerbang ini. Empat dari mereka hampir sama, menggunakan >
bukan |
atau 1
bukan )
(atau keduanya):
??>@!) ??>@!1 ??|@!) ??|@!1
Dua menggunakan satu ?
yang digunakan dua kali karena cermin. Negasi kemudian terjadi seperti yang kita lakukan xor
dengan (~
atau ~)
.
?>!)~@ ?>!~(@
Dan akhirnya, dua solusi menggunakan saklar IP bersyarat, karena mengapa menggunakan cara sederhana jika yang berbelit-belit juga berfungsi:
??#)!@ ??#1!@
1011
: B menyiratkan A
\ #
? ? !
1 @
Ini menggunakan beberapa IP switching yang agak rumit. Saya akan mulai dengan A = 1
kasing kali ini, karena lebih sederhana:
Kita mulai pada jalur abu-abu, yang berbunyi A
dengan ?
dan kemudian klik #
. Sejak A
adalah 1
ini beralih ke IP 1
(jalur hijau). The !
segera mencetak itu, IP membungkus ke kiri atas, membaca B
(tidak perlu) dan berakhir.
Ketika A = 0
segalanya menjadi sedikit lebih menarik. Pertama mari kita pertimbangkan A = B = 0
:
Kali ini, #
tidak melakukan apa-apa dan kami tetap di IP 0
(jalur merah sejak saat itu dan seterusnya). ?
membaca B
dan 1
mengubahnya menjadi 1
. Setelah membungkus ke sudut kiri atas, kami menekan #
lagi, jadi kami berakhir di jalur hijau, dan mencetak 1
seperti sebelumnya, sebelum mengakhiri.
Akhirnya, inilah (A, B) = (0, 1)
yang salah:
Perhatikan bahwa saya telah menghapus jalur abu-abu awal untuk kejelasan, tetapi program dimulai dengan cara yang sama, dan kita berakhir di jalur merah seperti sebelumnya. Jadi kali ini yang kedua ?
kembali 1
. Sekarang kita temui 1
. Pada titik ini, penting untuk memahami apa yang sebenarnya dilakukan digit dalam Hexagony (sejauh ini kami hanya menggunakannya pada nol): ketika digit dijumpai, nilai saat ini dikalikan dengan 10 dan kemudian digit ditambahkan. Ini biasanya digunakan untuk menulis angka desimal kata demi kata ke dalam kode sumber, tetapi itu berarti bahwa B = 1
sebenarnya dipetakan ke nilai 11
. Jadi ketika kita menekan #
, ini diambil modulo 6
untuk diberikan 5
dan karenanya kita beralih ke IP 5
(bukan 1
seperti sebelumnya) dan melanjutkan di jalur biru. Memukul?
ketiga kalinya mengembalikan nol, sehingga !
mencetak itu, dan setelah dua yang lain ?
, IP membungkus ke kanan bawah di mana program berakhir.
Ada empat solusi 7-byte untuk ini dan mereka semua bekerja secara berbeda:
#)/!?@$ <!?_@#1 \#??!1@ |/)#?@!
1100
: Tidak a
? (
~ ! @
. .
Hanya yang linier sederhana: baca A
dengan ?
, negasikan dengan (~
, cetak dengan !
, akhiri dengan @
.
Ada satu solusi alternatif, dan itu meniadakan dengan ~)
:
?~)!@
1101
: A menyiratkan B
? .
| @ !
) .
Ini jauh lebih sederhana daripada implikasi sebaliknya yang baru saja kita bicarakan. Lagi-lagi ini adalah salah satu program cabang horizontal, seperti untuk and
. Jika A
adalah 0
, itu hanya akan bertambah untuk 1
di cabang bawah dan dicetak. Kalau tidak, cabang teratas dieksekusi lagi di mana ?
membaca B
dan kemudian !
mencetaknya.
Ada banyak alternatif di sini (total 66 solusi), sebagian besar karena pilihan bebas dari no-op yang efektif. Sebagai permulaan kami dapat memvariasikan solusi di atas dengan semua cara yang sama yang kami bisa lakukan and
dan kami juga dapat memilih antara )
dan 1
:
?.|@!) .?|@!) ?=|@!) =?|@!) ?_|@!) _?|@!) ?0|@!)
?.|@!1 .?|@!1 ?=|@!1 =?|@!1 ?_|@!1 _?|@!1 ?0|@!1
?.>@!) .?>@!) ?=>@!) =?>@!) ?_>@!) _?>@!) ?0>@!)
?.>@!1 .?>@!1 ?=>@!1 =?>@!1 ?_>@!1 _?>@!1 ?0>@!1
Dan kemudian ada versi yang berbeda menggunakan pemilihan IP bersyarat, di mana perintah pertama dapat dipilih hampir secara sewenang-wenang, dan ada juga pilihan antara )
dan 1
untuk beberapa opsi tersebut:
"?#1!@ &?#1!@ '?#1!@ )?#1!@ *?#1!@ +?#1!@ -?#1!@ .?#1!@
0?#1!@ 1?#1!@ 2?#1!@ 3?#1!@ 4?#1!@ 5?#1!@ 6?#1!@ 7?#1!@
8?#1!@ 9?#1!@ =?#1!@ ^?#1!@ _?#1!@ {?#1!@ }?#1!@
"?#)!@ &?#)!@ '?#)!@ *?#)!@ +?#)!@ -?#)!@
0?#)!@ 2?#)!@ 4?#)!@ 6?#)!@
8?#)!@ ^?#)!@ _?#)!@ {?#)!@ }?#)!@
1110
: Nand
? $
@ # )
! <
Yang rumit terakhir. Jika Anda masih membaca, Anda hampir berhasil. :) Mari kita lihat A = 0
dulu:
?
membaca A
dan kemudian kami menekan $
. Ini adalah perintah lompatan (seperti perintah Befunge #
) yang melompati instruksi selanjutnya sehingga kita tidak mengakhiri @
. Sebaliknya IP berlanjut di #
. Namun sejak A
itu 0
, ini tidak melakukan apa-apa. )
menambahnya 1
sehingga IP melanjutkan di jalur bawah di mana 1
dicetak. The <
mengalihkan IP ke kanan di mana ia membungkus ke sudut kiri dan program berakhir.
Selanjutnya, ketika inputnya (A, B) = (1, 0)
kita dapatkan situasi ini:
Ini pada dasarnya sama seperti sebelumnya, kecuali bahwa pada #
kita beralih ke IP 1
(jalur hijau), tapi karena B
ini 0
kita beralih kembali ke IP 0
ketika kita memukul #
kedua kalinya (jalan sekarang biru), di mana ia mencetak 1
seperti sebelumnya.
Akhirnya, A = B = 1
kasusnya:
Kali ini, saat kami #
kedua kalinya, nilai saat ini masih 1
sehingga kami tidak mengubah IP lagi. Yang <
memantulkannya dan ketiga kalinya kami menekan ?
kami mendapat nol. Oleh karena itu IP membungkus ke kiri bawah di mana !
mencetak nol dan program berakhir.
Ada sembilan solusi 7-byte total untuk ini. Alternatif pertama hanya menggunakan 1
bukannya )
:
?$@#1!<
Lalu ada dua solusi yang akan membantu Anda dengan jumlah IP switching yang terjadi:
)?#_[!@ 1?#_[!@
Ini benar-benar mengejutkan saya: bagian yang menarik adalah bahwa IP switching dapat digunakan sebagai persyaratan yang ditangguhkan. Aturan IP-switching bahasa adalah sedemikian rupa sehingga IP saat ini membuat langkah lain sebelum beralih terjadi. Jika langkah itu terjadi melalui sudut, maka nilai saat ini memutuskan cabang IP yang akan dilanjutkan jika kita pernah beralih kembali ke sana. Persisnya ini terjadi ketika input A = B = 1
. Meskipun ini semua konsisten dengan bagaimana saya mendesain bahasa, saya tidak pernah menyadari implikasi dari spesifikasi ini, jadi bagus ketika bahasa saya mengajarkan saya beberapa trik baru: D.
Lalu ada solusi ketiga yang jumlah IP switching-nya bahkan lebih buruk (walaupun tidak menggunakan efek kondisional yang ditunda):
>?1]#!@
Dan kemudian ada satu lagi:
?$@#)!<
Dan kemudian ada empat solusi setara ini, yang memang menggunakan beberapa IP switching non-kondisional dan sebaliknya menerapkan semua logika melalui cabang dan sudut:
]<?<@!) ]<?<@!1 ]|?<@!) ]|?<@!1
1111
: Benar
1 !
@ . .
. .
Anda telah mendapatkan sendiri sesuatu yang sederhana untuk akhir: mengatur untuk 1
, mencetak dengan !
, mengakhiri dengan @
. :)
Tentu saja, ada satu alternatif:
)!@
Seperti biasa, semua diagram alir kontrol dibuat dengan HexagonyColorer Timwi dan diagram memori dengan EsotericIDE- nya .