ตรวจสอบว่าตัวอักษรสามตัวสามารถสร้าง "ลูกบาศก์ Godel-Escher-Bach"


29

คำถามนี้ได้รับแรงบันดาลใจจากปกหนังสือ "Godel, Escher, Bach":

ความท้าทายที่นี่คือการเขียนฟังก์ชั่นที่บอกว่าตัวอักษรที่กำหนดสามตัวสามารถสร้างรูปปั้น 3 มิติที่สามารถอ่านได้จากสามด้าน

สำหรับแบบฝึกหัดนี้ตัวอักษรเดียวที่คุณสามารถใช้ได้คือบิตแมป 26 5px * 5px:

หรือเป็นเลขฐานสอง (A ถึง 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

รูปปั้นประกอบด้วยสามตัวอักษรตามลำดับต่อไปนี้:

  • จดหมายฉบับหนึ่งอยู่ด้านบน
  • ตัวอักษรสองทางซ้าย
  • ตัวอักษรสามทางด้านขวา
  • ด้านล่างของตัวอักษรหนึ่งถูกผูกไว้กับด้านบนของตัวอักษรสอง

ตัวอย่าง:

ฟังก์ชั่นของคุณอาจยอมรับว่าเป็นตัวอักษรตัวพิมพ์ใหญ่สามตัว (สามตัวอักษรหรือสามสายอักขระหนึ่งตัว) และส่งออกบูลีน (จริง / เท็จหรือ 0/1) เพื่อบอกว่ารูปปั้นที่เกี่ยวข้องนั้นมีอยู่จริงหรือไม่

ตัวอย่าง:

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)

หมายเหตุ: คุณอาจจะกลับมาจริงแม้ว่ารูปปั้นจะมี "พิกเซลบิน" (ก้อนหรือกลุ่มของก้อนที่ติดอยู่กับอะไร)

ช่องโหว่มาตรฐานใช้

แม่นยำยิ่งขึ้นคุณไม่สามารถใช้อินพุตภายนอกนอกเหนือจากตัวอักษรสามตัวและคุณไม่สามารถ hardcode คำตอบที่เป็นไปได้ 17576 ในซอร์สโค้ดของคุณ

คำตอบที่สั้นที่สุดในตัวละครในภาษาใด ๆ ชนะ!

มีความสุข :)



ใช่มันเป็นปริศนา MU ที่ทำให้ฉันค้นพบหนังสือและมันเป็นปกหนังสือที่ทำให้ฉันคิดถึงความท้าทายนี้ มีปัญหาอะไรไหม? นี่เป็นส่วนหนึ่งของ 18 หลุมของคุณหรือเปล่า
xem

2
มันจะเป็นตัวเลือกที่ดีในการแทนที่รู 1;) ... ไม่เป็นไรถ้ามีสิ่งใดที่เป็นความผิดของฉันที่จะไม่ทำให้บางสิ่งบางอย่างเร็วขึ้น มันเป็นความท้าทายที่ดีมาก +1!
Martin Ender

เราสามารถดึงข้อมูลที่กำหนดรูปร่างของตัวอักษรจากไฟล์ภายนอกหรือจำเป็นต้องรวมอยู่ในแหล่งข้อมูลด้วยหรือไม่?
CesiumLifeJacket

เลขฐานสอง B ของคุณมี 0 ที่มุมบนซ้ายไม่ใช่ 1
งานอดิเรกของ Calvin

คำตอบ:


13

Mathematica 423

ฉันเพิ่มส่วนที่เรียกว่า "วิธีการปิดกั้นการทำงาน"

Ungolfed

(* ข้อมูลไบนารีของตัวอักษรจะถูกเก็บไว้เป็นสตริงเดียวในs. varsนำเข้าและแปลงเป็นอาร์เรย์.)

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]

ตัวอย่าง

คิวบ์{"B", "G", "E"}ใช้งานได้หรือไม่ (เช่นตัวอักษรสามตัวจะฉายบนผนังได้อย่างถูกต้องหรือไม่)

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

เท็จ

ภาพประกอบ

รูปด้านล่างแสดงการแสดงผล BGE แถวด้านบนของตัวเลขใช้มุมมองแบบมุมฉากราวกับว่าผู้ชมอยู่ในตำแหน่งที่ไม่มีระยะห่างจากคิวบ์ แถวด้านล่างแสดงให้เห็นว่าจะมีลักษณะอย่างไรบล็อกจากระยะใกล้ ตัวเลข 3 มิติสามารถหมุนได้ด้วยตนเองเพื่อตรวจสอบอย่างแม่นยำในตำแหน่งที่ลูกบาศก์ของแต่ละยูนิต

ปัญหาเกิดขึ้นกับตัวอักษร "G" ไม่มีอะไรที่เชื่อมต่อ serif กับส่วนที่เหลือของจดหมาย

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

bge


อย่างไรก็ตาม BEG ควรทำงานได้ดี

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

จริง

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

beg


การปิดกั้นทำงานอย่างไร

โปรดขอโทษด้วยถ้าสิ่งนี้เห็นได้ชัด แต่บางทีคนบางคนอาจต้องการเห็นภาพว่าตัวอักษรรบกวนกันอย่างไรโดยยกเลิกพิกเซล 3 มิติของพวกเขา

ลองติดตามสิ่งที่เกิดขึ้นกับตัวอักษร G ในการเรนเดอร์คิวบ์ BGE

เราจะให้ความสนใจเป็นพิเศษกับvoxel (พิกเซล 3D หรือหน่วยลูกบาศก์) ด้านล่าง นั่นคือพิกเซลที่หายไปในคิวบ์ BGE เป็นพิกเซลที่สอดคล้องกับแถว 4 คอลัมน์ 5 ในบิตอาร์เรย์และในพล็อตอาร์เรย์ที่สอดคล้องกัน

blocking 1


ในระนาบ xy พิกเซลจะสอดคล้องกับดิสก์สีเทาที่จุด (5,2) แต่เนื่องจากเรากำลังจะทำงานในแบบ 3 มิติเราต้องพิจารณา 5 ตำแหน่งในเพลาจาก (5,1,2) ถึง (5,5,2) หากพิกเซลตัวใดตัวหนึ่งอยู่รอดได้โดยการแกะสลักตัวอักษร B และ E เราจะสามารถเห็นพิกเซลที่น่าสนใจในการฉายภาพ 3 มิติบนผนัง

blocking 2


ตัวอักษรรบกวนเมื่อพิกเซลถูกลบออกจากบล็อกทึบ ทางซ้ายลูกศรสีดำแสดงถึงการแกะสลักจากพิกเซลซึ่งสอดคล้องกับบิตที่มุมขวาล่าง มันมีค่า 0 สำหรับตัวอักษร B การแกะสลักเอาพิกเซลออกที่ (5,1,2) พร้อมกับพวกที่อยู่ด้านบนและด้านล่างโดยตรง สี่พิกเซลจะยังคงอยู่

blocking 3

แต่เมื่อบานหน้าต่างด้านขวาแสดงให้เห็นตัวอักษร E จะกำหนดจำนวนพิกเซลที่น่าสนใจ (5,2,2) (5,3,2), (5,4,2) และ (5,5,2) (นี่เป็นเพราะความจริงที่ว่าตัวอักษร E มีบิตเท่ากับ 0 ในแถวที่สี่จากคอลัมน์ที่ 2 ถึงคอลัมน์ที่ 5) ดังนั้นจึงไม่มีพิกเซลเดียวเหลืออยู่ในกลุ่มที่จำเป็นเพื่อให้แน่ใจว่ามีจุดสี (5 2) บนผนังไกล (สำหรับตัวอักษร G) แต่จะมีจุดสว่างที่สอดคล้องกับรูในตัวอักษร G! คิวบ์ BGE ไม่ดีเพราะทำให้ G ไม่ถูกต้อง

Golfed 423 ตัวอักษร

ฟังก์ชั่นนี้hทำหน้าที่เหมือนกันกับvalidQในรหัส unGolfed ฟังก์ชั่นการเรนเดอperspectiveร์ไม่รวมอยู่ด้วยเนื่องจากไม่ได้มีส่วนร่วมและไม่จำเป็นต้องใช้สำหรับการท้าทาย

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

ว้าวมุมมอง 3 มิติเหล่านั้นดูเรียบร้อยมาก! คุณแน่ใจหรือว่าการบล็อกรหัสสุดท้ายคือ "UnGolfed" ดูเหมือนว่าฉันจะเล่นกอล์ฟ :)
xem

คุณถูก. บล็อกสุดท้ายคือกอล์ฟ ฉันแก้ไขหัวข้อ สิ่งหนึ่งที่ยอดเยี่ยมเกี่ยวกับมุมมอง 3 มิติคือการโต้ตอบ: การหมุนและการซูมสามารถทำได้โดยใช้เมาส์
DavidC

BTW โดยการนับของฉันมี 564 ก้อนที่ถูกต้องในการเปลี่ยนลำดับที่เป็นไปได้ 15,600
DavidC

นั่นเป็นข้อมูลที่ดี ใช้เวลาในการคำนวณนานแค่ไหน เช่นกัน 26 * 26 * 26 = 17576 ไม่ใช่ 15600 หรือฉันทำบางอย่างขาดหายไป
xem

ฉันใช้วิธีเรียงสับเปลี่ยนไม่ใช่สิ่งอันดับ เช่นไม่มีตัวอักษรซ้ำแล้วซ้ำอีก 26 * 25 * 24 = 15600 ใช้เวลา 21 วินาทีในการค้นหาผู้ป่วย 564 ราย
DavidC

12

อารัมภบท, 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.

โปรแกรมนี้มีชื่อว่า:

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

Prologดูเหมือนจะเป็นทางเลือกที่ดีเนื่องจากเป็นเรื่องง่ายที่จะเป็นตัวแทนของปัญหาในตรรกะลำดับแรก ยังPrologมีฟังก์ชั่นการทำงานที่มีประสิทธิภาพสำหรับการแก้ปัญหาแบบนี้

อย่างไรก็ตามเนื่องจากรหัสนี้เล่นกอล์ฟฉันเดาว่าฉันควรเพิ่มคำอธิบาย

รุ่น golfed อย่างอ่อนโยน

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

พิกัดที่สอดคล้องกับพิกเซลในแต่ละด้านของลูกเต๋าสามารถแปลงเป็นระบบพิกัดสามมิติได้อย่างง่ายดาย ผมใช้T, LและRด้านบน (1), ซ้าย (2) และขวา (3) ด้าน uและvใช้สำหรับพิกัดในภาพ:

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

ผลลัพธ์สำหรับแต่ละพิกเซลที่ใช้งาน (เช่นสีดำ) จะถูกรวมเข้ากับชุดของ "3D-pixels" ที่สามารถนำมาใช้โดยไม่ต้องเปลี่ยนรูปลักษณ์ของวัตถุจากด้านนี้ จุดตัดของชุดสำหรับแต่ละด้านคือ 3D-pixels ทั้งหมดที่สามารถเปิดใช้งานได้โดยไม่ต้องเพิ่มพิกเซลที่จะขัดขวางมุมมอง (เช่นมองจากด้านหนึ่งอย่างน้อยจะมีพิกเซลที่ไม่ควรมี)

สิ่งที่เหลืออยู่คือการตรวจสอบแต่ละด้านถ้ามีพิกเซลในสี่แยกที่บล็อกมุมมองในกรณีที่จำเป็น

สิ่งนี้นำไปสู่เพรดิเคตในโปรแกรม:

  • f : ตรวจสอบขั้นสุดท้ายหรือไม่ ใช้ตัวอักษรที่ด้านบนด้านซ้ายและด้านขวา
  • u , vและw : ทำการตรวจสอบถ้าทุกพิกเซลที่ใช้งานอยู่ด้านข้างมี 3D-pixel ในจุดตัดที่บล็อกมุมมอง
  • h : ตรวจสอบการมีอยู่ของพิกเซลในสี่แยก
  • t , l , r : ตรวจสอบว่าสามารถปิดกั้น 3D-pixel จากด้านบนด้านซ้ายและด้านขวา
  • c : ตรวจสอบพิกเซลในภาพของตัวอักษร สายอักขระที่อยู่ในนั้นอาจดูแปลกไปหน่อย แต่มันเป็นวิธีกะทัดรัดในการจัดเก็บข้อมูลภาพ มันเป็นเพียงลำดับของตัวละครที่มีค่าดังต่อไปนี้ (โน้ตหกเหลี่ยม):

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

    อักขระแต่ละตัวเหล่านี้จัดเก็บข้อมูลสำหรับ 3 พิกเซลแถวในภาพตัวอักษร (= 15 พิกเซล) พิกเซลยังได้รับการจัดเรียงใหม่เพื่อให้ข้อมูลถูกจัดเก็บไว้ในที่เดียวและไม่แบ่งเป็นหลายแถวเช่นข้อมูลของ OP

สูตรทางคณิตศาสตร์

สูตร

ป้อนข้อมูล

สูตร

การแปลงจากพิกเซลในตัวอักษรหนึ่งตัวไปเป็นชุดของ 3D-pixels ที่ขัดขวางมุมมองของพิกเซลนี้

สูตร

สูตร

สูตร

พิกเซลที่สามารถเพิ่มได้อย่างปลอดภัย (โดยไม่กีดขวางการมองในที่ผิด)

สูตร

ตรวจสอบแต่ละด้านว่าพิกเซลที่ต้องมีสิ่งกีดขวางสามารถกีดขวางได้อย่างปลอดภัย

สูตร

สูตร

สูตร

รวมการตรวจสอบของแต่ละด้าน

สูตร


1
ฉัน .. เอ่อ .. อะไรนะ? ฉันพบสิ่งที่เข้าใจยาก (+1)
seequ

บริสุทธิ์ ... ฉันจะไปนอน ...
BrunoJ

ที่น่าประทับใจ! ขอบคุณสำหรับคำตอบนี้
xem

1
ดี btw ฉันคิดว่ากระบวนการเริ่มต้นจากบล็อกลูกบาศก์ทึบ (คุณคิดว่ามันเป็นการเพิ่มพิกเซลที่ไม่เคยมีมาก่อน) ตัวอักษรแต่ละตัวจะลบพิกเซล 3D บางส่วนออกจากบล็อกนั้น การแทรกสอดเกิดขึ้นเมื่อตัวอักษรที่อยู่ใกล้เคียงลบพิกเซลที่ตัวอักษร "ต้องการเก็บไว้" สัญญาณรบกวนเกิดจาก "พิกเซลที่หายไป" แทนที่จะเป็นพิกเซลเพิ่มเติม
DavidC

9

J - 223 197 191 ถ่าน

ฟังก์ชั่นการใช้รายการถ่านสามตัวเป็นอาร์กิวเมนต์

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

กอล์ฟนี้ต้องอาศัยคุณสมบัติที่ทรงพลังของ J เรียกว่าอันดับซึ่งให้การ "แกะสลักออก" และ "ดูด้านข้าง" ให้กับเราฟรี ในการทำให้มันมากไปหน่อยอันดับหมายถึงมิติของคำนามหรือการโต้แย้งตามธรรมชาติของคำกริยา

J มีอาร์เรย์หลายมิติและเป็นที่ชัดเจนว่าพูดว่าอาร์เรย์สามมิติสามารถตีความได้ว่าเป็นอาร์เรย์สามมิติเดี่ยวหรือเป็นรายการของเมทริกซ์หรืออาร์เรย์ของเวกเตอร์สองมิติหรือสเกลาร์สามมิติ ดังนั้นการดำเนินการทุกอย่างใน J สามารถควบคุมแอปพลิเคชันของมันได้ว่าจะกระจายไปอย่างไร อันดับ 0 หมายถึงนำไปใช้กับสเกลาร์, อันดับ 1 หมายถึงนำไปใช้กับเวกเตอร์และอื่น ๆ

   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

สิ่งนี้จะมีประสิทธิภาพมากเมื่อคุณแนะนำฟังก์ชั่น dyadic (สองข้อโต้แย้ง) เพราะถ้ารูปร่างของสองข้อโต้แย้ง (หลังจากการจัดอันดับ) เป็นที่ยอมรับ J จะทำการวนซ้ำโดยปริยาย:

   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

เมื่อรูปร่างทั้งหมดของคุณเป็นที่ยอมรับและคุณสามารถระบุอันดับของตัวเองได้มีหลายวิธีในการรวมอาร์กิวเมนต์ ที่นี่เราแสดงวิธีการบางอย่างที่คุณสามารถคูณเมทริกซ์ 2D และอาร์เรย์ 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|
+---------+---------+--------------+--------------+--------------+

คุณจะสังเกตเห็นว่าสิ่งนี้ไม่ได้แกะสลักตัวอักษรในทิศทางที่คำถามถาม แต่มันเขียนไว้ในนั้นว่าสะดวกสำหรับลอจิกอันดับ ถ้าเราไม่ย้อนกลับหรือหมุนตัวอักษรก่อนที่เราจะนำไปใช้มันจะไม่ทำงาน แต่การแก้ไขสิ่งต่าง ๆ เช่นนั้นจะใช้ตัวละครที่มีค่าดังนั้นเราจะเข้ารหัสตัวอักษรเช่นนั้นเมื่อ J ใส่ใจพวกเขาโดยธรรมชาติใบหน้าที่สามบางอันจะอยู่ในทิศทางที่ถูกต้องและตำแหน่งที่สัมพันธ์กัน มันกลับกลายเป็นว่าวิธีแก้ปัญหาที่สั้นที่สุดคือหมุนรูปแบบตัวอักษรทุกรอบเป็นทวนเข็มนาฬิกา เมื่อพิจารณามิติที่สามของ J เพื่อเป็นตัวแทนของแกนหน้าไปหลังแผนภาพด้านล่างแสดงเหตุผลว่าทำไมโครงการนี้ถึงใช้งานได้

การสร้างภาพของก้อน รูปที่: สามด้านของลูกบาศก์ที่ J สนใจเข้าไป รูปที่ B: ทั้งสามด้านซึ่งมีตัวอักษรที่เน้นเหมือนคำถามที่ถาม

ตัวเลือกในการเข้ารหัสนี้ช่วยประหยัด 12 ตัวอักษรในวิธีการก่อนหน้านี้ กอล์ฟที่แท้จริงสร้างคิวบ์ออกมา"1และ"2แกะสลักด้วยตรรกะที่ขี้ขลาดบางอย่างเนื่องจากการเพิ่มประสิทธิภาพที่ไม่เกี่ยวข้อง

จากนั้นเราต้องตรวจสอบใบหน้า เนื่องจากเราเข้ารหัสบล็อกเป็น 1 และ 0 เราก็สามารถรวมไปตามแต่ละแกนในทางที่เราต้องการ (เหล่านี้เป็น+/"1, +/"2และ+/บิต), ปรับให้เข้ากับบูลีน ( 0<) แล้วเปรียบเทียบพวกเขาทั้งหมดได้โดยตรงไปที่เดิม 90 ° - หันตัวอักษร

รูปแบบการบีบอัดจะเข้ารหัสแต่ละแถว 5px ของตัวอักษรแต่ละตัวเป็นฐาน 32 แสดงถึงเลขฐานสอง โดยการใช้ประโยชน์จากจำนวนน้ำตาลที่ให้มาทาง syntactic และการใช้งานเกินพิกัด".'1b',"#:เป็นวิธีที่สั้นที่สุดในการเปลี่ยนรายการของตัวละครให้เป็นตัวเลขฐาน 36 ในทางเทคนิคแล้วเบส 32 แต่เจคิดว่ามันไม่น่าสนใจดังนั้นใครจะนับ?

การใช้งานอยู่ด้านล่าง โปรดทราบว่าสตริงเป็นอาร์เรย์อักขระใน J ดังนั้น'A','B','C'สามารถเขียนรายการสามรายการ'ABC'ให้สั้นได้ นอกจากนี้ booleans ก็ 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))

โทรด้วยv:

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

ทุกอย่างด้านล่างมาจากเวอร์ชั่นที่ไม่ได้อัปโหลดก่อนหน้าของฉันซึ่งมีฟังก์ชั่นการวาด อย่าลังเลที่จะใช้มันเป็นจุดกระโดด

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

โทรvalidเพื่อเรียกใช้:

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

ขณะนี้รหัสได้รับการตั้งค่าเพื่อทดสอบความถูกต้องของB E Gและพิมพ์ใบหน้าผลลัพธ์:

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

ทำงานบนB G Eเราจะเห็นว่า G ไม่ถูกต้อง:

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

ว้าวทำได้ดีมาก! +1 สำหรับ drawAll และความสมบูรณ์ของคำตอบ +1 สำหรับการใช้อัลกอริทึมแบบสั้น <3
xem

@xem ขอบคุณ! ในที่สุดฉันก็เล่นกอล์ฟ แม้ว่าฉันไม่สามารถหาวิธีรับ bz2 เพื่อขยายอักขระ unicode
งานอดิเรกของ Calvin

+1 คำตอบที่ดี หวังว่าผู้คนจำนวนมากจะยกระดับสนามกอล์ฟที่ประกอบด้วยสนามกอล์ฟขนาดเล็กเช่นนี้เพราะมันต้องใช้ความพยายาม
Vectorized

1
g=[[0 for j in s]for i in s]g=map(list,[[0]*5]*5)สามารถลงไป if c[e]:g[e[a]][e[a-2]]=1นอกจากนี้คุณสามารถหลีกเลี่ยงการเยื้องบล็อกหากพวกเขาเป็นคำเดียว:
บากูริว

@ Bakuriu และ bitpwner ขอบคุณสำหรับคำแนะนำและการแก้ไข :)
Calvin's Hobbies

1

Python 3 + จำนวน, 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])

โซลูชันกอล์ฟนี้ต้องใช้ห้องสมุดภายนอกซึ่งค่อนข้างเป็นที่นิยมดังนั้นฉันคิดว่ามันใช้ได้ดี

สตริง Unicode อยู่ใน 41 ตัวอักษรในขณะที่สิ่งเดียวกันในคำตอบอารัมภบทของ fabian คือ 44

สิ่งที่น่าสนใจที่สุดคือการสร้างดัชนีของอาร์เรย์ที่มีค่า ในa[ix], สามารถเป็นอาร์เรย์แบบบูลที่มีรูปร่างเช่นเดียวกับix ก็เหมือนเป็นคำพูดaa[i, j, k] where ix[i, j, k] == True

เวอร์ชันที่ไม่ดี

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

สคริปต์เพื่อบีบอัดตาราง

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.