Pertanyaan ini diinspirasi oleh sampul buku "Godel, Escher, Bach":
Tantangannya di sini adalah untuk menulis fungsi yang memberi tahu jika tiga huruf yang diberikan dapat menghasilkan patung 3D yang dapat dibaca dari tiga sisi.
Untuk latihan ini, satu-satunya huruf yang dapat Anda gunakan adalah 26 5px * 5px bitmap:
Atau dalam biner (A ke Z):
01110 11110 01111 11110 11111 11111 11111 10001 11111 11111 10001 10000 10001 10001 01110 11110 01110 11110 01111 11111 10001 10001 10001 10001 10001 11111
10001 10001 10000 10001 10000 10000 10000 10001 00100 00100 10010 10000 11011 11001 10001 10001 10001 10001 10000 00100 10001 10001 10001 01010 01010 00010
10001 11110 10000 10001 11100 11110 10011 11111 00100 00100 11100 10000 10101 10101 10001 10001 10001 11111 01110 00100 10001 01010 10001 00100 00100 00100
11111 10001 10000 10001 10000 10000 10001 10001 00100 10100 10010 10000 10001 10011 10001 11110 10011 10010 00001 00100 10001 01010 10101 01010 00100 01000
10001 11110 01111 11110 11111 10000 11111 10001 11111 11100 10001 11111 10001 10001 01110 10000 01111 10001 11110 00100 01110 00100 01010 10001 00100 11111
Patung ini dibentuk oleh tiga huruf dengan urutan sebagai berikut:
- huruf satu di atas,
- huruf dua di sebelah kiri
- huruf tiga di sebelah kanan
- bagian bawah huruf satu terikat ke bagian atas huruf dua.
Contoh:
Fungsi Anda dapat menerima sebagai input tiga huruf besar (tiga karakter atau tiga string dari satu huruf), dan menghasilkan boolean (benar / salah atau 0/1) mengatakan jika patung yang sesuai dapat ada.
Contoh:
f("B","E","G") // true (because if you "sculpt out" B on top + E on the left + G on the right, and watch the three sides of the sculpture, you'll see exactly B, E and G as they are defined)
f("B","G","E") // false (because if you "sculpt out" B on top + G on the left + E on the right, and watch the three sides of the sculpture, you won't see a complete G and a complete E. Their shapes bother each other)
NB: Anda dapat mengembalikan true bahkan jika patung itu mengandung "piksel terbang" (kubus atau kelompok kubus yang tidak terikat dengan apa pun).
Celah standar berlaku.
Lebih tepatnya, Anda tidak dapat menggunakan input eksternal selain tiga huruf, dan Anda tidak dapat membuat kode kemungkinan 17576 jawaban yang mungkin dalam kode sumber Anda
Jawaban terpendek dalam karakter dalam bahasa apa pun akan menang!
Selamat bersenang-senang :)
Jawaban:
Mathematica 423
Saya menambahkan bagian yang disebut "Bagaimana cara memblokir"
Tidak disatukan
(* Data biner dari alfabet disimpan sebagai string tunggal
s
.vars
Impor dan mengubahnya menjadi array.)Contoh
Apakah kubus itu
{"B", "G", "E"}
valid? (Yaitu Apakah tiga huruf memproyeksikan dengan benar ke dinding?)Ilustrasi
Gambar di bawah ini menunjukkan bagaimana BGE ditampilkan. Baris atas gambar mengambil perspektif ortogonal, seolah-olah pemirsa diposisikan pada jarak tak terbatas dari kubus. Baris bawah menunjukkan bagaimana blok akan terlihat dari dekat. Gambar 3D dapat diputar secara manual untuk memeriksa secara tepat di mana masing-masing unit kubus diposisikan.
Terjadi masalah dengan huruf "G". Tidak ada yang menghubungkan serif ke seluruh surat.
BEG, bagaimanapun, harus bekerja dengan baik.
Bagaimana Cara Kerja Pemblokiran?
Maafkan saya jika ini tampak jelas, tetapi mungkin beberapa orang akan ingin memvisualisasikan bagaimana cara huruf saling mengganggu, membatalkan piksel 3D mereka.
Mari kita ikuti apa yang terjadi pada huruf G, dalam rendering kubus BGE.
Kami akan memberi perhatian khusus pada voxel (3D pixel atau unit cube) di bawah ini. Itu adalah piksel yang hilang di kubus BGE. Ini adalah pixel yang sesuai dengan Baris 4, Kolom 5 dalam array bit dan dalam plot array yang sesuai.
Dalam bidang xy, piksel berhubungan dengan disk abu-abu di titik (5,2). Tetapi karena kita akan bekerja dalam 3D, kita perlu mempertimbangkan 5 posisi dalam poros dari (5,1,2) hingga (5,5,2). Jika salah satu dari piksel tersebut bertahan mematung oleh huruf B dan E, kita akan dapat melihat piksel yang menarik dalam proyeksi 3D di dinding.
Huruf mengganggu ketika piksel dihapus dari blok padat. Di sebelah kiri, panah hitam mewakili ukiran piksel, sesuai dengan bit di kanan bawah; memiliki nilai 0 untuk huruf B. Ukiran menghilangkan piksel pada (5,1,2), bersama dengan yang langsung di atas dan di bawahnya. Empat piksel tetap harus diperhitungkan.
Tetapi seperti yang ditunjukkan panel kanan, huruf E memahat sisa piksel yang diminati, (5,2,2) (5,3,2), (5,4,2) dan (5,5,2). (Ini disebabkan oleh fakta bahwa huruf E memiliki bit sama dengan 0 pada baris keempat, dari kolom 2 hingga kolom 5.) Akibatnya, tidak ada satu piksel pun yang tersisa untuk memastikan keteduhan pada titik (5). , 2) di dinding jauh (untuk huruf G). Sebaliknya, akan ada titik terang yang sesuai dengan lubang pada huruf G! Kubus BGE tidak baik karena membuat G. salah
Golf 423 karakter
Fungsi
h
melayani peran yang sama sepertivalidQ
dalam kode yang tidak disatukan. Fungsi rendering,,perspective
tidak dimasukkan karena tidak berkontribusi, dan tidak diperlukan oleh, tantangan.sumber
Prolog,
440, 414Program ini dinamakan seperti ini:
Prolog
tampaknya menjadi pilihan yang baik, karena mudah untuk merepresentasikan masalah dalam logika urutan pertama. JugaProlog
menyediakan fungsionalitas yang kuat untuk memecahkan masalah semacam ini.Namun, karena kode golf, saya kira saya harus menambahkan beberapa penjelasan.
Versi golf ringan
Koordinat yang sesuai dengan piksel di setiap sisi dadu dapat dengan mudah dikonversi ke sistem koordinat 3D. Saya menggunakan
T
,L
danR
untuk sisi atas (1), kiri (2) dan kanan (3).u
danv
digunakan untuk koordinat dalam gambar:(u,v) -> (4-v, ?, u)
(u,v) -> (?, v, u)
(u,v) -> (u, v, ?)
Hasil untuk setiap piksel aktif (mis. Hitam) digabungkan ke satu set "3D-piksel" yang dapat diambil tanpa mengubah tampilan objek dari sisi ini. Perpotongan set untuk setiap sisi semuanya adalah 3D-piksel, yang dapat diaktifkan tanpa menambahkan piksel, yang akan menghalangi tampilan (yaitu melihat dari setidaknya satu sisi akan ada piksel yang seharusnya tidak ada di sana).
Yang tersisa adalah memeriksa setiap sisi, jika ada piksel di persimpangan yang menghalangi tampilan, jika perlu.
Ini mengarah ke predikat dalam program:
c : memeriksa piksel pada gambar surat. String di sana mungkin terlihat sedikit aneh, tetapi itu hanya cara yang ringkas untuk menyimpan data gambar. Ini hanya urutan karakter dengan nilai berikut (notasi hex):
Masing-masing karakter ini menyimpan data untuk 3 baris piksel dalam gambar huruf (= 15 piksel). Pixel juga disusun ulang sehingga data disimpan di satu lokasi dan tidak dibagi di beberapa baris, seperti data OP.
Formulasi matematika
Memasukan data
Konversi dari piksel dalam satu karakter ke kumpulan 3D-piksel yang menghalangi tampilan untuk piksel ini
Piksel yang dapat ditambahkan dengan aman (tanpa menghalangi tampilan di tempat yang salah)
Memeriksa setiap sisi, bahwa piksel yang perlu dihalangi dapat terhalang dengan aman
Kombinasi cek untuk setiap sisi
sumber
J -
223197191 charFungsi mengambil daftar tiga karakter sebagai argumen.
Golf ini sangat bergantung pada fitur kuat dari peringkat J yang disebut , yang memberi kita operasi "pahat" dan "tontonan" hampir gratis. Untuk menyederhanakannya sedikit, peringkat mengacu pada dimensi dari kata benda atau argumen alami kata kerja.
J memiliki array multidimensi, dan jelas bahwa, katakanlah, array 3D dapat diartikan sebagai array 3D tunggal, atau sebagai daftar matriks, atau array vektor 2D, atau array skalar 3D. Jadi setiap operasi di J dapat memiliki aplikasinya yang dikontrol, bagaimana cara menyebarkan argumen. Peringkat 0 berarti berlaku pada skalar, peringkat 1 berarti berlaku pada vektor, dan seterusnya.
Ini menjadi sangat kuat ketika Anda memperkenalkan fungsi diad (dua argumen), karena jika bentuk dari dua argumen (setelah memperhitungkan peringkat) dapat disetujui, J akan melakukan beberapa perulangan implisit:
Ketika semua bentuk Anda disetujui dan Anda dapat menentukan peringkatnya sendiri, ada banyak cara untuk menggabungkan argumen. Di sini kami memamerkan beberapa cara Anda dapat melipatgandakan matriks 2D dan array 3D.
Anda akan melihat bahwa ini tidak benar-benar diukir dalam huruf-huruf dalam orientasi yang ditanyakan oleh pertanyaan, itu hanya menulis mereka namun nyaman untuk logika peringkat. Kecuali kita membalikkan atau memutar huruf sebelum kita menerapkannya, itu tidak akan berfungsi dengan baik. Tetapi mengoreksi hal-hal seperti itu akan mengambil karakter yang berharga, jadi alih-alih kita akan menyandikan huruf-huruf sehingga, ketika J memahatnya secara alami, beberapa wajah akan berada dalam orientasi dan posisi relatif yang benar. Ternyata solusi terpendek adalah memutar semua bentuk huruf seperempat putaran berlawanan arah jarum jam. Mempertimbangkan dimensi ketiga J untuk mewakili sumbu depan-ke-belakang, diagram kasar di bawah ini menunjukkan mengapa skema ini bekerja.
Gambar A: Tiga sisi kubus yang diukir J. Gambar B: Tiga sisi yang memiliki huruf berorientasi seperti pertanyaan bertanya.
Pilihan dalam penyandian ini menyimpan 12 karakter dari metode sebelumnya, dan membuat semuanya lebih rapi. Golf yang sebenarnya menciptakan kubus dari
"1
dan"2
mengukir dengan logika yang funky, karena optimasi yang tidak terkait.Maka kita harus memeriksa wajah. Karena kita mengkodekan blok sebagai 1 dan 0, kita hanya dapat menyimpulkan sepanjang masing-masing sumbu dalam cara kita inginkan (ini adalah
+/"1
,+/"2
, dan+/
bit), sesuaikan dengan boolean (0<
), dan kemudian membandingkan mereka semua langsung dengan aslinya 90 ° - berubah huruf.Skema kompresi mengkodekan setiap baris 5px dari setiap huruf sebagai representasi basis 32 dari angka biner. Dengan memanfaatkan sejumlah gula sintaksis dan kelebihan operator,
".'1b',"#:
adalah cara terpendek untuk mengubah daftar karakter menjadi angka 36 dasar. Yah, secara teknis, basis 32, tapi J menganggapnya tidak biasa, jadi siapa yang menghitung?Penggunaan di bawah. Perhatikan bahwa string adalah array karakter dalam J, sehingga daftar tiga item
'A','B','C'
dapat ditulis'ABC'
singkat. Juga, booleans adalah 1/0.sumber
Python,
687682671Panggilan dengan
v
:Semuanya di bawah ini dari versi ungolfed saya sebelumnya yang mencakup fungsi menggambar bermanfaat. Jangan ragu untuk menggunakannya sebagai titik awal.
Panggilan
valid
untuk menjalankannya:Saat ini kode sedang disiapkan untuk menguji validitas
B E G
dan mencetak wajah yang dihasilkan:Dengan menjalankannya,
B G E
kita dapat melihat bahwa G tidak benar:sumber
g=[[0 for j in s]for i in s]
dapat disingkat menjadig=map(list,[[0]*5]*5)
. Anda juga dapat menghindari indentasi blok jika mereka pernyataan tunggal:if c[e]:g[e[a]][e[a-2]]=1
.Python 3 + numpy, 327C
Solusi golf ini memerlukan perpustakaan eksternal, numpy, yang cukup populer jadi saya pikir tidak masalah untuk menggunakannya.
String unicode ada di 41 karakter, sedangkan hal yang sama dalam jawaban prolog @ fabian adalah 44.
Yang paling menarik di sini adalah pengindeksan numpy array. Di
a[ix]
,ix
bisa berupa array boolean dengan bentuk yang sama dengana
. Itu sama dengan mengatakana[i, j, k] where ix[i, j, k] == True
.Versi Tidak Serigala
Script untuk mengompres tabel
sumber