백준 6568번 (귀도 반 로썸은 크리스마스날 심심하다고 파이썬을 만들었다, C++) [BAEKJOON]

귀도 반 로썸은 크리스마스날 심심하다고 파이썬을 만들었다

https://www.acmicpc.net/problem/6568

시간 제한메모리 제한제출정답맞힌 사람정답 비율
1 초128 MB101522217222.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;
}

댓글 달기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

위로 스크롤