Skip to content

Latest commit

 

History

History

day5

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 

Day 5: 소행성 예보 맑음 (Sunny with a Chance of Asteroids)

https://adventofcode.com/2019/day/5

Part 1

수성에 가까워질수록 점점 땀이 나기 시작합니다. 요정들은 컴퓨터가 온도 환경 관리 단말(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이라는 값을 제공하고 테스트를 모두 통과한 뒤, 프로그램이 만들어내는 진단 코드는 무엇인가요?

Part 2

에어컨이 가동되기 시작했습니다. 시원해진 공기가 기분좋게 느껴졌지만, 잠시 후 온도 환경 관리 단말(TEST)에서 알람이 울리기 시작합니다. 에어컨이 열기를 다른 곳으로 내보내지 못하고 우주선 내부로 되돌리고 있는 탓에, 결과적으로는 내부의 온도를 더 올리는 꼴이 되었습니다.

당신은 열기를 외부로 방출시키기 위해 TEST를 확장시켜야 합니다. 다행히 진단 프로그램(퍼즐의 입력)은 이 기능을 이미 지원하고 있습니다. 하지만 당신의 정수 컴퓨터는 그렇지 않죠.

당신의 컴퓨터는 몇가지 연산코드를 추가로 지원해야 합니다.

  • 연산코드 5jump-if-true입니다. 첫 번째 파라미터의 값이 0이 아니면, 명령 포인터를 두 번째 파라미터의 값으로 옮깁니다. 0이라면 아무것도 하지 않습니다.
  • 연산코드 6jump-if-false입니다. 첫 번째 파라미터의 값이 0이면, 명령 포인터를 두 번째 파라미터의 값으로 옮깁니다. 0이 아닐 경우 아무것도 하지 않습니다.
  • 연산코드 7less than입니다. 첫 번째 파라미터의 값이 두 번째 파라미터의 값보다 작으면, 세 번째 파라미터가 가리키는 주소에 1을 저장합니다. 그렇지 않다면 0을 저장합니다.
  • 연산코드 8equals입니다. 첫 번째 파라미터의 값과 두 번째 파라미터의 값이 같으면, 세 번째 파라미터가 가리키는 주소에 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인 시스템의 진단 코드는 무엇인가요?