고스택
시간 제한1초메모리 제한128 MB
스택 기반의 가상 기계 명령어들을 시뮬레이션하며 특수한 나눗셈 규칙과 오류 조건을 처리해 여러 입력에 대한 결과를 출력합니다.
문제
고창영은 스택을 조금 변형하여 고스택을 만들었다. 고스택은 정수만 저장할 수 있으며, 아래 10가지 연산을 수행한다.
편의상 스택의 맨 위에 있는 수를 첫 번째 수, 그 아래를 차례대로 두 번째 수, 세 번째 수라고 부른다.
- NUM X: 를 스택의 맨 위에 넣는다. ()
- POP: 맨 위의 수를 제거한다.
- INV: 첫 번째 수의 부호를 바꾼다. (예: )
- DUP: 첫 번째 수를 복사하여 스택의 맨 위에 하나 더 넣는다.
- SWP: 첫 번째 수와 두 번째 수의 위치를 맞바꾼다.
- ADD: 두 번째 수와 첫 번째 수를 더한다.
- SUB: 두 번째 수에서 첫 번째 수를 뺀다. (두 번째 − 첫 번째)
- MUL: 두 번째 수와 첫 번째 수를 곱한다.
- DIV: 두 번째 수를 첫 번째 수로 나눈 몫을 넣는다. (두 번째 수가 피제수, 첫 번째 수가 제수)
- MOD: 두 번째 수를 첫 번째 수로 나눈 나머지를 넣는다. (두 번째 수가 피제수, 첫 번째 수가 제수)
이항 연산에서는 첫 번째 수가 오른쪽 피연산자, 두 번째 수가 왼쪽 피연산자이다. 연산을 수행할 때는 두 수를 모두 스택에서 꺼낸 뒤 그 결과를 다시 스택에 넣는다.
다음 중 하나라도 발생하면 프로그램 에러이다.
- 연산에 필요한 수가 스택에 부족한 경우
- 0으로 나누는 경우 (DIV, MOD)
- 연산 결과의 절댓값이 을 초과하는 경우
음수 나눗셈의 모호함을 없애기 위해 다음 규칙을 따른다. 피연산자에 음수가 있으면 먼저 절댓값을 취해 계산한다. 그 뒤 몫과 나머지의 부호를 다음과 같이 정한다.
- 몫의 부호: 두 피연산자 중 음수가 정확히 하나이면 음수, 그렇지 않으면 양수이다.
- 나머지의 부호: 피제수(두 번째 수)의 부호와 같다.
예를 들어 , , 이다.
프로그램 에러가 발생하면 현재 실행을 즉시 중단하고, 그 뒤의 어떤 명령도 수행하지 않는다.
입력
입력은 여러 대의 기계 설명으로 이루어진다. 각 기계 설명은 프로그램과 입력 영역으로 나뉜다.
프로그램은 한 줄에 하나씩 놓인 명령어로 이루어진다. 각 명령어는 위에서 설명한 세 글자 대문자이며, 그 외의 글자는 주어지지 않는다. NUM은 명령어 뒤에 공백으로 구분된 정수 하나가 함께 주어지고, 이 정수는 이상 이하이다. 프로그램은 END 줄에서 끝난다.
입력 영역의 첫 줄에는 프로그램을 실행할 횟수 이 주어진다. () 이어지는 개의 줄에는 각각 입력값 가 하나씩 주어진다. () 각 입력값마다 프로그램을 한 번씩, 서로 독립적으로 실행한다. 매 실행을 시작할 때 스택에는 해당 입력값 하나만 들어 있다.
기계 설명들은 빈 줄로 구분된다. QUIT 줄이 나오면 더 이상 기계 설명이 없다는 뜻이다. 한 프로그램의 명령어 수가 개를 넘는 경우는 없으며, 실행 도중 스택에 개 이상의 수가 쌓이는 경우도 없다.
출력
각 입력값에 대해 프로그램을 실행한 뒤 출력값을 한 줄에 하나씩 출력한다. 출력값은 실행이 끝났을 때 스택에 남아 있는 수이다.
프로그램 에러가 발생했거나, 실행이 끝났을 때 스택에 남은 수가 정확히 한 개가 아니라면 대신 ERROR를 출력한다.
서로 다른 기계의 출력 사이에는 빈 줄을 하나씩 넣어 구분한다. 마지막 기계의 출력 뒤에는 빈 줄을 넣지 않는다.