세 글자가“Godel-Escher-Bach 큐브”를 형성 할 수 있는지 확인


29

이 질문은 "Godel, Escher, Bach"책의 표지에서 영감을 얻었습니다.

여기서 과제는 주어진 3 개의 문자가 3면에서 읽을 수있는 3D 조각을 생성 할 수 있는지 알려주는 함수를 작성하는 것입니다.

이 연습에서는 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

조각은 다음 순서로 세 글자로 구성됩니다.

  • 위에 편지 하나,
  • 왼쪽의 편지 2
  • 오른쪽의 편지 3
  • 문자 1의 하단은 문자 2의 상단에 바인딩됩니다.

예:

함수는 3 개의 대문자 (3 개의 문자 또는 1 개의 문자로 된 3 개의 문자열)를 입력으로 받아들이고 해당 조각이 존재할 수 있는지 알려주는 부울 (true / false 또는 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)

NB : 조각에 "비행 픽셀"(아무것도 붙어 있지 않은 큐브 또는 큐브 그룹)이 포함되어 있어도 true를 반환 할 수 있습니다.

표준 허점이 적용됩니다.

보다 정확하게는 세 글자 이외의 외부 입력을 사용할 수 없으며 소스 코드에서 17576 가능한 답변을 하드 코딩 할 수 없습니다

어떤 언어로든 가장 짧은 문자가 이깁니다!

재미있게 보내세요 :)



그렇다, 그것은 내가 책을 발견하게하는 것은 MU 퍼즐이고, 나는이 도전을 생각하게하는 책의 표지이다. 문제가 있습니까? 이것이 18 홀의 일부입니까?
xem

2
홀 1을 교체하는 것이 좋은 옵션이었을 것입니다.;) ... 문제가 발생하더라도 더 빨리 일어나지 않는 것이 제 잘못입니다. 정말 괜찮은 도전입니다, +1!
마틴 엔더

외부 파일에서 글자 모양을 정의하는 데이터를 검색 할 수 있습니까, 아니면 소스에도 포함시켜야합니까?
CesiumLifeJacket

바이너리 B는 1이 아니라 왼쪽 상단에 0이 있습니다.
Calvin 's Hobbies

답변:


13

매스 매 티카 423

"블로킹 작동 방식"이라는 섹션을 추가했습니다.

언 골프

(* 알파벳의 이진 데이터는에 단일 문자열로 저장됩니다 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 렌더링 방법을 보여줍니다. 그림의 상단 행은 마치 보는 사람이 입방체에서 무한한 거리에있는 것처럼 직교 원근법을 취합니다. 아래 줄은 블록이 어떻게 보이는지 보여줍니다. 3D 도형을 수동으로 회전하여 개별 단위 큐브가있는 위치를 정확하게 검사 할 수 있습니다.

문자 "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]

빌다


차단은 어떻게 작동합니까?

이것이 분명 해지면 실례하지만, 일부 사람들은 글자가 서로 어떻게 간섭하는지 시각화하여 3D 픽셀을 취소하려고 할 것입니다.

BGE 큐브 렌더링에서 문자 G에 발생하는 사항을 따르십시오.

아래 복셀 (3D 픽셀 또는 단위 큐브)에 특별한주의를 기울일 것 입니다. BGE 큐브에서 사라지는 픽셀입니다. 비트 배열 및 해당 배열 플롯의 행 4, 열 5에 해당하는 픽셀입니다.

차단 1


xy 평면에서 픽셀은 포인트 (5,2)의 회색 디스크에 해당합니다. 그러나 우리는 3D로 작업 할 것이기 때문에 샤프트 의 5 개 위치 를 (5,1,2)에서 (5,5,2)로 고려해야합니다. 이러한 픽셀 중 하나라도 문자 B와 E로 조각 된 후에도 벽의 3D 투영에서 관심있는 픽셀을 볼 수 있습니다.

차단 2


솔리드 블록에서 픽셀을 제거하면 문자가 방해를받습니다. 왼쪽에서 검은 색 화살표는 오른쪽 아래의 비트에 해당하는 픽셀에서 조각을 나타냅니다. 문자 B의 값은 0입니다. 조각하면 픽셀 바로 위와 아래의 픽셀과 함께 (5,1,2)의 픽셀이 제거됩니다. 4 개의 픽셀이 남아 있습니다.

차단 3

그러나 오른쪽 창에서 알 수 있듯이 문자 E는 나머지 관심 픽셀 인 (5,2,2) (5,3,2), (5,4,2) 및 (5,5,2)를 조각합니다. (이는 문자 E가 열 2에서 열 5까지 네 번째 행에서 0과 동일한 비트를 갖기 때문입니다.) 결과적으로 지점에서 음영을 보장하는 데 필요한 픽셀 중에 단일 픽셀이 남아 있지 않습니다 (5 , 2) 먼 벽에 (문자 G). 대신, 글자 G의 구멍에 해당하는 밝은 점이 있습니다! 큐브 BGE는 G를 잘못 렌더링하기 때문에 좋지 않습니다.

골프 423 자

이 기능 은 Ungolfed 코드에서 h와 동일한 역할을 수행했습니다 validQ. 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}}]

와우, 그 3D 뷰는 매우 깔끔합니다! 마지막 코드 블록이 "UnGolfed"입니까? 나에게 골프를 쳤다. :)
xem

당신이 올바른지. 마지막 블록은 골프입니다. 제목을 수정했습니다. 3D 뷰의 멋진 점 중 하나는 대화식이라는 점입니다. 마우스로 회전 및 확대 / 축소를 수행 할 수 있습니다.
DavidC

BTW, 내 계산에 따르면 15600 개의 가능한 순열 중 564 개의 유효한 큐브가 있습니다.
DavidC

좋은 정보입니다. 계산하는 데 시간이 얼마나 걸렸습니까? 또한 15600이 아닌 26 * 26 * 26 = 17576입니다. 아니면 뭔가 빠졌습니까?
xem

튜플이 아닌 순열을 사용했습니다. 즉, 반복되는 글자가 없습니다. 26 * 25 * 24 = 15600. 564 건을 찾는 데 21 초가 걸렸습니다.
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.

Prolog1 차 논리로 문제를 표현하기 쉽기 때문에 좋은 선택 인 것 같습니다. 또한 Prolog이런 종류의 문제를 해결하기위한 강력한 기능을 제공합니다.

그러나 코드가 골프화되어 있기 때문에 설명을 추가해야한다고 생각합니다.

가벼운 골프 버전

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

주사위의 각 측면에있는 픽셀에 해당하는 좌표는 3D 좌표계로 쉽게 변환 될 수 있습니다. I 사용 T, LR상부 (1)의 경우, (2) 및 우측 (3) 측을 떠났다. u그리고 v이미지의 좌표를 위해 사용된다 :

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

각 활성 (예 : 검은 색) 픽셀의 결과는이 측면에서 물체의 모양을 변경하지 않고 활성화 할 수있는 "3D 픽셀"세트로 결합됩니다. 각면에 대한 세트의 교차점은 모두 3D 픽셀이며, 픽셀을 추가하지 않고도 활성화 할 수 있으며,보기를 방해 할 수 있습니다 (즉, 적어도 한쪽에서 보면 픽셀이 없어야 함).

교차점에 픽셀이 있으면 필요한 부분을 확인하는 것이 남아 있습니다.

이것은 프로그램의 술어로 이어집니다.

  • f : 최종 점검을 수행합니다. 상단, 왼쪽 및 오른쪽에 글자를 가져옵니다
  • u , vw : 검사를 수행합니다. 측면에서 활성화 된 모든 픽셀에 대해 교차점에 3D 픽셀이 있으면보기를 차단합니다.
  • h : 교차점에 픽셀이 있는지 확인
  • t , l , r : 3D 픽셀을 위, 왼쪽 및 오른쪽에서 차단할 수 있는지 확인합니다.
  • c : 문자 이미지의 픽셀을 확인합니다. 거기에있는 문자열은 조금 이상하게 보일 수 있지만 이미지 데이터를 저장하는 간단한 방법 일뿐입니다. 단순히 다음 값 (16 진 표기법)을 갖는 문자 시퀀스입니다.

    [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 픽셀 세트로 변환

공식

공식

공식

안전하게 추가 할 수있는 픽셀 (잘못된 위치에서보기를 방해하지 않고)

공식

막아야 할 픽셀을 안전하게 막을 수 있는지를 확인합니다.

공식

공식

공식

각 측면에 대한 수표 조합

공식


1
전 어 .. 뭐? 나는 이것을 이해할 수 없다고 생각한다. (+1)
seequ

이런 ... 난 자러 갈거야 ...
BrunoJ

인상적! 이 답변에 감사드립니다
xem

1
좋은. btw, 나는 프로세스가 단단한 입방 블록으로 시작한다고 생각합니다. (이전에는 없었던 픽셀을 추가하는 것으로 생각합니다.) 각 문자는 해당 블록에서 일부 3D 픽셀을 제거합니다. 따라서 이웃 문자가 문자 "보관하려는"픽셀을 제거 할 때 간섭이 발생합니다. 간섭은 추가 픽셀이 아니라 "누락 된 픽셀"에서 비롯됩니다.
DavidC

9

J - 223 197 191 CHAR

세 문자 목록을 인수로 취하는 함수입니다.

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

이 골프는 rank 라는 J의 강력한 기능에 크게 의존 하여 거의 무료로 "조각"과 "감시면"작업을 수행 할 수 있습니다. 그것을 조금 단순화하기 위해 rank는 명사 또는 동사의 자연스러운 논증의 차원을 나타냅니다.

J에는 다차원 배열이 있으며 3D 배열은 단일 3D 배열 또는 행렬 목록, 벡터의 2D 배열 또는 스칼라의 3D 배열로 해석 될 수 있습니다. 따라서 J의 모든 연산은 응용 프로그램이 wrt를 통해 전파되는 방법을 제어 할 수 있습니다. 순위 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

이항 함수 (두 개의 인수)를 도입하면 매우 강력 해집니다. 왜냐하면 두 인수의 형태 (순위를 고려한 후)의 모양이 합리적이라면 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가 자연스럽게 문자를 세울 때 얼굴의 일부 트리플이 올바른 방향과 상대 위치에 있도록합니다. 가장 짧은 해결책은 모든 문자 양식을 시계 반대 방향으로 1/4 바퀴 돌리는 것입니다. 앞뒤 축을 나타내는 J의 3 차원을 고려할 때 아래의 조잡한 다이어그램은이 체계가 작동하는 이유를 보여줍니다.

큐브 시각화 그림 A : J가 조각하는 큐브의 세면. 그림 B : 질문과 같이 문자의 방향이있는 3면.

이 인코딩 선택은 이전 방법보다 12자를 절약하고 모든 것을 깔끔하게 만듭니다. 실제 골프는 밖으로 큐브 생성 "1"2인해 관련이없는 최적화 일부 펑키 논리에 새겨 놓을.

그런 다음 얼굴을 확인해야합니다. 우리는 1과 0으로 블록을 인코딩하기 때문에, 우리는 단지 우리가 원하는 방식으로 (이가있는 각 축을 따라 요약 할 수 있습니다 +/"1, +/"2+/비트), 부울 (적응 0<°), 다음 원래 90 모든 직접 비교 - 넘겨진 편지.

압축 체계는 각 문자의 각 5px 행을 이진 숫자의 기본 32 표현으로 인코딩합니다. 다수의 구문 설탕과 연산자 오버로드를 활용함으로써 ".'1b',"#:문자 목록을 기본 36 숫자로 바꾸는 가장 짧은 방법입니다. 글쎄, 기술적으로는 32 자이지만 J는 단항하다고 생각합니다. 누가 세고 있습니까?

사용법은 다음과 같습니다. 문자열은 J의 문자 배열이므로 3 개의 항목 목록 을 짧게 'A','B','C'작성할 수 있습니다 'ABC'. 또한 부울은 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

파이썬, 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

와, 잘 했어! drawAll과 답의 완전성을 위해 +1. 이러한 짧은 알고리즘을 사용하는 경우 +1 <3 it
xem

@xem 감사합니다! 나는 마침내 골프를 쳤다. bz2가 유니 코드 문자를 압축 해제하는 방법을 알 수는 없지만.
Calvin 's Hobbies

+1. 좋은 대답입니다. 더 많은 사람들이 이처럼 작은 골프로 구성된 골프를 찬성하기를 바랍니다.
벡터화

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

@Bakuriu와 bitpwner, 제안과 편집에 감사드립니다 :)
Calvin 's Hobbies

1

파이썬 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])

이 골프 솔루션에는 외부 라이브러리 인 numpy가 필요합니다.이 라이브러리는 꽤 인기가 있으므로 사용하는 것이 좋습니다.

유니 코드 문자열은 41 자이며 @fabian의 프롤로그 답변과 동일한 것은 44입니다.

여기서 가장 흥미로운 것은 numpy 배열의 색인 생성입니다. 이어 a[ix], ix동일한 형상을 갖는 부울 배열 될 수있다 a. 말하는 것과 같습니다 a[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.