Periksa apakah tiga huruf dapat membentuk "kubus Godel-Escher-Bach"


29

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 :)



Yap, itu teka-teki MU yang membuat saya menemukan buku itu, dan sampul buku itulah yang membuat saya memikirkan tantangan ini. Apakah ada masalah? Apakah ini bagian dari 18 lubang Anda?
xem

2
Itu akan menjadi pilihan yang baik untuk mengganti lubang 1.;) ... Sudahlah, jika ada yang salah saya karena tidak mendapatkan sesuatu lebih cepat. Ini tantangan yang sangat layak, +1!
Martin Ender

Bisakah kita mengambil data yang mendefinisikan bentuk huruf dari file eksternal, atau apakah itu perlu dimasukkan dalam sumber juga?
CesiumLifeJacket

Biner B Anda memiliki 0 di sudut kiri atas, bukan 1.
Calvin Hobbies

Jawaban:


13

Mathematica 423

Saya menambahkan bagian yang disebut "Bagaimana cara memblokir"

Tidak disatukan

(* Data biner dari alfabet disimpan sebagai string tunggal s. varsImpor dan mengubahnya menjadi array.)

vars=IntegerDigits[#,10,5]&/@Transpose[ImportString[s,"Table"]];
get[char_]:=(ToCharacterCode[char]-64)[[1]];
cube=Flatten[Table[{i,j,k},{i,5},{j,5},{k,5}],2];

(* character slice along axis *)
slice[char_,layer_,axis_,bit_]:=Insert[(Reverse@#),layer,axis]&/@Position[Reverse@vars[[get[char]]],bit]

(* cuboid assembly  *)
charBlocks[{char_,axis_,bit_}]:=Flatten[Table[slice[char,k,axis,bit],{k,5}],1]

(* letters are those whose HOLES should be sculped out of the full cube *)
sculpturePoints[letters_(*{char_,axis_,bit_}*)]:=Complement[cube,Union[Join@@(charBlocks/@letters(*{char,axis,bit}*))]];

collapse[letters_(*{char_,axis_,bit_}*),axis_]:=Union[Reverse/@(Delete[#,axis]&/@sculpturePoints[letters(*{char,axis,bit}*)])](*/.{x_,y_}\[RuleDelayed] {6-x,y}*)

vQ[l_]:=collapse[l,3]==collapse[{l[[1]]},3]\[And]collapse[l,2]==collapse[{l[[2]]},2]\[And]collapse[l,1]==collapse[{l[[3]]},1]

validQ@l_:= vQ[{{l[[1]],3,0},{l[[2]],2,0},{l[[3]],1,0}}]


perspective[letts_,view_:1]:=
Graphics3D[{AbsolutePointSize[10],Cuboid/@sculpturePoints[letts]},
ImageSize-> 120,
ViewPoint-> Switch[view,1,{0,0,\[Infinity]},2,{0,-\[Infinity],0},3,{\[Infinity],0,0},4,Top,5,Front,6,Right,True,{0,0,\[Infinity]}],
PlotLabel-> Switch[view,1,"top orthogonal view",2,"front orthogonal view",3,"right orthogonal view",4,"top close-up view",5,"front close-up view",6,"right close-up view"],
ImagePadding->10]

Contoh

Apakah kubus itu {"B", "G", "E"}valid? (Yaitu Apakah tiga huruf memproyeksikan dengan benar ke dinding?)

validQ[{"B", "G", "E"}]

Salah

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.

pts = {{"B", 3, 0}, {"G", 2, 0}, {"E", 1, 0}}
GraphicsGrid@Partition[Table[perspective[pts, view], {view, 1, 6}], 3]

membungkuk


BEG, bagaimanapun, harus bekerja dengan baik.

 validQ[{"B", "E", "G"}]

Benar

pts2 = {{"B", 3, 0}, {"E", 2, 0}, {"G", 1, 0}}
GraphicsGrid@Partition[Table[perspective[pts2, view], {view, 1, 6}], 3]

mengemis


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.

memblokir 1


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.

memblokir 2


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.

memblokir 3

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 hmelayani peran yang sama seperti validQdalam kode yang tidak disatukan. Fungsi rendering,, perspectivetidak dimasukkan karena tidak berkontribusi, dan tidak diperlukan oleh, tantangan.

x=Reverse;q=Flatten;
g@c_:=(ToCharacterCode[c]-64)[[1]];
r[{c_,a_,b_}]:=q[Table[Insert[(x@#),k,a]&/@Position[x@(IntegerDigits[#,10,5]&/@
Transpose[ImportString[s,"Table"]])[[g[c]]],b],{k,5}],1]
p@l_:=Complement[q[Table[{i,j,k},{i,5},{j,5},{k,5}],2],Union[Join@@(r/@l)]];
w[l_,a_]:=Union[x/@(Delete[#,a]&/@p[l])]
v@l_:=w[l,3]==w[{l[[1]]},3]\[And]w[l,2]==w[{l[[2]]},2]\[And]w[l,1]==w[{l[[3]]},1]

h@l_:= v[{{l[[1]],3,0},{l[[2]],2,0},{l[[3]],1,0}}]

Woah, tampilan 3D itu sangat rapi! Apakah Anda yakin blok kode terakhir adalah "Tidak Disatukan"? Sepertinya golf bagiku. :)
xem

Anda benar. Blok terakhir adalah golf. Saya mengoreksi judulnya. Satu hal yang menarik tentang tampilan 3D adalah tampilan interaktif: rotasi dan zoom dapat dilakukan dengan mouse.
DavidC

BTW, menurut perhitungan saya, ada 564 kubus yang valid di antara 15600 kemungkinan permutasi.
DavidC

Itu informasi yang bagus. Berapa lama Anda menghitungnya? juga, 26 * 26 * 26 = 17576, bukan 15600. Atau apakah saya kehilangan sesuatu?
xem

Saya menggunakan permutasi, bukan tupel; yaitu tidak ada huruf yang diulang. 26 * 25 * 24 = 15600. Butuh 21 detik untuk menemukan 564 kasus.
DavidC

12

Prolog, 440 , 414

:- encoding(utf8).
i(I) :- between(0,4,I).
h(T,L,R,X,Y,Z) :- i(X),i(Y),i(Z),I is 4-X,c(T,Z,I),c(L,Z,Y),c(R,X,Y).
f(T,L,R) :- forall((i(U),i(V),I is 4-V),((\+c(T,U,V);h(T,L,R,I,Y,U)),(\+c(L,U,V);h(T,L,R,X,V,U)),(\+c(R,U,V);h(T,L,R,U,V,Z)))).
c(C,X,Y) :- char_code(C,N),i(X),i(Y),Z is X+5*Y+25*(N-65),I is floor(Z/15),O is (Z mod 15),string_code(I,"䙎㹟䘑߯硁䙏縑ԁࠟя摟䠑䠑ᐑ粤Ⴟ䔅┉ё籁垑䙑曓䗱㩑䙏㡏晑䘞䕟㡞縐Ⴄ䙄㩑⩑䒪噑⩊䕤ᅱ粤ࢨ?",V),1 is (V-32)>>O/\1.

Program ini dinamakan seperti ini:

?- f('B','E','G').
true.
?- f('B','G','E').
false.

Prologtampaknya menjadi pilihan yang baik, karena mudah untuk merepresentasikan masalah dalam logika urutan pertama. Juga Prologmenyediakan fungsionalitas yang kuat untuk memecahkan masalah semacam ini.

Namun, karena kode golf, saya kira saya harus menambahkan beberapa penjelasan.

Versi golf ringan

:- encoding(utf8).
i(I) :- between(0,4,I).
t(C,X,Z) :- I is 4-X,c(C,Z,I).
l(C,Y,Z) :- c(C,Z,Y).
r(C,X,Y) :- c(C,X,Y).
h(T,L,R,X,Y,Z) :- i(X),i(Y),i(Z),t(T,X,Z),l(L,Y,Z),r(R,X,Y).
u(T,L,R) :- forall((i(U),i(V),I is 4-V,c(T,U,V)),h(T,L,R,I,Y,U)).
v(T,L,R) :- forall((i(U),i(V),c(L,U,V)),h(T,L,R,X,V,U)).
w(T,L,R) :- forall((i(U),i(V),c(R,U,V)),h(T,L,R,U,V,Z)).
f(T,L,R) :- u(T,L,R),v(T,L,R),w(T,L,R).
c(C,X,Y) :- char_code(C,N),i(X),i(Y),Z is X+5*Y+25*(N-65),I is floor(Z/15),O is (Z mod 15),string_code(I,"䙎㹟䘑߯硁䙏縑ԁࠟя摟䠑䠑ᐑ粤Ⴟ䔅┉ё籁垑䙑曓䗱㩑䙏㡏晑䘞䕟㡞縐Ⴄ䙄㩑⩑䒪噑⩊䕤ᅱ粤ࢨ?",V),1 is (V-32)>>O/\1.

Koordinat yang sesuai dengan piksel di setiap sisi dadu dapat dengan mudah dikonversi ke sistem koordinat 3D. Saya menggunakan T, Ldan Runtuk sisi atas (1), kiri (2) dan kanan (3). udan vdigunakan untuk koordinat dalam gambar:

  • T :(u,v) -> (4-v, ?, u)
  • L :(u,v) -> (?, v, u)
  • R :(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:

  • f : apakah pemeriksaan terakhir; mengambil huruf di bagian atas, sisi kiri dan kanan
  • u , v dan w : lakukan pemeriksaan, jika untuk setiap piksel aktif di samping ada 3D-pixel di persimpangan, yang menghalangi tampilan
  • h : memeriksa, untuk keberadaan piksel di persimpangan
  • t , l , r : memeriksa, apakah 3D-pixel dapat diblokir dari atas, kiri dan kanan.
  • 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):

    [464e,3e5f,4611,7ef,7841,464f,7e11,501,81f,44f,645f,4811,4811,1411,7ca4,10bf,4505,2509,451,7c41,5791,4651,66d3,45f1,3a51,464f,384f,6651,461e,455f,385e,7e10,10a4,4644,3a51,2a51,44aa,5651,2a4a,4564,1171,7ca4,8a8,3f]
    

    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

rumus

Memasukan data

rumus

Konversi dari piksel dalam satu karakter ke kumpulan 3D-piksel yang menghalangi tampilan untuk piksel ini

rumus

rumus

rumus

Piksel yang dapat ditambahkan dengan aman (tanpa menghalangi tampilan di tempat yang salah)

rumus

Memeriksa setiap sisi, bahwa piksel yang perlu dihalangi dapat terhalang dengan aman

rumus

rumus

rumus

Kombinasi cek untuk setiap sisi

rumus


1
Saya .. Eh .. Apa? Saya menemukan ini tidak bisa dimengerti. (+1)
seequ

Kudus ... aku akan tidur ...
BrunoJ

Impresif! Terima kasih atas jawaban ini
xem

1
Bagus. btw, saya pikir prosesnya dimulai dengan blok kubik padat. (Anda tampaknya menganggapnya sebagai menambahkan piksel di mana tidak ada sebelumnya.) Setiap huruf menghapus beberapa piksel 3D dari blok itu. Jadi gangguan muncul ketika surat tetangga menghapus piksel yang huruf "ingin tetap". Gangguan berasal dari "piksel yang hilang" dan bukan piksel ekstra.
DavidC

9

J - 223 197 191 char

Fungsi mengambil daftar tiga karakter sebagai argumen.

(_5#:\".'1b',"#:'fiiifalllvhhhheehhhvhhllvgkkkvnlhhvv444vhhvhhggvhjha44v1111vv848vv248vehhheciiivfjhhedmkkvilll9ggvggu111uo616ou121uha4ahg878ghpljh')((-:0<+/"1,+/"2,:+/)*`(*"1/)/)@:{~_65+3&u:

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.

   1 + 2 + 3 + 4  NB. add these things together
10
   +/ 1 2 3 4     NB. sum the list by adding its items together
10
   i. 3 4         NB. 2D array, with shape 3-by-4
0 1  2  3
4 5  6  7
8 9 10 11
   +/"2 i. 3 4    NB. add the items of the matrix together
12 15 18 21
   0 1 2 3 + 4 5 6 7 + 8 9 10 11    NB. equivalent
12 15 18 21
   +/"1 i. 3 4    NB. now sum each vector!
6 22 38
   +/"0 i. 3 4    NB. now sum each scalar!
0 1  2  3
4 5  6  7
8 9 10 11

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:

   10 + 1             NB. scalar addition
11
   10 20 30 + 4 5 6   NB. vector addition, pointwise
14 25 36
   10 + 4 5 6         NB. looping! 
14 15 16
   10 20 + 4 5 6      NB. shapes do not agree...
|length error
|   10 20    +4 5 6

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.

   n =: i. 5 5
   n
 0  1  2  3  4
 5  6  7  8  9
10 11 12 13 14
15 16 17 18 19
20 21 22 23 24
   <"2 n *"2 (5 5 5 $ 1)  NB. multiply by 2-cells
+--------------+--------------+--------------+--------------+--------------+
| 0  1  2  3  4| 0  1  2  3  4| 0  1  2  3  4| 0  1  2  3  4| 0  1  2  3  4|
| 5  6  7  8  9| 5  6  7  8  9| 5  6  7  8  9| 5  6  7  8  9| 5  6  7  8  9|
|10 11 12 13 14|10 11 12 13 14|10 11 12 13 14|10 11 12 13 14|10 11 12 13 14|
|15 16 17 18 19|15 16 17 18 19|15 16 17 18 19|15 16 17 18 19|15 16 17 18 19|
|20 21 22 23 24|20 21 22 23 24|20 21 22 23 24|20 21 22 23 24|20 21 22 23 24|
+--------------+--------------+--------------+--------------+--------------+
   <"2 n *"1 (5 5 5 $ 1)  NB. multiply by vectors
+---------+---------+--------------+--------------+--------------+
|0 1 2 3 4|5 6 7 8 9|10 11 12 13 14|15 16 17 18 19|20 21 22 23 24|
|0 1 2 3 4|5 6 7 8 9|10 11 12 13 14|15 16 17 18 19|20 21 22 23 24|
|0 1 2 3 4|5 6 7 8 9|10 11 12 13 14|15 16 17 18 19|20 21 22 23 24|
|0 1 2 3 4|5 6 7 8 9|10 11 12 13 14|15 16 17 18 19|20 21 22 23 24|
|0 1 2 3 4|5 6 7 8 9|10 11 12 13 14|15 16 17 18 19|20 21 22 23 24|
+---------+---------+--------------+--------------+--------------+
   <"2 n *"0 (5 5 5 $ 1)  NB. multiply by scalars
+---------+---------+--------------+--------------+--------------+
|0 0 0 0 0|5 5 5 5 5|10 10 10 10 10|15 15 15 15 15|20 20 20 20 20|
|1 1 1 1 1|6 6 6 6 6|11 11 11 11 11|16 16 16 16 16|21 21 21 21 21|
|2 2 2 2 2|7 7 7 7 7|12 12 12 12 12|17 17 17 17 17|22 22 22 22 22|
|3 3 3 3 3|8 8 8 8 8|13 13 13 13 13|18 18 18 18 18|23 23 23 23 23|
|4 4 4 4 4|9 9 9 9 9|14 14 14 14 14|19 19 19 19 19|24 24 24 24 24|
+---------+---------+--------------+--------------+--------------+

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.

visualisasi kubus 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 "1dan "2mengukir 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.

   NB. can be used inline...
   (_5#:\".'1b',"#:'fiiifalllvhhhheehhhvhhllvgkkkvnlhhvv444vhhvhhggvhjha44v1111vv848vv248vehhheciiivfjhhedmkkvilll9ggvggu111uo616ou121uha4ahg878ghpljh')((-:0<+/"1,+/"2,:+/)*`(*"1/)/)@:{~_65+3&u:'BEG'
1
   NB. or assigned to a name
   geb=:(_5#:\".'1b',"#:'fiiifalllvhhhheehhhvhhllvgkkkvnlhhvv444vhhvhhggvhjha44v1111vv848vv248vehhheciiivfjhhedmkkvilll9ggvggu111uo616ou121uha4ahg878ghpljh')((-:0<+/"1,+/"2,:+/)*`(*"1/)/)@:{~_65+3&u:
   geb 'BGE'
0

4

Python, 687 682 671

import itertools as t,bz2
s=range(5)
c=dict([(i,1)for i in t.product(*3*[s])])
z=dict([(chr(i+65),[map(int,bz2.decompress('QlpoOTFBWSZTWXndUmsAATjYAGAQQABgADABGkAlPJU0GACEkjwP0TQlK9lxsG7aomrsbpyyosGdpR6HFVZM8bntihQctsSiOLrWKHHuO7ueAyiR6zRgxbMOLU2IQyhAEAdIJYB0ITlZwUqUlAzEylBsw41g9JyLx6RdFFDQEVJMBTQUcoH0DEPQ8hBhXBIYkXDmCF6E/F3JFOFCQed1Saw='.decode('base64')).split('\n')[j].split()[i])for j in s])for i in range(26)])
def m(a,g):
 for e in c:c[e]&=g[e[a]][e[a-2]]
def f(a):
 g=map(list,[[0]*5]*5)
 for e in c:g[e[a]][e[a-2]]|=c[e]
 return g
r=lambda g:map(list,zip(*g)[::-1])
def v(T,L,R):T,L,R=r(r(z[T])),r(z[L]),z[R];m(1,T);m(2,L);m(0,R);return(T,L,R)==(f(1),f(2),f(0))

Panggilan dengan v:

v('B','E','G') => True
v('B','G','E') => False

Semuanya di bawah ini dari versi ungolfed saya sebelumnya yang mencakup fungsi menggambar bermanfaat. Jangan ragu untuk menggunakannya sebagai titik awal.

import string as s
import itertools as t

az = """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""".split('\n')

dim = range(len(az))
az = dict([(c, [map(int, az[j].split()[i]) for j in dim]) for i, c in enumerate(s.uppercase)])
cube = dict([(i, 1) for i in t.product(*3*[dim])])

def mask(axis, grid):
    for c in cube:
        if not grid[c[axis]][c[axis - 2]]:
            cube[c] = 0

def face(axis):
    grid = [[0 for j in dim] for i in dim]
    for c in cube:
        if cube[c]:
            grid[c[axis]][c[axis - 2]] = 1
    return grid

def rot(grid):
    return map(list, zip(*grid)[::-1])

def draw(grid, filled='X', empty=' '):
    s = ''
    for y in dim:
        for x in dim:
            s += filled if grid[y][x] else empty
        s += '\n'
    print s

def drawAll():
    print 'TOP:\n'
    draw(rot(rot(face(1))))
    print 'LEFT:\n'
    draw(rot(rot(rot(face(2)))))
    print 'RIGHT:\n'
    draw(face(0))

def valid(top, left, right):
    top, left, right = rot(rot(az[top])), rot(az[left]), az[right]
    mask(1, top)
    mask(2, left)
    mask(0, right)
    return top == face(1)and left == face(2) and right == face(0)

letters = 'BEG'

if valid(*letters):
    print letters, 'is valid.\n'
else:
    print letters, 'is not valid!\n'

drawAll()

Panggilan validuntuk menjalankannya:

valid('B', 'E', 'G') #returns True
valid('B', 'G', 'E') #returns False

Saat ini kode sedang disiapkan untuk menguji validitas B E Gdan mencetak wajah yang dihasilkan:

BEG is valid.

TOP:

XXXX 
X   X
XXXX 
X   X
XXXX 

LEFT:

XXXXX
X    
XXX  
X    
XXXXX

RIGHT:

XXXXX
X    
X  XX
X   X
XXXXX

Dengan menjalankannya, B G Ekita dapat melihat bahwa G tidak benar:

BGE is not valid!

TOP:

XXXX 
X   X
XXXX 
X   X
XXXX 

LEFT:

XXXXX
X    
X  XX
X    
XXXXX

RIGHT:

XXXXX
X    
XXX  
X    
XXXXX

wow, kerja bagus! +1 untuk drawAll dan kelengkapan jawabannya. +1 untuk menggunakan algoritma singkat seperti itu. <3
xem

@ xem Terima kasih! Saya akhirnya golf itu. Meskipun saya tidak tahu bagaimana cara mendapatkan bz2 untuk mendekompresi karakter unicode.
Calvin Hobbies

+1. Jawaban bagus. Berharap lebih banyak orang akan meningkatkan kualitas golf yang terdiri dari golf yang lebih kecil, seperti ini, karena ini benar-benar membutuhkan usaha.
Vektor

1
g=[[0 for j in s]for i in s]dapat disingkat menjadi g=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.
Bakuriu

@ Bakuriu dan bitpwner, terima kasih atas saran dan suntingannya :)
Calvin Hobbies

1

Python 3 + numpy, 327C

from numpy import*
B=hstack([ord(x)>>i&1for x in'옮弟ჹ羂옱쏷)ជ࿂︹缘龌ℿ쓥剴ℌᾄ起츱ꎚㆋឺ௣옮忬⧼ﯠႄ挒⺌ꕆ豈ꪱ袨冊䈑∾Ϣ'for i in range(16)])[:-6].reshape(26,5,5)
T=transpose
def f(*X):
 A=ones((5,5,5));F=list(zip([A,T(A,(1,0,2)),T(fliplr(A),(2,0,1))],[B[ord(x)-65]for x in X]))
 for r,f in F:r[array([f]*5)==0]=0
 return all([all(r.sum(0)>=f)for r,f in F])

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], ixbisa berupa array boolean dengan bentuk yang sama dengan a. Itu sama dengan mengatakan a[i, j, k] where ix[i, j, k] == True.

Versi Tidak Serigala

import numpy as np
table = '옮弟ჹ羂옱쏷)ជ࿂︹缘龌ℿ쓥剴ℌᾄ起츱ꎚㆋឺ௣옮忬⧼ﯠႄ挒⺌ꕆ豈ꪱ袨冊䈑∾Ϣ'

def expand_bits(x):
    return [ord(x) >> i & 1 for i in range(16)]

# B.shape = (26, 5, 5), B[i] is the letter image matrix of the i(th) char
B = np.hstack([expand_bits(x) for x in table])[:-6].reshape(26, 5, 5)

def f(*chars):
    """
    cube:    ----------   axis:           
            /         /|      --------->2  
           /   1     / |     /|            
          /         /  |    / |            
         /         /   |   /  |            
        |---------|  3 |  v   |           
        |         |    /  1   |           
        |    2    |   /       v          
        |         |  /        0         
        |         | /                  
        -----------
    """
    cube = np.ones((5, 5, 5))
    cube_views = [
        cube,
        cube.transpose((1, 0, 2)),  # rotate to make face 2 as face 1
        np.fliplr(cube).transpose(2, 0, 1),  # rotate to make face 3 as face 1
    ]
    faces = [B[ord(char) - ord('A')] for char in chars]
    # mark all white pixels as 0 in cube
    for cube_view, face in zip(cube_views, faces):
        # extrude face to create extractor
        extractor = np.array([face] * 5)
        cube_view[extractor == 0] = 0

    return np.all([
        # cube_view.sum(0): sum along the first axis
        np.all(cube_view.sum(0) >= face)
        for cube_view, face in zip(cube_views, faces)
    ])

Script untuk mengompres tabel

import numpy as np

def make_chars():
    s = """
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
""".strip().split('\n')
    bits = np.zeros((26, 5, 5), dtype=np.bool)
    for c_id in range(26):
        for i in range(5):
            for j in range(5):
                bits[c_id, i, j] = s[i][j + c_id * 7] == '1'
    bits = np.hstack([bits.flat, [0] * 7])
    bytes_ = bytearray()
    for i in range(0, len(bits) - 8, 8):
        x = 0
        for j in range(8):
            x |= bits[i + j] << j
        bytes_.append(x)
    chars = bytes_.decode('utf16')
    return chars
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.