https://adventofcode.com/2019/day/5
수성에 가까워질수록 점점 땀이 나기 시작합니다. 요정들은 컴퓨터가 온도 환경 관리 단말(Thermal Environment Supervision Terminal; TEST)을 지원하도록 업그레이드해 에어컨을 틀자고 제안합니다.
온도 환경 관리 단말(TEST)은 진단 프로그램(퍼즐의 입력)을 실행함으로써 동작하기 시작합니다. TEST 진단 프로그램은 이미 가지고 있는 정수 컴퓨터를 약간만 수정하면 실행할 수 있을 것 입니다.
먼저, 두 개의 새로운 명령어를 지원해야 합니다.
- 연산코드
3
은 하나의 정수를 입력으로 받아, 그것을 파라미터가 지정하는 번지에 저장합니다. 예를 들어, 명령어3,50
은 입력 값을 50번지에 저장합니다. - 연산코드
4
는 파라미터가 가리키는 번지의 값을 출력합니다. 예를 들어, 명령어4,50
은 50번지에 있는 값을 출력합니다.
이 명령어들을 사용하는 프로그램들을 실행할 때는, 무엇이 입력되어야 하고 무엇이 출력되어야 하는지가 함께 제공될 것입니다. 프로그램 3,0,4,0,99
는 무엇을 입력으로 받는 그것을 출력하고 종료하는 프로그램이 될 것입니다.
두 번째로, 파라미터 모드를 지원해야 합니다.
명령어의 각 파라미터들은 각자의 파라미터 모드를 가집니다. 현재, 당신이 가지고 있는 컴퓨터는 이미 파라미터 모드 0
, 즉 파라미터의 값이 주소를 의미하는 **주소 모드(position mode)**를 지원하고 있습니다. 만약 파라미터가 50
이면, 그 값은 메모리의 50
번지에 저장된 값이 됩니다.
이제 당신의 컴퓨터는 파라미터 모드 1
, **즉시 모드(immediate mode)**를 지원해야 합니다. 즉시 모드에서는 파라미터를 값으로 해석합니다. 즉, 파라미터가 50
이면, 단순히 그 값은 50
입니다.
파라미터 모드를 나타내는 값은 명령어의 연산코드와 함께 저장됩니다. 연산의 종류를 나타내는 코드가 가장 오른쪽 두 자리(일의 자리와 십의 자리)이고, 파라미터 모드는 그 왼쪽으로 한 자리씩 늘어나는 형태로 붙게 됩니다. 즉, 첫 번째 파라미터에 대한 모드는 백의 자리에, 두 번째 파라미터에 대한 모드는 천의 자리에 붙는 식입니다. 해당 자리에 값이 없다면 0으로 생각하면 됩니다.
예를 들어, 1002,4,3,4,33
이라는 프로그램을 봅시다.
첫 번째 명렁어, 1002,4,3,4
는 곱셈 연산입니다. 가장 오른쪽 두 자리(02
)는 연산코드 2
를 나타냅니다. 그리고 왼쪽으로 이동해보면, 파라미터 모드는 차례로 0
(백의 자리), 1
(천의 자리), 0
(만의 자리, 표현되지 않았으므로 0
)입니다.
ABCDE
1002
DE - 두 자리 연산코드, 02 == 연산코드 2
C - 첫 번째 파라미터 모드, 0 == 주소 모드
B - 두 번째 파라미터 모드, 1 == 즉시 모드
A - 세 번째 파라미터 모드, 0 == 주소 모드, 0으로 시작하는 정수라 생략됨
이 명령어는 처음 두 파라미터를 곱합니다. 첫 번째 파라미터는 주소 모드의 4
이므로, 실제 값은 4
번지의 값인 33
입니다. 두 번째 파라미터는 즉시 모드의 3
이므로, 실제 값은 3
입니다. 결과 값인 99
는 세 번째 파라미터는 주소 모드의 4
이므로, 4
번지에 저장됩니다.
연산의 결과를 저장할 주소를 나타내는 파라미터는 결코 즉시 모드가 될 수 없습니다.
마지막으로, 몇 가지 참고할 점들입니다.
- 명령 포인터는 한 명령어의 실행이 끝날 때마다 그 명령어의 크기만큼 증가해야 합니다. 새 명령어들 때문에, 이제 이 값은
4
가 아닐 수 있습니다. - 정수 값은 음수일 수 있습니다.
1101,100,-1,4,0
은 유효한 프로그램입니다. (100 + -1
을 계산하고,4
번지에 저장합니다.)
TEST 진단 프로그램은 입력 명령어를 사용해 테스트할 시스템의 아이디를 요청할 것입니다. 이때 에어컨의 아이디인 1
을 제공하면 됩니다.
그러고나면 프로그램은 정수 프로그램의 각 요소가 잘 동작하는지 테스트할 것입니다. 각 테스트마다, 프로그램은 예상하던 값과 실제 계산 결과의 차이를 출력할 것입니다. 즉, 0
을 출력한다면 정상적으로 동작하고 있는 것입니다. 0
이 아닌 값이 출력된다면 어떤 기능이 정상적으로 동작하지 않는 것입니다. 만약 그렇다면, 출력 명령 전에 실행된 명령어를 확인해보세요.
프로그램은 마지막으로 진단 코드를 출력하고 즉시 종료될 것입니다. 이 마지막 출력은 에러가 아닙니다. 출력 직후에 프로그램이 종료되었다면, 프로그램의 실행이 완료된 것입니다. 진단 코드 외의 모든 값이 0
이라면, 진단 프로그램은 성공적으로 수행된 것입니다.
입력 명령어에 1
이라는 값을 제공하고 테스트를 모두 통과한 뒤, 프로그램이 만들어내는 진단 코드는 무엇인가요?
에어컨이 가동되기 시작했습니다. 시원해진 공기가 기분좋게 느껴졌지만, 잠시 후 온도 환경 관리 단말(TEST)에서 알람이 울리기 시작합니다. 에어컨이 열기를 다른 곳으로 내보내지 못하고 우주선 내부로 되돌리고 있는 탓에, 결과적으로는 내부의 온도를 더 올리는 꼴이 되었습니다.
당신은 열기를 외부로 방출시키기 위해 TEST를 확장시켜야 합니다. 다행히 진단 프로그램(퍼즐의 입력)은 이 기능을 이미 지원하고 있습니다. 하지만 당신의 정수 컴퓨터는 그렇지 않죠.
당신의 컴퓨터는 몇가지 연산코드를 추가로 지원해야 합니다.
- 연산코드
5
는 jump-if-true입니다. 첫 번째 파라미터의 값이0
이 아니면, 명령 포인터를 두 번째 파라미터의 값으로 옮깁니다.0
이라면 아무것도 하지 않습니다. - 연산코드
6
은 jump-if-false입니다. 첫 번째 파라미터의 값이0
이면, 명령 포인터를 두 번째 파라미터의 값으로 옮깁니다.0
이 아닐 경우 아무것도 하지 않습니다. - 연산코드
7
은 less than입니다. 첫 번째 파라미터의 값이 두 번째 파라미터의 값보다 작으면, 세 번째 파라미터가 가리키는 주소에1
을 저장합니다. 그렇지 않다면0
을 저장합니다. - 연산코드
8
은 equals입니다. 첫 번째 파라미터의 값과 두 번째 파라미터의 값이 같으면, 세 번째 파라미터가 가리키는 주소에1
을 저장합니다. 그렇지 않다면0
을 저장합니다.
기존의 명령어들과 똑같이, 추가되는 명령어들도 파라미터 모드를 지원해야 합니다.
일반적으로는 한 명령어의 수행이 끝나면, 명령 포인터는 명령어의 크기만큼 증가합니다. 하지만 명령어가 명령 포인터의 값 자체를 바꾸는 경우, 명령 포인터는 해당 값을 사용하며 자동으로 증가되지 않습니다.
하나의 입력 값을 받아, 8
과 비교하여, 하나의 출력 값을 만드는 프로그램 몇가지를 보겠습니다.
3,9,8,9,10,9,4,9,99,-1,8
- 주소 모드를 사용하여, 입력 값이8
과 같은지 비교합니다. 같다면1
을, 아니라면0
을 저장합니다.3,9,7,9,10,9,4,9,99,-1,8
- 주소 모드를 사용하여, 입력 값이8
보다 작은지 비교합니다. 작다면1
을, 아니라면0
을 저장합니다.3,3,1108,-1,8,3,4,3,99
- 즉시 모드를 사용하여, 입력 값이8
과 같은지 비교합니다. 같다면1
을, 아니라면0
을 저장합니다.3,3,1107,-1,8,3,4,3,99
- 즉시 모드를 사용하여, 입력 값이8
보다 작은지 비교합니다. 작다면1
을, 아니라면0
을 저장합니다.
이어서, 점프 명령어를 테스트하는 몇 가지 예시이비다. 입력이 0
이면 0
을, 0
이 아니면 1
을 반환합니다.
3,12,6,12,15,1,13,14,13,4,13,99,-1,0,1,9
(주소 모드를 사용)3,3,1105,-1,9,1101,0,0,12,4,12,99,1
(즉시 모드를 사용)
더 큰 예시도 있습니다.
3,21,1008,21,8,20,1005,20,22,107,8,21,20,1006,20,31,
1106,0,36,98,0,0,1002,21,125,20,4,20,1105,1,46,104,
999,1105,1,46,1101,1000,1,20,4,20,1105,1,46,98,99
위 예시는 하나의 입력 값을 요청합니다. 입력 값이 8
보다 작으면 999
를, 8
과 같으면 1000
을, 8
보다 크면 1001
을 출력합니다.
이번에는 TEST 진단 프로그램이 열기 방출 제어기를 테스트하게 하기 위해, 입력 값으로 시스템의 아이디 값인 5
를 입력해주세요. 진단 프로그램은 단 하나의 숫자(진단 코드)만을 출력할 것입니다.
아이디가 5
인 시스템의 진단 코드는 무엇인가요?