고스택

시간 제한1초메모리 제한128 MB

요약
스택 기반의 가상 기계 명령어들을 시뮬레이션하며 특수한 나눗셈 규칙과 오류 조건을 처리해 여러 입력에 대한 결과를 출력합니다.
난이도

보통10점 중 5점

유형
스택, 시뮬레이션, 구현
정답자
아직 제출이 없습니다

문제

고창영은 스택을 조금 변형하여 고스택을 만들었다. 고스택은 정수만 저장할 수 있으며, 아래 10가지 연산을 수행한다.

편의상 스택의 맨 위에 있는 수를 첫 번째 수, 그 아래를 차례대로 두 번째 수, 세 번째 수라고 부른다.

  • NUM X: XX를 스택의 맨 위에 넣는다. (0≤X≤1090 \le X \le 10^9)
  • POP: 맨 위의 수를 제거한다.
  • INV: 첫 번째 수의 부호를 바꾼다. (예: 42→−4242 \rightarrow -42)
  • DUP: 첫 번째 수를 복사하여 스택의 맨 위에 하나 더 넣는다.
  • SWP: 첫 번째 수와 두 번째 수의 위치를 맞바꾼다.
  • ADD: 두 번째 수와 첫 번째 수를 더한다.
  • SUB: 두 번째 수에서 첫 번째 수를 뺀다. (두 번째 − 첫 번째)
  • MUL: 두 번째 수와 첫 번째 수를 곱한다.
  • DIV: 두 번째 수를 첫 번째 수로 나눈 몫을 넣는다. (두 번째 수가 피제수, 첫 번째 수가 제수)
  • MOD: 두 번째 수를 첫 번째 수로 나눈 나머지를 넣는다. (두 번째 수가 피제수, 첫 번째 수가 제수)

이항 연산에서는 첫 번째 수가 오른쪽 피연산자, 두 번째 수가 왼쪽 피연산자이다. 연산을 수행할 때는 두 수를 모두 스택에서 꺼낸 뒤 그 결과를 다시 스택에 넣는다.

다음 중 하나라도 발생하면 프로그램 에러이다.

  • 연산에 필요한 수가 스택에 부족한 경우
  • 0으로 나누는 경우 (DIV, MOD)
  • 연산 결과의 절댓값이 10910^9을 초과하는 경우

음수 나눗셈의 모호함을 없애기 위해 다음 규칙을 따른다. 피연산자에 음수가 있으면 먼저 절댓값을 취해 계산한다. 그 뒤 몫과 나머지의 부호를 다음과 같이 정한다.

  • 몫의 부호: 두 피연산자 중 음수가 정확히 하나이면 음수, 그렇지 않으면 양수이다.
  • 나머지의 부호: 피제수(두 번째 수)의 부호와 같다.

예를 들어 13÷(−4)=−313 \div (-4) = -3, (−13) mod 4=−1(-13) \bmod 4 = -1, (−13) mod (−4)=−1(-13) \bmod (-4) = -1이다.

프로그램 에러가 발생하면 현재 실행을 즉시 중단하고, 그 뒤의 어떤 명령도 수행하지 않는다.

입력

입력은 여러 대의 기계 설명으로 이루어진다. 각 기계 설명은 프로그램과 입력 영역으로 나뉜다.

프로그램은 한 줄에 하나씩 놓인 명령어로 이루어진다. 각 명령어는 위에서 설명한 세 글자 대문자이며, 그 외의 글자는 주어지지 않는다. NUM은 명령어 뒤에 공백으로 구분된 정수 하나가 함께 주어지고, 이 정수는 00 이상 10910^9 이하이다. 프로그램은 END 줄에서 끝난다.

입력 영역의 첫 줄에는 프로그램을 실행할 횟수 NN이 주어진다. (0≤N≤10,0000 \le N \le 10{,}000) 이어지는 NN개의 줄에는 각각 입력값 ViV_i가 하나씩 주어진다. (0≤Vi≤1090 \le V_i \le 10^9) 각 입력값마다 프로그램을 한 번씩, 서로 독립적으로 실행한다. 매 실행을 시작할 때 스택에는 해당 입력값 ViV_i 하나만 들어 있다.

기계 설명들은 빈 줄로 구분된다. QUIT 줄이 나오면 더 이상 기계 설명이 없다는 뜻이다. 한 프로그램의 명령어 수가 100,000100{,}000개를 넘는 경우는 없으며, 실행 도중 스택에 1,0001{,}000개 이상의 수가 쌓이는 경우도 없다.

출력

각 입력값에 대해 프로그램을 실행한 뒤 출력값을 한 줄에 하나씩 출력한다. 출력값은 실행이 끝났을 때 스택에 남아 있는 수이다.

프로그램 에러가 발생했거나, 실행이 끝났을 때 스택에 남은 수가 정확히 한 개가 아니라면 대신 ERROR를 출력한다.

서로 다른 기계의 출력 사이에는 빈 줄을 하나씩 넣어 구분한다. 마지막 기계의 출력 뒤에는 빈 줄을 넣지 않는다.

예제3

  1. 예제 1

    입력
    DUP
    MUL
    NUM 2
    ADD
    END
    3
    1
    10
    50
    
    NUM 1
    NUM 1
    ADD
    END
    2
    42
    43
    
    NUM 600000000
    ADD
    END
    3
    0
    600000000
    1
    
    QUIT
    
    예상 출력
    3
    102
    2502
    
    ERROR
    ERROR
    
    600000000
    ERROR
    600000001
    
  2. 예제 2

    입력
    NUM 5
    ADD
    END
    3
    0
    1000000000
    999999995
    
    INV
    END
    2
    1000000000
    0
    
    QUIT
    
    예상 출력
    5
    ERROR
    1000000000
    
    -1000000000
    0
    
  3. 예제 3

    입력
    NUM 4
    INV
    DIV
    END
    4
    13
    12
    0
    7
    
    NUM 4
    INV
    MOD
    END
    4
    13
    12
    0
    7
    
    INV
    NUM 4
    MOD
    END
    4
    13
    12
    0
    7
    
    INV
    NUM 4
    INV
    MOD
    END
    4
    13
    12
    0
    7
    
    QUIT
    
    예상 출력
    -3
    -3
    0
    -1
    
    1
    0
    0
    3
    
    -1
    0
    0
    -3
    
    -1
    0
    0
    -3