Kiểm tra xem ba chữ cái có thể tạo thành khối hình khối Godel-Escher-Bach


29

Câu hỏi này được lấy cảm hứng từ bìa của cuốn sách "Godel, Escher, Bach":

Thách thức ở đây là viết một hàm cho biết nếu ba chữ cái đã cho có thể tạo ra một tác phẩm điêu khắc 3D có thể được đọc từ ba mặt.

Đối với bài tập này, các chữ cái duy nhất bạn có thể sử dụng là 26 bitmap 5 5px * 5px:

Hoặc ở dạng nhị phân (A đến 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

Tác phẩm điêu khắc được hình thành bởi ba chữ cái theo thứ tự sau:

  • chữ cái trên đầu
  • chữ cái hai bên trái
  • chữ ba bên phải
  • dưới cùng của chữ một được ràng buộc với đầu của chữ cái hai.

Thí dụ:

Hàm của bạn có thể chấp nhận làm đầu vào ba chữ cái viết hoa (ba ký tự hoặc ba chuỗi của một chữ cái) và xuất ra một giá trị boolean (đúng / sai hoặc 0/1) nếu tác phẩm điêu khắc tương ứng có thể tồn tại.

Thí dụ:

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)

Lưu ý: bạn có thể trả về đúng ngay cả khi tác phẩm điêu khắc có chứa "pixel bay" (hình khối hoặc nhóm hình khối được gắn vào không có gì).

Tiêu chuẩn áp dụng.

Chính xác hơn, bạn không thể sử dụng đầu vào bên ngoài ngoài ba chữ cái và bạn không thể mã hóa 17576 câu trả lời có thể có trong mã nguồn của mình

Câu trả lời ngắn nhất trong các nhân vật trong bất kỳ ngôn ngữ chiến thắng!

Chúc vui vẻ :)



Đúng, đó là câu đố MU khiến tôi khám phá cuốn sách, và đó là bìa của cuốn sách khiến tôi nghĩ về thử thách này. Có vấn đề gì không? Đây có phải là một phần của điều 18 lỗ của bạn?
xem

2
Nó sẽ là một lựa chọn tốt để thay thế lỗ 1 .;) ... Đừng bận tâm, nếu có bất cứ điều gì đó là lỗi của tôi vì không nhận được thứ gì đó sớm hơn. Đó là một thử thách thực sự tốt, +1!
Martin Ender

Chúng ta có thể truy xuất dữ liệu xác định hình dạng của các chữ cái từ một tệp bên ngoài không, hay nó cũng cần được đưa vào nguồn?
CaesiumLifeJquet

B nhị phân của bạn có 0 ở góc trên cùng bên trái, không phải 1.
Sở thích của Calvin

Câu trả lời:


13

Toán học 423

Tôi đã thêm một phần gọi là "Cách chặn hoạt động".

Bị đánh cắp

(* Dữ liệu nhị phân của bảng chữ cái được lưu trữ dưới dạng một chuỗi s. varsNhập nó và chuyển đổi nó thành một mảng.)

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]

Thí dụ

Là khối {"B", "G", "E"}hợp lệ? (tức là ba chữ cái sẽ chiếu chính xác lên tường?)

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

Sai

Minh họa

Các hình dưới đây cho thấy BGE được hiển thị như thế nào. Hàng trên của các hình có quan điểm trực giao, như thể người xem được định vị ở khoảng cách vô hạn từ khối lập phương. Hàng dưới cho thấy các khối sẽ nhìn từ gần như thế nào. Các hình 3D có thể được xoay bằng tay để kiểm tra chính xác vị trí của các khối đơn vị riêng lẻ.

Một vấn đề xảy ra với chữ "G". Không có gì kết nối serif với phần còn lại của bức thư.

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

bge


BEG, tuy nhiên, nên hoạt động tốt.

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

Thật

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

ăn xin


Làm thế nào để chặn hoạt động?

Xin thứ lỗi cho tôi nếu điều này có vẻ rõ ràng, nhưng có lẽ một số người sẽ muốn hình dung cách các chữ cái giao thoa với nhau, hủy các pixel 3D của chúng.

Hãy theo dõi những gì xảy ra với chữ G, trong kết xuất khối BGE.

Chúng tôi sẽ đặc biệt chú ý đến voxel (pixel 3D hoặc khối đơn vị) bên dưới. Đó là pixel biến mất trong khối BGE. Đó là pixel tương ứng với Hàng 4, Cột 5 trong mảng bit và trong biểu đồ mảng tương ứng.

chặn 1


Trong mặt phẳng xy, pixel tương ứng với đĩa màu xám tại điểm (5,2). Nhưng vì chúng tôi sẽ làm việc ở chế độ 3D, chúng tôi cần xem xét 5 vị trí trong trục từ (5,1,2) đến (5,5,2). Nếu bất kỳ pixel nào trong số đó tồn tại được điêu khắc bởi các chữ B và E, chúng ta sẽ có thể thấy pixel quan tâm trong phép chiếu 3D trên tường.

chặn 2


Các chữ cái can thiệp khi các pixel bị xóa khỏi khối rắn. Ở bên trái, mũi tên màu đen đại diện cho việc khắc các pixel, tương ứng với bit ở phía dưới bên phải; nó có giá trị 0 cho chữ B. Khắc phục loại bỏ pixel ở (5,1,2), cùng với các giá trị trực tiếp bên trên và bên dưới nó. Bốn pixel vẫn được tính.

chặn 3

Nhưng như khung bên phải hiển thị, chữ E sẽ loại bỏ các pixel quan tâm còn lại, (5,2,2) (5,3,2), (5,4,2) và (5,5,2). (Điều này là do thực tế là chữ E có các bit bằng 0 ở hàng thứ tư, từ cột 2 đến cột 5.) Kết quả là, không có một pixel nào trong số các pixel cần thiết để đảm bảo bóng tại điểm (5 , 2) trên bức tường phía xa (đối với chữ G). Thay vào đó, sẽ có một điểm sáng tương ứng với một lỗ hổng trong chữ G! Khối BGE không tốt vì nó hiển thị không chính xác G.

Đã chơi 423 ký tự

Hàm này hđóng vai trò tương tự như validQtrong mã chưa được mã hóa. Chức năng kết xuất, perspectivekhông được bao gồm bởi vì nó không đóng góp và không được yêu cầu bởi thách thức.

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}}]

Ái chà, những góc nhìn 3D đó rất gọn gàng! Bạn có chắc chắn khối mã cuối cùng là "UnGolfed" không? Có vẻ như chơi golf với tôi. :)
xem

Bạn nói đúng. Khối cuối cùng là golf. Tôi sửa lại tiêu đề. Một điều thú vị về chế độ xem 3D là chúng tương tác: xoay và thu phóng có thể được thực hiện bằng chuột.
DavidC

BTW, theo tính toán của tôi, có 564 hình khối hợp lệ trong số 15600 hoán vị có thể có.
DavidC

Đó là một thông tin tốt. Bạn mất bao lâu để tính toán điều đó? Ngoài ra, 26 * 26 * 26 = 17576, không phải 15600. Hay tôi đang thiếu thứ gì?
xem

Tôi đã sử dụng hoán vị, không tuples; tức là không có chữ cái lặp đi lặp lại. 26 * 25 * 24 = 15600. Phải mất 21 giây để tìm thấy 564 trường hợp.
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.

Chương trình được gọi như thế này:

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

Prologdường như là một lựa chọn tốt, vì nó dễ dàng đại diện cho vấn đề theo logic thứ tự đầu tiên. Cũng Prologcung cấp chức năng mạnh mẽ để giải quyết loại vấn đề này.

Tuy nhiên, vì mã được đánh gôn, tôi đoán tôi nên thêm một số lời giải thích.

Phiên bản golf nhẹ

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

Các tọa độ tương ứng với các pixel ở mỗi bên của súc sắc có thể dễ dàng chuyển đổi thành hệ tọa độ 3D. Tôi sử dụng T, LRcho phía trên (1), bên trái (2) và bên phải (3). uvđược sử dụng cho tọa độ trong ảnh:

  • T :(u,v) -> (4-v, ?, u)
  • L :(u,v) -> (?, v, u)
  • R :(u,v) -> (u, v, ?)

Các kết quả cho mỗi pixel hoạt động (tức là màu đen) được kết hợp thành một tập hợp "pixel 3D" có thể được thu nhỏ mà không làm thay đổi giao diện của đối tượng từ phía này. Giao điểm của các bộ cho mỗi bên đều là các pixel 3D, có thể được kích hoạt mà không cần thêm pixel, sẽ gây cản trở chế độ xem (tức là nhìn từ ít nhất một bên sẽ có một pixel không nên có).

Tất cả những gì còn lại là kiểm tra từng bên, nếu có một pixel trong giao lộ chặn chế độ xem, khi cần thiết.

Điều này dẫn đến các vị từ trong chương trình:

  • f : kiểm tra cuối cùng; lấy các chữ cái ở trên cùng, bên trái và bên phải
  • u , vw : thực hiện kiểm tra, nếu đối với mỗi pixel hoạt động ở bên cạnh có một pixel 3D ở giao lộ, sẽ chặn chế độ xem
  • h : kiểm tra sự tồn tại của một pixel trong giao lộ
  • t , l , r : kiểm tra, nếu pixel 3D có thể bị chặn từ phía trên, bên trái và bên phải.
  • c : kiểm tra pixel trong hình ảnh của một chữ cái. Chuỗi trong đó có thể trông hơi lạ, nhưng đó chỉ là một cách nhỏ gọn để lưu trữ dữ liệu hình ảnh. Nó chỉ đơn giản là một chuỗi ký tự với các giá trị sau (ký hiệu 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]
    

    Mỗi ký tự này lưu trữ dữ liệu cho 3 hàng pixel trong (các) hình ảnh chữ cái (= 15 pixel). Các pixel cũng được sắp xếp lại để dữ liệu được lưu trữ tại một vị trí và không được chia thành nhiều hàng, giống như dữ liệu của OP.

Công thức toán học

công thức

Dữ liệu đầu vào

công thức

Chuyển đổi từ pixel trong một char thành tập hợp các pixel 3D gây cản trở chế độ xem cho pixel này

công thức

công thức

công thức

Các pixel có thể được thêm một cách an toàn (mà không cản trở tầm nhìn ở sai vị trí)

công thức

Kiểm tra cho mỗi bên, rằng các pixel cần bị cản trở có thể bị cản trở một cách an toàn

công thức

công thức

công thức

Combinatin của kiểm tra cho mỗi bên

công thức


1
Tôi .. Uh .. Cái gì? Tôi thấy điều này không thể hiểu được. (+1)
xem

Thánh ... tôi sẽ đi ngủ ...
BrunoJ

Ấn tượng! Cảm ơn câu trả lời này
xem

1
Tốt đẹp. btw, tôi nghĩ về quá trình như bắt đầu với một khối lập phương vững chắc. (Bạn dường như nghĩ về nó như thêm các pixel mà trước đó không có pixel nào.) Mỗi ​​chữ cái sẽ xóa một số pixel 3D khỏi khối đó. Vì vậy, sự can thiệp phát sinh khi một chữ cái lân cận loại bỏ các pixel mà một chữ cái "muốn giữ". Sự giao thoa bắt nguồn từ "các pixel bị thiếu" thay vì các pixel phụ.
DavidC

9

J - 223 197 191 char

Một hàm lấy một danh sách ba char làm đối số.

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

Môn gôn này phụ thuộc rất nhiều vào một tính năng mạnh mẽ của J được gọi là thứ hạng , mang đến cho chúng ta các hoạt động "điêu khắc" và "theo dõi" gần như miễn phí. Để đơn giản hóa nó một chút, thứ hạng đề cập đến tính chiều của danh từ hoặc đối số tự nhiên của động từ.

J có các mảng đa chiều, và rõ ràng là, một mảng 3D có thể được hiểu là một mảng 3D đơn lẻ, hoặc là một danh sách các ma trận, hoặc một mảng vectơ 2D hoặc một mảng vô hướng 3D. Vì vậy, mọi hoạt động trong J có thể khiến ứng dụng của nó được kiểm soát wrt làm thế nào để trải rộng đối số. Hạng 0 có nghĩa là áp dụng trên vô hướng, hạng 1 có nghĩa là áp dụng trên các vectơ, v.v.

   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

Điều này trở nên rất mạnh mẽ khi bạn giới thiệu các hàm dyadic (hai đối số), bởi vì nếu hình dạng của hai đối số (sau khi tính thứ hạng) có thể chấp nhận được, J sẽ thực hiện một số vòng lặp ngầm định:

   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

Khi tất cả các hình dạng của bạn đều dễ chịu và bạn có thể tự chỉ định thứ hạng, có nhiều cách để kết hợp các đối số. Ở đây chúng tôi trình bày một số cách mà bạn có thể nhân ma trận 2D và mảng 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|
+---------+---------+--------------+--------------+--------------+

Bạn sẽ nhận thấy rằng điều này không thực sự khắc các chữ cái theo hướng mà câu hỏi yêu cầu, nó chỉ viết chúng theo cách thuận tiện cho logic xếp hạng. Trừ khi chúng ta đảo ngược hoặc xoay các chữ cái trước khi chúng ta áp dụng chúng, nó sẽ không hoạt động đúng. Nhưng việc sửa những thứ như thế sẽ chiếm các ký tự quý giá, vì vậy thay vào đó chúng ta sẽ mã hóa các chữ cái sao cho khi J khắc chúng một cách tự nhiên, một số bộ ba khuôn mặt sẽ có hướng chính xác và vị trí tương đối. Hóa ra giải pháp ngắn nhất là xoay tất cả các mẫu chữ một phần tư ngược chiều kim đồng hồ. Xem xét chiều thứ ba của J để biểu thị trục trước-sau, sơ đồ thô dưới đây cho thấy lý do tại sao sơ ​​đồ này hoạt động.

hình dung của khối lập phương Hình A: Ba cạnh của khối lập phương mà J khắc vào. Hình B: Ba mặt có các chữ cái được định hướng giống như câu hỏi.

Sự lựa chọn này trong mã hóa giúp tiết kiệm 12 ký tự so với phương thức trước đó và làm cho toàn bộ điều gọn gàng hơn. Golf thực tế tạo ra khối lập phương ra khỏi "1"2khắc với một số logic thú vị, do một tối ưu hóa không liên quan.

Sau đó chúng ta phải kiểm tra khuôn mặt. Vì chúng ta mã hóa khối là 1s và 0s, chúng tôi chỉ có thể tóm tắt theo mỗi trục theo cách chúng ta muốn (đây là những +/"1, +/"2+/bit), điều chỉnh để boolean ( 0<), và sau đó so sánh tất cả chúng trực tiếp với bản gốc 90 ° - chữ viết tắt.

Lược đồ nén mã hóa mỗi hàng 5px của mỗi chữ cái dưới dạng đại diện 32 cơ sở của một số nhị phân. Bằng cách khai thác một số loại đường cú pháp và quá tải toán tử, ".'1b',"#:là cách ngắn nhất để biến danh sách các ký tự thành 36 số cơ sở. Chà, về mặt kỹ thuật, căn cứ 32, nhưng J nghĩ nó đơn nhất, vậy ai đang đếm?

Cách sử dụng là dưới đây. Lưu ý rằng các chuỗi là mảng ký tự trong J, vì vậy một danh sách ba mục 'A','B','C'có thể được viết 'ABC'tắt. Ngoài ra, booleans là 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

Con trăn, số 68 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))

Gọi với v:

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

Tất cả mọi thứ dưới đây là từ phiên bản chưa được chỉnh sửa trước đây của tôi bao gồm các chức năng vẽ hữu ích. Hãy sử dụng nó như một điểm nhảy ra.

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

Gọi validđể chạy nó:

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

Ngay bây giờ mã được thiết lập để kiểm tra tính hợp lệ của B E Gvà in ra các mặt kết quả:

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

Chạy nó trên B G Echúng ta có thể thấy rằng G không chính xác:

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, làm tốt lắm +1 cho drawAll và tính đầy đủ của câu trả lời. +1 để sử dụng thuật toán ngắn như vậy. <3 nó
xem

@xem Cảm ơn! Cuối cùng tôi đã đánh golf nó. Mặc dù tôi không thể tìm ra cách để bz2 giải nén các ký tự unicode.
Sở thích của Calvin

+1. Câu trả lời tốt đẹp. Hy vọng nhiều người sẽ nâng cao các sân golf bao gồm các sân golf nhỏ hơn, như thế này, vì nó thực sự cần nỗ lực.
Vectorized

1
g=[[0 for j in s]for i in s]có thể rút ngắn thành g=map(list,[[0]*5]*5). Ngoài ra, bạn có thể tránh các khối thụt lề nếu chúng là một câu lệnh : if c[e]:g[e[a]][e[a-2]]=1.
Bakuriu

@Bakuriu và bitpwner, cảm ơn vì những gợi ý và chỉnh sửa :)
Sở thích của Calvin

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

Giải pháp chơi gôn này cần một thư viện bên ngoài, gọn gàng, khá phổ biến vì vậy tôi nghĩ sử dụng nó là tốt.

Chuỗi unicode nằm trong 41 ký tự, trong khi điều tương tự trong câu trả lời prolog của @ fabian là 44.

Điều thú vị nhất ở đây là việc lập chỉ mục của mảng numpy. Trong a[ix], ixcó thể là một mảng boolean với hình dạng tương tự như a. Nó giống như nói a[i, j, k] where ix[i, j, k] == True.

Phiên bản Ungolfed

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

Tập lệnh nén bảng

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.