Dalam gim Tetris , ada 7 jenis batu bata atau Tetr i minoes , yang secara matematis dikenal sebagai tetr o minoes karena semuanya dibuat dengan 4 segmen persegi:
Memiliki nama I, J, L, O, S, T, dan Z, yang sesuai dengan bentuk perkiraan mereka. Menghitung rotasi 90 °, total ada 19 bentuk unik:
I
I
I
I
IIII
J
J
JJ
JJJ
J
JJ
J
J
J
JJJ
L
L
LL
L
LLL
LL
L
L
LLL
L
OO
OO
SS
SS
S
SS
S
TTT
T
T
TT
T
T
TTT
T
TT
T
ZZ
ZZ
Z
ZZ
Z
Tantangan
Tulis blok kode segi empat yang bertindak sebagai segmen dasar dari 19 bentuk ini. Ketika kode ini disusun menjadi salah satu bentuk, sebuah program harus dibentuk yang menampilkan huruf besar tunggal yang terkait dengan bentuk itu. Ini harus bekerja untuk semua 19 bentuk.
Area kosong terkemuka yang hadir dalam beberapa 19 bentuk diisi seluruhnya dengan spasi ( ). Area kosong yang tertinggal tidak diisi dengan apa pun (sehingga program tidak selalu persis persegi panjang).
Contoh
Misalkan ini adalah blok kode Anda:
ABC
123
Maka salah satu susunan blok ke dalam potongan S Tetris akan menjadi program yang mencetak S
:
ABCABC
123123
ABCABC
123123
ABC
123
ABCABC
123123
ABC
123
(Perhatikan bahwa semua ruang kosong terdepan diisi dengan karakter spasi, dan tidak ada garis yang memiliki spasi tambahan.)
Ide yang sama berlaku untuk semua 6 bagian lainnya dan rotasi masing-masing.
Catatan
- Semua 19 program final harus dijalankan dalam bahasa pemrograman yang sama.
- Jika diinginkan, Anda dapat menambahkan satu baris baru untuk semua program (bukan hanya beberapa, semua atau tidak sama sekali).
- Blok kode Anda dapat berisi karakter apa pun (termasuk spasi) yang bukan terminator baris .
- Keluarkan surat ke stdout (atau alternatif terdekat bahasa Anda) dengan baris tambahan opsional.
Mencetak gol
Kiriman yang blok kodenya memiliki area terkecil (lebar kali tinggi) menang. Ini pada dasarnya berarti kode terpendek menang, itulah sebabnya ini ditandai dengan kode-golf . Tiebreaker pergi ke jawaban terpilih tertinggi .
The ABC\n123
contoh memiliki area 3 × 2 = 6.
Potongan
Diberikan blok kode, cuplikan ini akan menghasilkan semua 19 program:
<script>function drawShape(X,n,v){for(var t="",e=0;e<v.length;e++)for(var l=0;l<n.length;l++){for(var r=0;r<v[e].length;r++)t+="X"===v[e][r]?n[l]:X[l];t+="\n"}return t}function go(){var X=document.getElementById("input").value;if(0!=X.length){var n=X.replace(/./g," ").split("\n");X=X.split("\n");for(var v="I (v1):|I (v2):|J (v1):|J (v2):|J (v3):|J (v4):|L (v1):|L (v2):|L (v3):|L (v4):|O:|S (v1):|S (v2):|T (v1):|T (v2):|T (v3):|T (v4):|Z (v1):|Z (v2):".split("|"),t="X\nX\nX\nX|XXXX| X\n X\nXX|XXX\n X|XX\nX\nX|X\nXXX|X\nX\nXX| X\nXXX|XX\n X\n X|XXX\nX|XX\nXX| XX\nXX|X\nXX\n X|XXX\n X|X\nXX\nX| X\nXXX| X\nXX\n X|XX\n XX| X\nXX\nX".split("|"),e="",l=0;l<v.length;l++)e+=v[l]+"\n\n"+drawShape(n,X,t[l].split("\n"))+"\n";e=e.substring(0,e.length-2),document.getElementById("output").value=e}}</script><style>html *{font-family: monospace;}</style>Code Block:<br><textarea id='input' rows='8' cols='64'>ABC
123</textarea><br><button type='button' onclick='go()'>Go</button><br><br>All 19 Programs:<br><textarea id='output' rows='24' cols='64'></textarea>
sumber
Jawaban:
<> <(Ikan) - 12 * 32 = 384
Saya berencana untuk mencari solusi yang lebih elegan, tapi entah bagaimana saya berakhir dengan ini, yang sangat kasar:
Ini cukup sederhana, memeriksa kode dalam kotak 3x3 untuk teks dan menggunakan hasil untuk melihat tetrimino yang sesuai dengan bentuk kode. Saya belum mengambil banyak usaha untuk golf itu.
Coba kodenya di sini (setelah menggunakan snippet untuk membentuknya seperti tetrimino)
Contoh kode dalam bentuk Z (v1) di sini
sumber
C (gcc) ,
26x20 = 52025x19 = 47523x17 = 391Saya baru-baru ini diberitahu tentang atribut fungsi GNU, dan yang paling menarik adalah
constructor
atributnya, yang memungkinkan untuk implementasi yang lebih singkat dari apa yang saya lakukan dengan cara yang lebih bundaran dalam pendekatan saya sebelumnya untuk masalah ini.Dorongan ide sama dengan sebelumnya: Bangun string dan mencarinya dalam daftar untuk mengidentifikasi blok tetris mana kode diletakkan. Ini dilakukan dengan memanggil fungsi, masing-masing menambahkan karakter ke string. Komplikasi itu dan tetap bahwa jumlah fungsi bervariasi.
Menentukan fungsi dengan
attribute((constructor(x)))
membuatnya agar fungsi dijalankan sebelummain()
dimasukkan, dengan opsionalx
menjadi prioritas (lebih rendah berarti dijalankan sebelumnya). Ini menghilangkan kebutuhan untuk pointer fungsi, yang memungkinkan kita untuk menjatuhkan makro, beberapa deklarasi, dan rantai panggilan.Menggunakan
__LINE__
untuk prioritas adalah rapuh, karena tingkat prioritas 0-100 dicadangkan. Namun, itu tidak menghasilkan kesalahan, hanya peringatan, dan itu banyak ketika bermain golf, jadi apa lagi?Itu akan membantu mencukur kolom lain untuk tidak menggunakan prioritas sama sekali, tetapi urutan eksekusi tampaknya tidak didefinisikan. (Mereka terbalik dalam kasus ini, tetapi tes lain tidak dapat disimpulkan.)
Contoh L v2 di sini
Pendekatan yang lebih tua, lebih portabel,
Salah satu masalah favorit saya yang saya pecahkan di situs ini.
Saya mulai dengan mencari tahu setiap blok akan ilahi koordinat sendiri entah bagaimana. Barisnya mudah
__LINE__
, dan jumlah blok yang berdekatan secara horizontal dapat ditemukan dengan menggunakan panjang string literal, seperti:Ambil panjang string yang dihasilkan dan dan bagi dengan jumlah yang tepat dan Anda memiliki lebar. Sayangnya, ruang kosong sebelum blok tidak terlihat oleh metode ini. Saya masih menduga string akan menjadi solusi, karena spasi hanya memiliki makna luar string sangat jarang, dalam hal-hal seperti
a+++b
vs.a+ ++b
. Saya secara singkat mempertimbangkan sesuatu seperti itu, tetapi tidak dapat menemukan sesuatu yang berguna. Kemungkinan lain adalah membiarkan pengidentifikasi "direkatkan" bersama-sama ketika blok bertemu:Saya tidak akan terkejut jika ini masih bisa menjadi solusi yang menarik.
Terlepas dari kesederhanaannya, butuh beberapa waktu untuk menemukan solusi string, yang didasarkan pada fragmen blok ini:
Jika fragmen tidak memiliki tetangga horizontal, baris baru pada baris kedua diloloskan oleh garis miring terbalik, membuat string dengan panjang 2. Jika, bagaimanapun, memiliki tetangga, garis miring terbalik akan lepas dari tanda queri di awal baris 2 dari blok selanjutnya:
Ini akan membuat string "\" "dengan panjang 5.
Lebih penting lagi, ini juga memungkinkan deteksi ruang kosong sebelum blok:
Lagi-lagi, baris baru diloloskan, dan spasi putih dari blok kosong di sebelah kiri termasuk dalam string "" panjang 6 yang dihasilkan.
Total ada tujuh konfigurasi blok yang berbeda pada satu baris yang perlu kita khawatirkan, dan semuanya membuat string dengan panjang yang unik:
Blok akhir tentu saja tidak memiliki panjang yang pendek, tetapi prinsipnya sama terlepas dari ukuran blok. Ini juga memiliki bonus yang tidak diperlukan mekanisme terpisah untuk mendeteksi lebar. Dengan menambahkan karakter yang sesuai dengan panjang string ini ke string hasil, masing-masing dari 19 konfigurasi menghasilkan string yang unik, yang hanya perlu dibandingkan dengan daftar yang sesuai setelah semua blok dijalankan.
Setelah ini disortir, masalah besar berikutnya adalah bagaimana "mengunjungi" setiap baris blok. Dalam C, kami sangat terbatas pada apa yang bisa dilakukan di luar fungsi. Kita juga perlu
main()
muncul, tetapi hanya sekali. Yang terakhir mudah dicapai oleh beberapa#define
s, tetapi jika kita ingin kode blok berikutnya berada di dalammain()
, masalah bagaimana mengetahui kapan harus menempatkan braket keriting penutupan akhir. Lagi pula, kita tidak tahu berapa banyak baris balok yang akan digunakan. Jadi kita perlu memilikimain()
statis dan entah bagaimana sisanya menjadi dinamis.Jika baris-blok lainnya harus mandiri, mereka harus fungsi, tetapi kita perlu memastikan setiap fungsi memiliki nama yang unik, sementara juga cukup dapat diprediksi untuk dapat dipanggil dari
main()
. Kita juga membutuhkan mekanisme untuk mengetahui fungsi mana yang sebenarnya dipanggil. Membuat nama-nama unik diselesaikan oleh makro pembantu:Memanggil
F
akan membuat pengenal yang namanya dimulai dengan f dan diakhiri dengan nomor baris.A
melakukan hal yang sama tetapi dengan awalan sebagai, yang digunakan untuk bagian kedua dari solusi, yang merupakan pointer fungsi. Kami mendeklarasikan empat petunjuk tersebut:Karena ini dinyatakan sebagai variabel global, mereka dengan mudah diatur ke NULL. Nantinya, setiap blok-baris akan memiliki bagian kode berikut:
Ini pertama-tama akan mendeklarasikan suatu fungsi, mendefinisikan pointer fungsi yang sesuai untuk menunjuk ke fungsi itu (kita hanya dapat mendefinisikan global sekali, tetapi deklarasi sebelumnya tidak dihitung sebagai definisi, bahkan jika itu diinisialisasi ke NULL), dan kemudian mendefinisikan aktual fungsi. Ini memungkinkan Anda
main()
memanggil fungsi apa saja yang bukan NULL (a17 tidak akan pernah menjadi NULL):Melakukannya akan membangun string
r
, yang kemudian dicari dalam tabel string dan jika ditemukan, huruf yang sesuai adalah output.Satu-satunya trik yang tersisa adalah bahwa daftar string yang cocok dengan itu dipersingkat setiap kali ambiguitas dapat dihindari, atau string yang tumpang tindih dapat digabungkan.
Contoh L v2 di sini
sumber
opcode x86 (.com),
8682 bytePenguji:
Sumber:
Jalankan di win7dos di mana init AX = 0, SI = 100, BX = 0 Referensi
sumber
mov bx, 100h
di awal.