귀도 반 로썸은 크리스마스날 심심하다고 파이썬을 만들었다
https://www.acmicpc.net/problem/6568
시간 제한 | 메모리 제한 | 제출 | 정답 | 맞힌 사람 | 정답 비율 |
---|---|---|---|---|---|
1 초 | 128 MB | 1015 | 222 | 172 | 22.051% |
문제
그래서 여러분도 크리스마스날 심심해서 컴퓨터를 하나 만들었다.
이 컴퓨터는 아주 적은 수의 명령어를 사용하는 하나의 프로세서, 32바이트 메모리, 8비트짜리 가산기, 5비트짜리 프로그램 카운터(pc)로 이루어져 있다.
폰 노이만 구조를 표방하여 이 컴퓨터는 메모리와 프로그램 구문을 공유한다.
프로그램 카운터는 다음에 실행되어야 하는 명령어의 주소를 갖고 있다.
각 명령어의 길이는 1바이트이며, 상위 3비트는 명령어의 종류를, 하위 5비트는 피연산자를 표현한다.
피연산자는 언제나 메모리 값(XXXXX)이다.
피연산자가 필요하지 않은 명령어도 있는데, 이때는 하위 5비트는 무의미하다(—–).
사용되는 명령어들의 의미는 다음과 같다.
000xxxxx STA x : 메모리 주소 x에 가산기의 값을 저장한다.
001xxxxx LDA x : 메모리 주소 x의 값을 가산기로 불러온다.
010xxxxx BEQ x : 가산기의 값이 0이면 PC 값을 x로 바꾼다.
011—– NOP : 아무 연산도 하지 않는다.
100—– DEC : 가산기 값을 1 감소시킨다.
101—– INC : 가산기 값을 1 증가시킨다.
110xxxxx JMP x : PC 값을 x로 바꾼다.
111—– HLT : 프로그램을 종료한다.
초기엔 PC와 가산기 값은 모두 0이다.
명령어를 불러와 해독한 뒤, 그 명령어를 실행하기 전에 PC 값은 1 증가한다.
프로그램은 언제나 종료된다고 가정해도 좋다.
입력
입력은 여러 개의 테스트 케이스로 주어진다.
각 테스트 케이스는 32개의 줄에 걸쳐 각 메모리 값, 즉 코드가 순서대로 8비트 2진수의 형태로 주어진다.
왼쪽에 있는 비트일수록 상위 비트이다.
입력은 EOF와 함께 종료된다.
출력
각 테스트 케이스마다 한 줄에 걸쳐 프로그램이 종료되었을 때의 가산기 값을 역시 8비트 2진수 형태로 출력한다.
이때도 왼쪽에 출력될수록 상위 비트이다.
예제 입력 1
00111110 10100000 01010000 11100000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00111111 10000000 00000010 11000010 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 11111111 10001001
예제 출력 1
10000111
힌트
누산기의 값은 8비트이므로 그 범위를 초과하면 하위 8비트만 남겨두고 잘린다.
2번째 명령어인 INC를 수행하기 직전 가산기 값은 11111111이었는데, INC 수행 후 00000000이 된다.
출처
Contest > University of Ulm Local Contest > University of Ulm Local Contest 2000 C번
- 문제를 번역한 사람: kks227
알고리즘 분류
EOF와 2진수 입력을 처리하는 것이 중점인 문제 같다.
그리 좋은 문제는 아닌 듯…
통과된 코드
#pragma warning(disable:4996) #include <iostream> using namespace std; int main(void) { ios_base::sync_with_stdio(0); cin.tie(0); while (true) { int Memory[32] = { 0 }; for (int i = 0; i < 32; i++) { for (int j = 0; j < 8; j++) { int bit; //EOF if (scanf("%1d", &bit) < 0) return 0; Memory[i] = Memory[i] * 2 + bit; } } int programCnt = 0; // adder = 가산기 int adder = 0; while (true) { // 상위 3자리 bit를 계산해 줍니다. int command = Memory[programCnt] / 32; // 하위 5자리 비트를 계산해줍니다.(나머지 연산) int operand = Memory[programCnt] % 32; if (command == 7) { break; } // HLT 프로그램을 종료한다. programCnt = (programCnt + 1) % 32; //2^8 = 256 switch (command) { case 0: // STA x 메모리 주소 x에 가산기의 값을 저장한다. Memory[operand] = adder; break; case 1: // LDA x 메모리 주소 x의 값을 가산기로 불러온다. adder = Memory[operand]; break; case 2: // BEQ x 가산기의 값이 0이면 PC 값을 x로 바꾼다. if (adder == 0) { programCnt = operand; } break; case 3: // NOP 아무 연산도 하지 않는다. break; case 4: // DEC 가산기 값을 1 감소시킨다. adder = (adder + 255) % 256; break; case 5: // INC 가산기 값을 1 증가시킨다. adder = (adder + 1) % 256; break; case 6: // JMP x PC 값을 x로 바꾼다. programCnt = operand; break; } } for (int i = 7; i >= 0; i--) printf("%1d", (adder >> i) & 1); printf("\n"); } return 0; }