SEGMENT 31904
SEQUENCE COUNTER
문제
- SEQUENCES ARE ZERO-TERMINATED
- READ A SEQUENCE FROM IN
- WRITE THE SUM TO OUT.S
- WRITE THE LENGTH TO OUT.L
- 시퀀스는 0으로 종료된다고 정의한다.
- IN으로 들어오는 시퀀스를 읽는다.
- 시퀀스를 이루는 수들의 합을 OUT.S로 출력한다.
- 시퀀스의 길이를 OUT.L로 출력한다.
풀이 1
- 335 CYCLES / 4 NODES / 24 INSTR
4개의 노드를 사용하는 방법이다.
@0
@1
MOV UP, DOWN
@2
@3
@4
MOV UP, ACC
MOV ACC, DOWN # 0 판별용
MOV ACC, DOWN # SUM 계산용
@5
@6
@7
@8
^:
SAV # ACC(합계)를 BAK에 저장한다
MOV UP, ACC # IN 값을 ACC 에 저장한다
MOV ACC, RIGHT # 길이 계산을 하고 있는 @9 노드에 값을 보내준다
JEZ END-SEQ # IN 값이 0 이면 시퀀스가 종료된 것이므로 goto END-SEQ
SWP # 시퀀스가 끝나지 않았으므로 BAK(합계)를 ACC로 가져온다
ADD UP # 입력값을 ACC(합계)에 더한다
JMP ^ # goto 시작지점(^)
END-SEQ:
SWP # BAK에 저장해둔 합계를 ACC로 가져온다
MOV ACC, DOWN # ACC(합계)를 출력한다
MOV UP, NIL # SUM 계산용 두번째 중복값을 버린다
MOV 0, ACC # 다음 시퀀스를 위해 합계를 0 으로 초기화한다
@9
^:
SAV # ACC(길이)를 BAK에 저장한다
MOV LEFT, ACC # @8 노드에서 보낸 값을 ACC에 저장한다
JEZ END-SEQ # 시퀀스가 끝났다면(ACC가 0이면) goto END-SEQ
SWP # 시퀀스가 끝나지 않았으므로 BAK(길이)를 ACC로 가져온다
ADD 1 # 길이를 1 증가시킨다
JMP ^ # goto 시작지점(^)
END-SEQ:
SWP # BAK에 저장해둔 길이를 ACC로 가져온다
MOV ACC, DOWN # ACC(길이)를 출력한다
MOV 0, ACC # 다음 시퀀스를 위해 길이를 0 으로 초기화한다
@10
풀이 2: 아마도 최적화된 풀이
- 233 CYCLES / 4 NODES / 20 INSTR
내 나름 이것보다 더 최적화된 코드를 작성하긴 일단은 어려울 것 같다.
TIS-100의 레지스터가 취급할 수 있는 정수의 범위가 -999
~ 999
라는 특징을 이용하면, 분기를 위한 명령을 좀 아낄 수 있다.
@0
@1
MOV UP, DOWN
@2
@3
@4
^:
MOV UP, ACC # IN 값을 ACC 에 저장한다
JEZ END-SEQ # IN 값이 0 이면 시퀀스가 종료된 것이므로 goto END-SEQ
MOV ACC, DOWN # IN 값을 @8 노드로 내려보낸다
JMP ^ # goto 시작지점(^)
END-SEQ: # 시퀀스가 끝났다면
MOV -999, DOWN # -999를 @8 노드로 내려보낸다
@5
@6
@7
@8
^:
ADD UP # @4 노드에서 전달받은 값을 ACC(합계)에 더한다
# -999 를 받았다면 ACC 는 합계 - 999 가 된다
JLZ END-SEQ # ACC(합계)가 0 미만이면 시퀀스가 종료된 것이므로 goto END-SEQ
MOV 1, RIGHT # ACC(합계)가 0 이상이면 길이를 계산하는 @9 노드로 1 을 보낸다
JMP ^ # goto 시작지점(^)
END-SEQ: # 시퀀스가 끝났다면
MOV -999, RIGHT # -999를 길이를 계산하는 @9 노드로 내려보낸다
ADD 999 # ACC(합계)에 999를 더해서 999를 빼기 전의 합계값으로 복원한다
MOV ACC, DOWN # 복원한 합계 값을 출력한다
MOV 0, ACC # 다음 시퀀스를 위해 ACC(합계)를 0 으로 초기화한다
@9
^:
ADD LEFT # @8 노드에서 전달받은 값을 ACC(길이)에 더한다
# -999 를 받았다면 ACC 는 길이 - 999 가 된다
JLZ END-SEQ # ACC(길이)가 0 미만이면 시퀀스가 종료된 것이므로 goto END-SEQ
JMP ^ # goto 시작지점(^)
END-SEQ: # 시퀀스가 끝났다면
ADD 999 # ACC(길이)에 999를 더해서 999를 빼기 전의 길이값으로 복원한다
MOV ACC, DOWN # 복원한 길이 값을 출력한다
MOV 0, ACC # 다음 시퀀스를 위해 ACC(길이)를 0 으로 초기화한다
@10