진리표가 주어지면 그것을 만족시키는 Stackylogic 프로그램을 출력하십시오.


17

Stackylogic은 이전 과제에서 작성한 프로그래밍 언어입니다 : Run Stackylogic . 자세한 내용과 예를 보려면 해당 게시물을 읽으십시오.

Stackylogic 소요 0의과 1입력의 단일 출력 0 또는 1시 완료.

프로그램은 문자 만 포함 하는 행과 한 행의 끝에 01?정확히 한 <행으로 구성됩니다. 라인은 비워 둘 수 없습니다 수 있으며, 함께 라인은 <적어도 하나 있어야합니다 0, 1또는 ?그 전에합니다.

다음 은 두 비트 의 NAND 를 계산하는 샘플 프로그램입니다 .

1
?<
11
?
0

프로그램의 모든 줄은 스택 으로 간주 되며 맨 아래는 왼쪽이고 맨 위는 오른쪽입니다. 암시 적으로, 프로그램의 첫 번째 줄 앞과 마지막 줄 뒤에 빈 스택 (예 : 빈 줄)이 있습니다.

<프로그램이 실행될 때, 커서라는 마크 스택에 시작합니다. 실행은 다음과 같이 진행됩니다.

  1. 커서가 현재 가리키는 스택에서 맨 위 문자를 팝하십시오.

    • 문자가 ?인 경우 사용자에게 a 0또는 a 1를 묻고 문자 인 것처럼 행동하십시오.
    • 문자가 0인 경우 커서를 한 스택 위로 움직입니다 (현재 줄 위의 줄로).
    • 문자가 1인 경우 커서를 한 스택 아래로 (현재 줄 아래의 줄로) 이동하십시오.
  2. 커서가 이동하는 스택이 비어 있으면 스택에서 마지막으로 튀어 나온 마지막 값 (항상 a 0또는 1)을 출력하고 프로그램을 종료하십시오.

  3. 그렇지 않으면, 커서가 이동하는 스택이 비어 있지 않으면 1 단계로 돌아가서 프로세스를 반복하십시오.

이 과제에 대해 알아야 할 핵심은 모든 Stackylogic 프로그램이 진리표 와 동일하다는 입니다. 미리 정해진 수의 부울 값이 입력되고 정확히 하나의 부울 값이 결정적으로 출력됩니다.

따라서 귀하의 임무는 만족하거나 시뮬레이션하는 Stackylogic 프로그램을 생성하는 것입니다. 즉, 주어진 진리표와 동일한 출력을 갖습니다. 그러나 Stackylogic이 진리표 시뮬레이트 할 있는지 확실하지 않으므로 유도에 의한 증거가 있습니다 .

기본 케이스

두 0 입력 진리표는 항상 출력 테이블입니다 01. 이 테이블의 Stackylogic 등가물은 0<하고 1< 각각.

유도 단계

Stackylogic이 N- 입력 진리표를 시뮬레이션 할 수 있다고 가정하십시오. M = N + 1이라고하자.

M 입력 테이블 T는 2 개의 N 입력 테이블 T 0 과 T 1 에 추가 입력 비트 B를 더한 값 으로 표현할 수 있습니다 . B가 0이면 T 0 의 결과 가 사용됩니다. B가 1이면 T 1 의 결과 가 사용됩니다.

예를 들어, 의사 코드에 해당하는 3 입력 진리표

if B:
    result = x OR y
else:
    result = x NAND y

이다

B x y | result
0 0 0 | 1
0 0 1 | 1
0 1 0 | 1
0 1 1 | 0
1 0 0 | 0
1 0 1 | 1
1 1 0 | 1
1 1 1 | 1

이것은 실제로 NAND와 OR에 대한 2 개의 2 입력 진리표이며, muxing 비트 B로 서로 쌓여 있습니다.

S 0 과 S 1을 각각 T 0 과 T 1 을 만족시키는 Stackylogic 프로그램이라고 하자 (첫 번째 가정에 따라 존재 함을 알고 있음). T를 만족시키는 프로그램 S는 다음과 같이 구성 될 수 있습니다.

[lines of S0 excluding the cursor, with 0 appended to all lines below the cursor]
?<
[lines of S1 excluding the cursor, with 1 appended to all lines above the cursor]

S 사이의 이러한 구성은 효과적으로 멀티플렉서 0 과 S 1 (행에서 제 1 입력 비트에 기초하여 ?<). 이 경우 0, 커서는 첨부 된 탈 것 0S의 원래 커서 위치까지에요 ' 0 다음 빈 스택으로 상단과 하단을 경계 할 것, 따라서 원래의 S 정확하게 동일한 실행 0 . 마찬가지로 1입력 된 경우 커서는 의 커서 위치 1를 S 1 의 커서 위치로 내려 가서 마치 마치 마치 마치 마치 실행합니다.

예를 들어 OR 및 NAND에 대한 Stackylogic 프로그램은 다음과 같습니다.

?
?<

1
?<
11
?
0

그들은 시뮬레이션을 위해 결합 될 수 있습니다

if B:
    result = x OR y
else:
    result = x NAND y

이렇게 :

1
?
110
?0
00
0
?<
?1
?

따라서 모든 진리표는 Stackylogic 프로그램으로 시뮬레이션 할 수 있습니다.

도전

테이블 의 출력을 2 진 오름차순으로 나타내는 2 개의 N 부울 값 목록 형식으로 N 입력 진리표 (N> 0)를 사용하는 프로그램 또는 함수를 작성하십시오 .

합리적인 입력 형식은 괜찮습니다. 예 : OR 진리표의 경우

x y | OR
0 0 | 0
0 1 | 1
1 0 | 1
1 1 | 1

이러한 입력 스타일 중 하나라도 괜찮을 것입니다.

0111

0, 1, 1, 1

0
1
1
1

[False, True, True, True]

진리표를 충족시키는, 즉 동일한 입력에 대해 정확히 동일한 출력을 갖는 Stackylogic 프로그램을 인쇄하거나 리턴하십시오. 해당 테이블을 충족시키는 모든 유한 프로그램은 유효한 출력입니다. 귀납적 증거의 구성 방법을 따를 필요는 없습니다. Stackylogic 프로그램은 최적으로 짧을 필요는 없습니다.

예를 들어 입력이 인 11100111경우 하나의 유효한 출력은

1
?
110
?0
00
0
?<
?1
?

그러나 다른 많은 것들이 있습니다.

바이트 단위의 가장 짧은 코드가 이깁니다.

통역사가 필요한 경우 원래 Stackylogic 문제를 참조하십시오 .


N을 두 번째 입력으로 취할 수 있습니까?
Leaky Nun

필요한 경우 @LeakyNun 예 (또는 2 ^ N)입니다.
Calvin 's Hobbies

답변:


8

Pyth, 53 바이트

L?tb,lehJyMc2bsX0.e.e+W>_Wk-Yhb0ZkebJ\?,0]`hbjXF+yQ\<

온라인으로 시도

이것은 Stackylogic에서 임의의 진리표를 구현하는 방법에 대한 도전에서 설명한 시스템의 정확한 구현입니다. 우리는 단순히 진리표를 반으로 자르고 그것을 재귀 적으로 구현 한 다음 적절하게 0과 1을 추가합니다.

이것은 반환 값이 재귀 함수를 정의하며 [1, ['0', '?', '1']], 첫 번째 숫자는 포인터의 위치이고 나머지는 스택 프로그램입니다.

L?tb,lehJyMc2bsX0.e.e+W>_Wk-Yhb0ZkebJ\?,0]`hbjXF+yQ\<
                                                         Q = eval(input())
L?tb,lehJyMc2bsX0.e.e+W>_Wk-Yhb0ZkebJ\?,0]`hb
L                                                 def y(b): return
 ?tb                                              if b[1:] (base case on false)
                                      ,0]`hb      else: [0, str([0])]
                                                  then:
           c2b                                    Cut the input in half
         yM                                       Map y over the halves
        J                                         Store that in J
    ,leh                                          The cursor position is the length 
                                                  of the body of the first function
                 .e                 J             enum-map, where k is the index
                                                  and b is the value, over J
                   .e             eb              enum-map, Y is the index and
                                                  Z is the value, over body of b
                     +W         Zk                Add to Z (line) k (the overall 
                                                  index, 0 or 1) conditional on
                          -Yhb                    Y (line index) - cursor
                       _Wk                        Negated if k
                      >       0                   > 0
               X0                    \?           Add '?' to the first element
              s                                   Concatenate, giving the body

jXF+yQ\<
    yQ      Call the above on the input
   +  \<    Append a '<'
 XF         Splat the 3 element list into the 'append-at' function,
            adding the curson in the right place
j           Join on newlines and print.

글쎄 ... 방금 해결책을 찾기 위해 집으로 돌아갔습니다 ...
찾기

3

파이썬 3 352 208 205 바이트

이것은 여전히 ​​풀리지 않으며 나중에 설명을 추가하려고합니다. 일부 수정 후, 나는 제거 관리 (144) 147 바이트를.

f=lambda x,l=len,r=range:'\n'.join(*x)if l(x)<2 else f([[x[i][j]+['0',''][j<=l(x[i])//2]for j in r(l(x[i]))]+[['?','?<'][l(x)<3]]+[x[i+1][j]+['1',''][j>=l(x[i])//2]for j in r(l(x[i]))]for i in r(0,l(x),2)])

f진리표 값을 형식의 부울 목록으로 입력 하는 함수 입니다 ['1','1','1','0','0','1'...]. 여기서 '1'진리적이고 '0'허위 인 경우 Stackylogic 프로그램을 리턴합니다.

Ideone에서 사용해보십시오

제작 된 프로그램을 테스트하려면 여기서 GamrCorps 의 Convex 인터프리터를 사용 하십시오 .

작동 원리

이것은 재귀 함수이며 질문에 설명 된 유도 방법을 사용합니다.

인덱스가없는 재귀 수준 에서이 a함수 는 목록 n/2 a+1의 입력 프로그램에서 입력 입력 Stackylogic 프로그램을 만듭니다 n a. 이것은 목록에서 두 개의 프로그램의 모든 인접한 쌍을 결합하여 수행됩니다.? ; 커서는 항상 각 구성 프로그램의 중간 요소에 있기 때문에 필요한 추가 0또는 1결합 할 프로그램의 각 행을 반복하고 현재 행의 색인이 크거나 같거나 큰 경우 추가하여 수행 할 수 있습니다 중간 인덱스 이상 목록에 두 개의 프로그램 만 포함 된 경우 다음 재귀 호출은 최종 프로그램을 제공합니다. 커서가 필요하기 때문에 대신에 조인이 발생합니다 ?<.

리스트가 length 1인 경우리스트는 전체 프로그램을 포함하는 하나의 요소 만 포함해야합니다. 따라서 프로그램의 모든 행이 개행으로 결합 된 후 리턴됩니다.

예는 이것을 설명하는 데 도움이됩니다.

Take the input ['1', '1', '1', '0', '0', '1', '1', '1'].

Level  Return value

0  [['1', '?', '1'], ['1', '?', '0'], ['0', '?', '1'], ['1', '?', '1']]
1  [['1', '?', '10', '?', '11', '?', '0'], ['0', '?', '10', '?', '11', '?', '1']]
2  [['1', '?', '10', '?', '110', '?0', '00', '?<', '01', '?1', '101', '?', '11', '?', '1']]
3  '1\n?\n10\n?\n110\n?0\n00\n?<\n01\n?1\n101\n?\n11\n?\n1'

which when printed gives:

1
?
10
?
110
?0
00
?<
01
?1
101
?
11
?
1
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.