문제

  • READ FROM IN.1 THROUGH IN.4
  • WRITE THE INPUT NUMBER WHEN THE VALUE GOES FROM 0 TO 1
  • TWO INTERRUPTS WILL NEVER CHANGE IN THE SAME INPUT CYCLE
  • IN.1 부터 IN.4 까지의 값을 읽는다.
  • 입력값이 0에서 1로 바뀔 때, 해당 입력값의 번호를 출력한다.
  • 하나의 입력 사이클에 인터럽트는 하나 뿐이다.

image

예제에 대한 설명

IN.1 IN.2 IN.3 IN.4 OUT OUT 값에 대한 설명
0 0 0 0 0  
0 0 0 0 0  
0 0 0 1 4 IN.4 가 1로 바뀜
0 0 1 1 3 IN.3 이 1 로 바뀜
0 0 1 1 0  
0 0 0 1 0  
1 0 0 1 1 IN.1 이 1로 바뀜
1 0 1 1 3 IN.3 이 1로 바뀜

풀이 1

  • 319 CYCLES / 6 NODES / 33 INSTR

6개의 노드, 33개의 INSTR을 사용하는 방법이다.

image

아이디어는 이렇다.

  • IN.1, IN.2, IN.3, IN.4 입력을 받는 노드는 입력값이 1이라면 자신의 식별값으로 1, 2, 3, 4를 각각 전달한다.
  • 이렇게 전달된 값들의 총합을 구해, 노드 하나에 SAV 해둔다.
  • 입력 사이클 하나에서 변경되는 값은 1개 뿐이므로, 이전에 SAV한 값과 현재의 총합과의 차이를 구하면 된다.
    • 결과가 양수라면 그대로 출력한다.
    • 결과가 음수라면 0을 출력한다.
IN.1 IN.2 IN.3 IN.4 SUM OUT OUT 값에 대한 설명
0 0 0 0 0 0  
0 0 0 0 0 0  
0 0 0 1 4 4 4 - 0 = 4
0 0 1 1 7 3 7 - 4 = 3
0 0 1 1 7 0 7 - 7 = 0
0 0 0 1 4 0 7 - 4 = -3 이므로 OUT은 0
1 0 0 1 5 1 5 - 4 = 1
1 0 1 1 8 3 8 - 5 = 3

save/33762.2.txt

@0
MOV UP, RIGHT

@1
^:MOV UP, ACC
JGZ ON          # IN.2 값이 1 이면 goto ON

OFF:            # IN.2 값이 0 이면..
 MOV LEFT, RIGHT    # IN.1 값(0 또는 1)을 전달해준다
 JMP ^

ON:             # IN.2 값이 1 이면
 MOV 2, ACC     # ACC에 2를 저장한다
 ADD LEFT       # IN.1 값을 더하고 @2 노드로 전달한다
 MOV ACC, RIGHT

@2
^:
 MOV UP, ACC
 JGZ ON         # IN.3 값이 1 이면 goto ON

OFF:
 MOV 0 ,ACC     # IN.3 값이 0 이면 ACC에 0을 저장한다
 JMP $

ON:             # IN.3 값이 1 이면..
 MOV 3, ACC     # ACC에 3을 저장한다

$:
 ADD LEFT
 ADD RIGHT      # IN.1 + IN.2 + IN.3 + IN.4
 MOV ACC, DOWN  # SUM 값을 @6 으로 전달한다

@3
^:MOV UP ,ACC
JGZ ON

OFF:            # IN.4 값이 0 이면..
 MOV 0, LEFT    # @2 노드에 0 을 전달한다
 JMP ^

ON:             # IN.4 값이 1 이면..
 MOV 4, LEFT    # @2 노드에 4 를 전달한다

@4


@5


@6
MOV UP, ACC

MOV ACC, DOWN   # 이전 값과 뺄셈하기 편하게 두 번 전달한다
MOV ACC, DOWN

@7


@8


@9
^:SWP   # 이전 SUM 값을 가져온다
SUB UP  # 이전 SUM 값에서 현재 입력 SUM 값을 뺀다
JLZ INC # 결과가 음수라면 SUM이 증가한 것이다 goto INC

DEC:            # SUM 이 그대로이거나 감소했다면
 MOV 0, DOWN    # 0에서 1로 변한 입력이 없는 것이다
 JMP $

INC:            # SUM 이 증가했다면
 NEG            # 음수를 양수로 바꾼다
 MOV ACC, DOWN  # 결과를 출력한다

$:
 MOV UP, ACC    # 현재 SUM을 다음 사이클에서 사용하기 위해 SAV 한다
 SAV

@10

풀이 2

  • 201 CYCLES / 9 NODES / 42 INSTR

약간 최적화한 버전이다. 각 입력값이 1이 들어오면 다음 사이클에서는 0 을 확정적으로 출력한다.

image

save/33762.1.txt

@0
OFF:
 MOV UP, ACC
 JGZ +          # IN1. 값이 1 이면 goto +
 MOV 0, DOWN    # 값이 0 이면 0 을 내려보낸다
 JMP OFF        # goto OFF

+:
 MOV 1, DOWN    # IN1. 값이 1 이면 1을 전달한다

ON:             # 1이면 그 다음 출력에서 0 -> 1 될 수 없다
 MOV UP, ACC    # 다음 입력값을 받는다
 MOV 0, DOWN    # 무조건 0 을 내려보낸다
 JGZ ON         # 입력값이 1 이었다면 goto ON

@1
OFF:
 MOV UP, ACC
 JGZ +
 MOV 0, DOWN
 JMP OFF

+:
 MOV 2, DOWN

ON:
 MOV UP, ACC
 MOV 0, DOWN
 JGZ ON

@2
OFF:
 MOV UP, ACC
 JGZ +
 MOV 0, DOWN
 JMP OFF

+:
 MOV 3, DOWN

ON:
 MOV UP, ACC
 MOV 0, DOWN
 JGZ ON

@3
OFF:
 MOV UP, ACC
 JGZ +
 MOV 0, DOWN
 JMP OFF

+:
 MOV 4, DOWN

ON:
 MOV UP, ACC
 MOV 0, DOWN
 JGZ ON

@4
MOV UP, RIGHT

@5
MOV UP, ACC
ADD LEFT
MOV ACC, RIGHT

@6
MOV UP, ACC
ADD RIGHT
ADD LEFT
MOV ACC, DOWN

@7
MOV UP, LEFT

@8
# 201 CYCLES
# 9 NODES
# 42 INSTR

@9
MOV UP, DOWN

@10