그리드 기반 디지털 로직 (Duodyadic Tiles)


33

십자형 타일은 사각형의 종류입니다 두 개의 입력을 갖는 기능 블록으로 , 하나는 상단에서 하나는 왼쪽에서 하나는 오른쪽에 하나는 아래쪽에 하나의 출력이 있습니다. 각 출력은 두 입력의 개별 기능입니다.

예를 들어, #일반 타일을 나타내고, 우측 출력은 R함수 f의 입력은 TL, 상기 저부의 출력은 B다른 함수 gTL:

 T
L#R         R = f(T, L)
 B          B = g(T, L)

(두 개의 함수가 있기 때문에 타일을 "duo"라고하고 두 함수 가 두 개의 인수를 갖기 때문에 "dyadic"이라고합니다. 합니다.)

그런 다음 타일을 그리드에 함께 구성 할 수 있습니다. 한 타일의 출력은 인접한 타일의 입력으로 직접 이동합니다. 예를 들어, 왼쪽의 오른쪽 출력은 오른쪽 #의 왼쪽 입력으로갑니다 #.

 AB         D = f(f(A, C), B)
C##D        E = g(A, C)
 EF         F = g(f(A, C), B)

특정 기능을 가진 두 개의 이중 체 타일 세트가 주어지면 복잡하고 잠재적으로 유용한 구성을 만들 수 있다고 상상할 수 있습니다.

이 과제 에서는 모든 입력 및 출력이 단일 비트 이진수 (0 또는 1) 인 기존의 10 가지 논리 기반 십이 음표 타일 에만 관심이 있습니다. 각 타일 유형을 나타 내기 위해 별도의 ASCII 문자를 사용합니다.

타일 ​​문자 및 해당 입력 / 출력 관계는 다음과 같습니다.
( T상단 입력, L왼쪽 입력, R오른쪽 출력, B하단 출력)

  1. 0 : 0또는 (공백) → R = 0,B = 0
  2. 하나 : 1R = 1,B = 1
  3. 십자가 : +R = L,B = T
  4. 거울 : \R = T,B = L
  5. 상단 만 : UR = T,B = T
  6. 왼쪽 만 : )R = L,B = L
  7. 아님 : !R = not L,B = not T
  8. 그리고 : &R = L and T,B = L and T
  9. 또는 : |R = L or T,B = L or T
  10. Xor : ^R = L xor T,B = L xor T

도전

0 1+\U)!&|^10 가지 논리 기반 십이 음표 타일을 사용하여 만든 "회로"를 나타내는 문자의 사각형 격자를 취하는 프로그램 또는 함수를 작성하십시오 . 또한 두 개의 문자열에 걸릴 필요가 0의와 1의; 하나는 왼쪽 입력 열이고 다른 하나는 상단 입력 행입니다. 프로그램 / 기능은 하단 출력 행과 오른쪽 출력 열을 인쇄 / 반환해야합니다 ( 01 의).

예를 들어이 그리드에서

+++
+++

모든 입력은 그리드를 가로 질러 출력으로 똑바로 흐릅니다.

 ABC
D+++D
E+++E
 ABC

그래서의 입력 010/가 01출력했을 010/ 01:

 010
0+++0
1+++1
 010

프로그램의 정확한 결과는 다음 [bottom output row]\n[right output column][bottom output row]/[right output column]같습니다.

010
01

또는

010/01

함수를 작성한 경우 두 문자열을 튜플 또는 목록으로 반환하거나 여전히 인쇄 할 수 있습니다.

세부

  • 명령 행, 텍스트 파일, sdtin, 함수 arg와 같이 합리적인 방식으로 세 개의 입력을 문자열로 사용하십시오 (주문 그리드, 맨 위 행, 왼쪽 열).
  • 입력 행과 열 길이가 그리드 치수와 일치하고 0의 및1 .
  • 격자는 올바른 문자 ( 0 1+\U)!&|^)를 사용해야합니다 . 그 기억 0같은 일을 의미한다.

테스트 사례

(I / O를 top/ leftbottom/ 로 읽습니다 right.)

낸드 :

&!

00/ 001/ 1
00/ 101/ 1
10/ 001/ 1
10/ 111/0

모든 것 :

1111
1\+\
1+\+
1\+\

모든 입력은 1111/ 가되어야합니다 1111.

Nand에서 Xor : (후행 공백 열 참고)

\)+\ 
U&!& 
+! ! 
\&!& 
   ! 

00000/ 0000000000/ 00000
00000/ 1000000010/ 00000
10000/ 0000000010/ 00000
10000/ 1000000000/00000

지그재그 :

+++\00000000
000\!!!!\000
00000000\+++

왼쪽 입력의 첫 번째 비트는 오른쪽 출력의 마지막 비트가됩니다. 다른 모든 것입니다 0.

000000000000/ 000000000000000/ 000
000000000000/ 100000000000000/001

번식:

)))
UUU
U+U
U+U
UUU

왼쪽 입력의 첫 번째 비트는 모든 출력으로갑니다.

000/ 00000000/ 00000
000/ 10000111/11111

모든 1 × 1 그리드 테스트 사례의 pastebin이 있습니다.

채점

바이트 단위 의 최단 제출 이깁니다.

보너스 : 어떤 멋진 "회로"를 만들 수 있습니까?

추신 : 인터넷 검색 "이중 체 타일"을 귀찮게하지 마십시오. 나는 어제 그것들을 만들었습니다 .D
이 아이디어를 본격적인 프로그래밍 언어로 확장하는 것에 대해 논의하고 싶다면 이 대화방으로 오십시오 .


11
멋진 도전을 위해 +1하지만 또한 정말 멋진 2 인용 타일 을 발명 했기 때문 입니다.
Alex A.

3
+1 goo.gl/zuqfdW 와 같이 구글을 만드는 것은 정말 쓸모가 없습니다 . 좋은 도전!
BrainSteel

나는 그들과 함께 있습니다. 나는이 골프 도전보다 프로그래밍 언어로 타일에 훨씬 더 관심이 있습니다. 추신 : 16 개의 가능한 타일이 있으므로 다른 6 개의 글자 / 이름이 나오면 깔끔합니다.
Sparr

다른 방향에서 출력 / 입력되는 블록을 갖는 것이 흥미로울 것입니다. 그렇지 않으면 모든 것이 오른쪽 아래 방향으로 흐르기 때문에 래치를 만들 수 없기 때문입니다.
Sp3000

2
Rubik 's Cube 표기법과 유사한 방식으로 F / B를 가질 수 있도록 T / B를 U (p) / D (자체)로 변경할 수 있습니다. . . 삼면 체 큐브?
Soham Chowdhury

답변:


8

피스, 122

괴물의 종류. 단순히 재귀를 사용하며 동적 프로그래밍과 같은 멋진 것은 없습니다.

D:NGHR@Cm+d[1HG&GH|GHxGH0),[GH!G)[HG!H)x"+\\!1U)&|^"N#aYw)M:@@YGH?hgGtHHv@eYG?egtGHGv@ePYHjkm+0egtleYklePYjkm+0hgbtlePYleY

온라인 데모 .

입력은 다음과 같은 방식으로 이루어집니다. 먼저 그리드 (이스케이프 없음, 추가 기호 없음)와 두 줄의 입력 (예 : 지그재그)

+++\00000000
000\!!!!\000
00000000\+++
000000000000
100

8

매쓰, 331 276 270 267 264 262 252 250 바이트

Print@@@{#[[2;;,-1,2]],#[[-1,2;;,1]]}&@MapIndexed[h=Characters;({r@#2,b@#2}=<|##|>&@@Thread[h@"0 1+\\)U!&|^"->{0,0,1,i={##},{#2,#},##,1-i,1##,Max@i,(#-#2)^2}]&[r[#2-{1,0}],b[#2-{0,1}]]@#{1,1})&,Join[h@{"0"<>#3},h@StringSplit[#2<>"
"<>#,"
"]],{2}]&

그만큼 매스 매 티카는 첨자로 사용하는 개인 사용 유니 코드 문자입니다 T즉, 그것은 이항 연산자입니다.

더 읽기 쉬운 버전은 다음과 같습니다.

Print @@@ {#[[2 ;;, -1, 2]], #[[-1, 2 ;;, 1]]} &@
  MapIndexed[h = Characters;
   (
     {r@#2, b@#2} = <|##|> & @@ Thread[
            h@"0 1+\\)U!&|^" -> {
              0,
              0,
              1,
              i = {##},
              {#2, #},
              ##,
              1 - i,
              1 ##,
              Max@i,
              (# - #2)^2
              }] & [
          r[#2 - {1, 0}],
          b[#2 - {0, 1}]
          ] @ # {1, 1}
     ) &,
   Join[
    h@{"0" <> #3},
    h@StringSplit[#2 <> "\n" <> #, "\n"]\[Transpose]
   ],
   {2}] &

이것은 그리드, 상단 및 왼쪽 입력에 대해 세 개의 문자열을 사용하여 하단 및 오른쪽 출력을 인쇄하는 명명되지 않은 함수입니다.

설명

이 단계를 단계별로 살펴 봅시다 (Mathematica 지식을 가정하지 않겠습니다). 코드를 앞뒤로 읽어야합니다. 기본 알고리즘은 각 기능을 계산하고 결과를 저장하는 라인을 스윕합니다.f 하고 후속 타일에서 액세스 할 수 있도록 .

입력 처리

이 비트입니다.

Join[
  h@{"0" <> #3},
  h@StringSplit[#2 <> "\n" <> #, "\n"]\[Transpose]
]

이것은 단순히 그리드를 중첩 된 문자 목록으로 나누고 ( 코드의 어딘가에 h대한 별칭으로 정의 Character했음) 입력과 함께 행과 열을 앞에 추가합니다. 이 작품은, 때문에 1하고 0그래서 실제로 수동으로 입력을 공급하는 것과 같은 효과가 있습니다에 그들을 가하고, 또한 일정한 기능 타일의 이름입니다. 이것들은 함수이기 때문에 기술적으로 그리드 외부에서 입력을받을 것이지만, 중요하지 않은 일정한 함수이기 때문입니다. 왼쪽 상단에 a가 표시 0되지만 해당 타일의 결과가 사용되지 않으므로 상당히 임의적입니다.

또한 전치에 유의하십시오. 열을 추가하면 행을 추가하는 것보다 많은 문자가 필요하므로 맨 위 행을 추가 한 후 그리드를 바꿉니다. 이것은 프로그램의 주요 부분에 대해 위 / 아래와 왼쪽 / 오른쪽이 바뀌 었음을 의미하지만, 완전히 교환 가능하므로 중요하지 않습니다. 결과를 올바른 순서로 반환해야합니다.

그리드 해결

(이 섹션은 약간 구식입니다. 골프를 마쳤다고 확신하면 수정됩니다.)

다음 MapIndexed으로이 중첩 목록의 내부 수준을 살펴 봅니다. 그리드의 각 문자에 대한 첫 번째 인수로 제공된 익명 함수를 호출합니다. 또한 현재 두 개의 좌표로 그것을 목록을 제공합니다. 그리드는 순서대로 순회되므로 이전 셀을 기반으로 각 셀을 안전하게 계산할 수 있습니다.

변수 r(ight) 및 b(ottom)을 각 셀의 결과에 대한 조회 테이블로 사용합니다. 익명 함수에는에 현재 좌표가 #2있으므로 다음을 사용하여 모든 셀에 입력을 얻습니다.

r[#2 - {1, 0}],
b[#2 - {0, 1}]

첫 번째 행과 열에서 정의되지 않은 값에 액세스 r하고b . Mathematica는 실제로 그것에 문제가 없으며 대신 좌표를 돌려 줄 것입니다. 그러나 행 / 열의 모든 타일은 상수 함수이므로 어쨌든이 결과를 무시합니다.

이제 이건 :

<|##|> & @@ Thread[
  h@"0 1+\\U)!&|^" -> {
     z = {0, 0}, z, o = 1 + z, {##}, ...
  }] &

골프 형태입니다

<|"0" -> (z = {0, 0}), " " -> z, "1" -> (o = 1 + z), "+" -> {##}, ... |> &

두 개의 타일 입력이 주어지면이 두 입력에 대해 가능한 모든 타일 결과를 포함하는 연관 (해시 맵 또는 다른 언어로 된 테이블이라고 함)을 반환하는 함수입니다. 모든 함수가 어떻게 구현되는지 이해하려면 이러한 함수의 첫 번째 인수에 액세스 할 수 있고 #두 번째는에 액세스 할 수 있음을 알아야합니다 #2. 또한 ##인수를 "표시"하는 데 사용할 수있는 두 인수의 순서를 제공합니다.

  • 0: 간단합니다. 상수를 반환하고 나중에 사용할 {0, 0}z있도록 할당 합니다 (예 : 공간 타일).
  • 1:은 본질적으로 {1,1}이지만 z이것을 갖는 것이 단축됩니다 1+z. 우리는 또한 이것을 저장합니다o 두 출력이 동일한 모든 타일에 유용하기 때문에이를 합니다.
  • +: 여기서는 시퀀스를 사용합니다. {##}는 동일 {#,#2}하고 두 입력을 변경하지 않고 통과시킵니다.
  • \: 우리는 두 가지 논쟁을 바꾼다. {#2,#} .
  • U: 이제 우리는 사용할 수 있습니다 o. o#2방법{1,1}*#2 우리는 단지 두 출력에 최고 인수를 넣어 있도록.
  • ): 왼쪽 주장과 비슷합니다. o# .
  • !: Mathematica에서 비트 단위는 성가신 것이 아니지만, 오직 0and 만 가지고 있기 때문에 1간단히 두 입력을 빼고 1(반전시켜) 전달할 수 있습니다.1-{##} .
  • &: 이것은 꽤 깔끔합니다. 처음에 우리는 그 비트를 발견하고 대한 01곱셈과 동일합니다. 또한 o##동일하다o*#*#2 .
  • |: 다시, 우리는 동등한 기능을 사용합니다. 비트 단위 또는이 경우와 동일 Max하므로 Max입력 인수에 적용 하고 결과에를 곱합니다 {1,1}.
  • ^: xor에서 찾은 가장 짧은 것은 차이를 취하여 제곱하는 것입니다 (양성을 보장하기 위해) o(#-#2)^2.

이 기능이 완료 반환 우리는 우리가 관심있는 요소를 빼고에 저장하기 위해 현재 셀의 문자를 사용하여 전체 연결 후 rb. 이것은 또한 사용 된 익명 함수의 반환 값입니다.MapIndexed 이므로 매핑은 실제로 모든 결과의 그리드를 제공합니다.

출력 처리

MapIndexed3D 그리드를 반환합니다. 첫 번째 차원은 가로 격자 좌표에 해당하고 (이전 조옮김 기억) 두 번째 차원은 세로 격자 좌표에 해당하고 세 번째 차원은 아래쪽 또는 왼쪽 출력이 있는지 여부를 나타냅니다. 여기에는 제거해야 할 입력 행과 열도 포함되어 있습니다. 따라서 하단 행의 하단 출력에 액세스합니다.

#[[2;;,-1,2]]

마지막 열의 올바른 결과는

#[[-1,2;;,1]]

참고 2;; 마지막 요소에 두 번째의 범위이다.

마지막으로, 우리 는 두 번째 수준의 구문 설탕으로 Print사용하는 두 가지 모두에 적용 합니다. 이 인수는 모든 인수를 연속적으로 인쇄합니다 (두 개의 개별 표현식에 적용되므로 하단과 하단 사이에 줄 바꿈이 있음) 올바른 출력).@@@Apply


8

C, 332 309 272 270 266 259 247 225 바이트

#define C(x)*c-x?
i,k,T,L,m;f(c,t,l)char*c,*t,*l;{while(L=l[i]){for(k=0;T=t[k];c++)L=C(49)C(43)C(92)C(85)C(41)C(33)C(38)C('|')C(94)T=48:(T^=L-48):(T|=L):(T&=L):(T^=1,L^1):(T=L):T:(m=T,T=L,m):L:(T=49),t[k++]=T;c++;l[i++]=L;}}

온라인 결과를 여기에서 확인하십시오!

이 함수 void f(char*, char*, char*)는 보드를 첫 번째 입력, 맨 위 입력 행, 왼쪽 입력 행으로 사용해야 하는 함수를 정의합니다 .

테스트에 사용한 내용은 다음과 같습니다.

#include "stdio.h"
int main() {
    char buf[1024],top[33],left[33];
    /* Copy and paste an example circuit as the first input,
       and put a 'Q' immediately after it. 
       Note that the Q is never touched by the function f, and is used
       solely as a delimiter for input. */
    scanf("%[^Q]Q ",buf);
    /* Then enter your top inputs */
    scanf("%[01]%*[^01]", top);
    /* Then your left ones */
    scanf("%[01]", left);
    /* OUTPUT: Bottom\nRight */
    f(buf, top, left);
    return 0;
}

따라서 Sp3000의 2 비트 승수를 입력하여 다음을 수행하십시오.

UUUU))))
UU++)))&
UUU+)  U
UU++&))U
U++&+)^U
U)&\&)UU
   U+^UU
   \&UUUQ
11110000
00000000

우리는 얻는다 :

00001001
11111111

Sp3000의 반가산기를 염두에두고 전체 가산기를보고 싶습니다. 여러분 중 한 명이 해냈습니다! 시스템 자체가 프로그래밍 언어라고 생각하지는 않지만 매우 흥미 롭습니다. 그러나 이것은 metagolf의 훌륭한 목표처럼 보입니다!

간단한 설명 :

해결되지 않은 주석이 달린 코드는 다음과 같습니다.

/* We define the first half of the ?: conditional operator because, well,
   it appears over and over again. */
#define C(x)*c-x?
/* i,k are counting variables
   T,L are *current* top and left inputs */
i,k,T,L,m;
f(c,t,l)char*c,*t,*l;{
    /* The outer loop iterates from top to bottom over l and c */
    while(L=l[i]){
        /* Inner loop iterates from left to right over t and c */
        for(k=0;T=t[k];c++)
            /* This line looks awful, but it's just a bunch of character
            comparisons, and sets T and L to the output of the current c */
            L=C(49)C(43)C(92)C(85)C(41)C(33)C(38)C('|')C(94)T=48:(T^=L-48):(T|=L):(T&=L):(T^=1,L^1):(T=L):T:(m=T,T=L,m):L:(T=49),
            /* Write our output to our input, it will be used for the next row */
            t[k++]=T;
        c++; /*Absorbs the newline at the end of every row */
        /* Keep track of our right-most outputs, 
        and store them in the handy string passed to the function. */
        l[i++]=L;
    }
    /* Bottom output is now stored entirely in t, as is right output in l */        
}

우리는 c왼쪽에서 오른쪽으로 (위에서 아래로) 반복하고 t매번 입력을 다시 작성하고 가장 오른쪽에있는 출력을 l문자열에 밀어 넣습니다 . 우리는 상위 행의 교체로이 상상할 수 c1 의와0 '반복적 S 및 오른쪽에서 압출되는 비트의 트랙 유지.

보다 시각적 인 순서는 다음과 같습니다.

 111                                  
1&+^  =>  110 ->0  =>     ->0  =>     0 Thus, "01" has been written to l,
1+&+     1+&+         110 ->1         1
                                  110   And "110" is stored currently in t.

이것은 분명히 다른 기호와 크기로 더 복잡해 지지만 중심 아이디어는 유지됩니다. 이것은 데이터가 절대로 흐르거나 남지 않기 때문에 작동합니다.


골프를위한 많은 잠재력! 의 헤더 변경하여 시작 f에를 f(c,t,l)char*c,*t,*l(반환 형식에 대한 상관 없어).
FUZxxl

@FUZxxl 누군가가 채팅에서 이것을 언급했지만 작동시키지 못했습니다. 이 동작이 표준입니까? LLVM은 해당 라인에 2 개 이상의 오류를 발생시킵니다.
BrainSteel

죄송합니다. 이어야했다 f(c,t,l)char*c,*t,*l;. C11 모드에서 컴파일하지 마십시오. 반환 유형을 삭제할 수있는 암시 적 int 규칙이 해당 개정에서 삭제 되었기 때문입니다.
FUZxxl 5

@FUZxxl C99에서도 실패한 것 같습니다. 실제로 컴파일러를 설정 한 모든 모드는 해당 코드를 거부했습니다.
BrainSteel

바로 뒤에 세미콜론을 추가 했습니까 *l? 내 컴퓨터에서 C99 모드로 컴파일됩니다.
FUZxxl

7

파이썬 2, 316 바이트

이 함수는 10 개의 타일 람다 함수를 작성한 다음 그리드를 통해 반복하여 논리 상태를 업데이트합니다. 그런 다음 최종 수직 및 수평 로직 상태가 인쇄됩니다.

def b(d,j,g):
 h=enumerate;e=dict((s[0],eval('lambda T,L:('+s[1:]+')'))for s in' 0,0#00,0#11,1#+L,T#\\T,L#UT,T#)L,L#!1-L,1-T#&T&L,T&L#|T|L,T|L#^T^L,T^L'.split('#'));j=list(j+'\n');g=list(g)
 for y,k in h(d.split('\n')):
  L=g[y]
  for x,c in h(k):T=j[x];L,B=e[c](int(T),int(L));j[x]=`B`
  g[y]=`L`
 print''.join(j+g)

테스트를 포함한 ungolfed 코드 :

def logic(grid, top, left):
    loop = enumerate;
    func = dict((s[0], eval('lambda T,L:('+s[1:]+')')) for s in ' 0,0#00,0#11,1#+L,T#\\T,L#UT,T#)L,L#!1-L,1-T#&T&L,T&L#|T|L,T|L#^T^L,T^L'.split('#'));
    top = list(top+'\n');
    left = list(left)
    for y,row in loop(grid.split('\n')):
        L = left[y]
        for x,cell in loop(row) :
            T = top[x];
            L, B = func[cell](int(T), int(L));
            top[x] = `B`
        left[y] = `L`
    print ''.join(top + left)

import re
testset = open('test.txt', 'rt').read().strip()
for test in testset.split('\n\n'):
    if test.endswith(':'):
        print '------------------\n'+test
    elif re.match('^[01/\n]+$', test, re.S):
        for run in test.split():
            top, left = run.split('/')
            print 'test', top, left
            logic(grid, top, left)
    else:
        grid = test

test.txt(SP3000에 의해이 개 다른 테스트 포함) 파일 :

Nand:

&!

00/0
00/1
10/0
10/1

All ones:

1111
1\+\
1+\+
1\+\

1001/1100

Xor from Nand (note the column of trailing spaces):

\)+\ 
U&!& 
+! ! 
\&!& 
   ! 

00000/00000
00000/10000
10000/00000
10000/10000

Half adder:

+))
U&+
U+^

000/000
000/100
100/000
100/100

Right shift:

\\\
\++
\++

001/110
010/101
101/100

테스트 출력 :

------------------
Nand:
test 00 0
01
1
test 00 1
01
1
test 10 0
01
1
test 10 1
11
0
------------------
All ones:
test 1001 1100
1111
1111
------------------
Xor from Nand (note the column of trailing spaces):
test 00000 00000
00000
00000
test 00000 10000
00010
00000
test 10000 00000
00010
00000
test 10000 10000
00000
00000
------------------
Half adder:
test 000 000
000
000
test 000 100
001
101
test 100 000
101
001
test 100 100
110
110
------------------
Right shift:
test 001 110
000
111
test 010 101
101
010
test 101 100
010
110

7

파이썬 2, 384 338 325 바이트

def f(G,T,L):
 def g(x,y):
  if x>-1<y:l=g(x-1,y)[1];t=g(x,y-1)[0];r=l,t,1-l,0,0,1,t,l,l&t,l|t,l^t;i="+\\!0 1U)&|^".index(G[y*-~W+x]);return((t,l,1-t)+r[3:])[i],r[i]
  return(int((y<0)*T[x]or L[y]),)*2
 H=G.count("\n")+1;W=len(G)/H;return eval('"".join(map(str,[g(%s]for _ in range(%s)])),'*2%('_,H-1)[0','W','W-1,_)[1','H'))

진지하게 CH, 이것이 장난감이 아니라면 장난감 공장을 울려 야합니다.

더 골프를 치고 효율성은 떨어지지 만 여전히 CarpetPython을 따라 잡지 못했습니다. 같은 입력f("1111\n1\\+\\\n1+\\+\n1\\+\\","0101","1010") , 출력은 두 문자열의 튜플입니다. 하지만 보드에 줄 바꿈이 없어야합니다.

테스트 프로그램

def f(G,T,L):
 def g(x,y):
  if x>-1<y:l=g(x-1,y)[1];t=g(x,y-1)[0];r=l,t,1-l,0,0,1,t,l,l&t,l|t,l^t;i="+\\!0 1U)&|^".index(G[y*-~W+x]);return((t,l,1-t)+r[3:])[i],r[i]
  return(int((y<0)*T[x]or L[y]),)*2
 H=G.count("\n")+1;W=len(G)/H;return eval('"".join(map(str,[g(%s]for _ in range(%s)])),'*2%('_,H-1)[0','W','W-1,_)[1','H'))


import itertools

G = r"""
+))
U&+
U+^
""".strip("\n")

def test(T, L):
    print f(G, T, L)

def test_all():
    W = len(G[0])
    H = len(G)

    for T in itertools.product([0, 1], repeat=len(G.split("\n")[0])):
        T = "".join(map(str, T))

        for L in itertools.product([0, 1], repeat=len(G.split("\n"))):
            L = "".join(map(str, L))

            print "[T = %s; L = %s]" % (T, L)
            test(T, L)
            print ""

test("000", "000")
test("000", "100")
test("100", "000")
test("100", "100")

가능한 모든 사례를 테스트 할 수도 있습니다. test_all() .

추가 테스트 사례

반가산기

여기 왼쪽 상단 비트를 추가하여 다음을 출력하는 반가산기가 있습니다 <input bit> <carry> <sum>.

+))
U&+
U+^

테스트 :

000 / 000  ->  000 / 000
000 / 100  ->  001 / 101
100 / 000  ->  101 / 001
100 / 100  ->  110 / 110

입력의 두 번째 / 세 번째 비트가 변경 되더라도 출력은 동일해야합니다.

오른쪽 교대

주어진 abc / def결과는 fab / cde다음과 같습니다.

\\\
\++
\++

테스트 :

001 / 110 -> 000 / 111
010 / 101 -> 101 / 010
101 / 100 -> 010 / 110

3 비트 분류기

top의 처음 3 비트를 bottom의 마지막 3 비트로 정렬합니다. 올바른 결과물은 정크입니다.

UUU)))
UU)U U
U&UU U
U+|&)U
\UU++|
 \)&UU
  \+|U
   UUU

테스트 :

000000 / 00000000 -> 000000 / 00000000
001000 / 00000000 -> 000001 / 11111111
010000 / 00000000 -> 000001 / 00001111
011000 / 00000000 -> 000011 / 11111111
100000 / 00000000 -> 000001 / 00001111
101000 / 00000000 -> 000011 / 11111111
110000 / 00000000 -> 000011 / 00001111
111000 / 00000000 -> 000111 / 11111111

2 비트 x 2 비트 승수

첫 번째 / 2 비트의 최상위를 첫 번째 숫자로 사용하고 3 번째 / 4 비트의 최상위를 두 번째 숫자로 사용합니다. 맨 아래의 마지막 4 비트로 출력합니다. 올바른 결과물은 정크입니다.

UUUU))))
UU++)))&
UUU+)  U
UU++&))U
U++&+)^U
U)&\&)UU
   U+^UU
   \&UUU

편집 : 열과 두 행을 골라냅니다.

테스트 :

00000000 / 00000000 -> 00000000 / 00000000
00010000 / 00000000 -> 00000000 / 10000000
00100000 / 00000000 -> 00000000 / 00000000
00110000 / 00000000 -> 00000000 / 10000000
01000000 / 00000000 -> 00000000 / 00000000
01010000 / 00000000 -> 00000001 / 11111111
01100000 / 00000000 -> 00000010 / 00000000
01110000 / 00000000 -> 00000011 / 11111111
10000000 / 00000000 -> 00000000 / 00000000
10010000 / 00000000 -> 00000010 / 10000000
10100000 / 00000000 -> 00000100 / 00000000
10110000 / 00000000 -> 00000110 / 10000000
11000000 / 00000000 -> 00000000 / 00000000
11010000 / 00000000 -> 00000011 / 11111111
11100000 / 00000000 -> 00000110 / 00000000
11110000 / 00000000 -> 00001001 / 11111111

1

R, 524 517

아마도 이것을 줄일 수있는 충분한 공간이 있지만 이것은 정말 흥미 롭습니다. 두 가지 기능이 있습니다. 함수 d는 워커이고 f는 비교 자입니다.

함수 d는 3 개의 문자열, Gates, Top 및 Left로 호출됩니다. 게이트는 너비에 따라 결정된 매트릭스에 배치됩니다.

I=strtoi;S=strsplit;m=matrix;f=function(L,T,G){O=I(c(0,1,L,T,!L,!T,L&T,L|T,xor(L,T)));X=which(S(' 01+\\U)!&|^','')[[1]]==G);M=m(c(1,1,1,2,1,1,3,2,2,4,3,4,5,4,3,6,4,4,7,3,3,8,5,6,9,7,7,10,8,8,11,9,9),nrow=3);return(c(O[M[2,X]],O[M[3,X]]))};d=function(G,U,L){W=nchar(U);H=nchar(L);U=c(list(I(S(U,'')[[1]])),rep(NA,H));L=c(list(I(S(L,'')[[1]])),rep(NA,W));G=m((S(G,'')[[1]]),nrow=W);for(i in 1:H)for(n in 1:W){X=f(L[[n]][i],U[[i]][n],G[n,i]);L[[n+1]][i]=X[1];U[[i+1]][n]=X[2]};cat(U[[H+1]],' / ',L[[W+1]],sep='',fill=T)}

조금 포맷

I=strtoi;S=strsplit;m=matrix;
f=function(L,T,G){
    O=I(c(0,1,L,T,!L,!T,L&T,L|T,xor(L,T)));
    X=which(S(' 01+\\U)!&|^','')[[1]]==G);
    M=m(c(1,1,1,2,1,1,3,2,2,4,3,4,5,4,3,6,4,4,7,3,3,8,5,6,9,7,7,10,8,8,11,9,9),nrow=3);
    return(c(O[M[2,X]],O[M[3,X]]))
};
d=function(G,U,L){
    W=nchar(U);H=nchar(L);
    U=c(list(I(S(U,'')[[1]])),rep(NA,H));
    L=c(list(I(S(L,'')[[1]])),rep(NA,W));
    G=m((S(G,'')[[1]]),nrow=W);
    for(i in 1:H)
        for(n in 1:W){
            X=f(L[[n]][i],U[[i]][n],G[n,i]);
            L[[n+1]][i]=X[1];
            U[[i+1]][n]=X[2]
        };
    cat(U[[H+1]],' / ',L[[W+1]],sep='',fill=T)
}

일부 테스트

> d('&!','00','0')
01 / 1
> d('&!','00','1')
01 / 1
> d('&!','10','0')
01 / 1
> d('&!','10','1')
11 / 0
> d('\\)+\\ U&!& +! ! \\&!&    ! ','00000','00000')
00000 / 00000
> d('\\)+\\ U&!& +! ! \\&!&    ! ','00000','10000')
00010 / 00000
> d('\\)+\\ U&!& +! ! \\&!&    ! ','10000','00000')
00010 / 00000
> d('\\)+\\ U&!& +! ! \\&!&    ! ','10000','10000')
00000 / 00000
> d('+++\\00000000000\\!!!!\\00000000000\\+++','000000000000','100')
000000000000 / 001
> d('+++\\00000000000\\!!!!\\00000000000\\+++','000000000000','000')
000000000000 / 000
> d('+))U&+U+^','000','000')
000 / 000
> d('+))U&+U+^','000','100')
001 / 101
> d('+))U&+U+^','100','000')
101 / 001
> d('+))U&+U+^','100','100')
110 / 110
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.