세상에, Vim! (쉬움)
시간 제한1초메모리 제한512 MB
스택 언어로 프로그램을 작성해 x를 출력하되, 줄 순서를 뒤집으면 2x를, 줄을 사전순으로 정렬하면 -x를 출력하게 만든다.
문제
꼬마 Johnny는 여름 프로그래밍 캠프에 참가하고 있다. 첫 과제는 숫자 를 읽어 같은 숫자 를 출력하는 프로그램을 작성하는 것이었다. Johnny의 프로그램은 이미 잘 동작하고 있었지만, 사고가 일어났다. Vim 편집기를 쓰던 중 Johnny가 아무 생각 없이 뭔가를 눌렀고, 프로그램이 거꾸로 뒤집혔다. 즉, 프로그램의 줄 순서가 반대로 뒤집힌 것이다.
놀랍게도 프로그램은 여전히 동작했지만, 이제는 다른 일을 했다. 를 읽어 를 출력한 것이다.
Johnny는 줄을 원래 순서로 되돌리려고 무엇을 눌렀는지 기억해 보려 했지만, 또 실수해서 Vim이 프로그램의 줄을 정렬해 버렸다. Johnny는 새 프로그램을 시험해 보고 할 말을 잃었다. 이제 프로그램은 를 읽어 를 출력했다.
"세상에, Vim은 마법이야! 평생 Vim만 쓸 거야!"라고 Johnny가 외쳤다.
"그건 그냥 아무도 Vim을 종료하는 법을 모르기 때문이지"라고 다른 학생이 소리쳤다.
Johnny의 프로그램과 같은 동작을 하는 프로그램을 작성할 수 있는가?
이 문제에서는 간단한 스택 기반 프로그래밍 언어를 사용한다. 메모리는 부호 있는 정수의 스택이다. 여러 명령이 스택에 값을 넣거나 스택 꼭대기에서 값을 꺼낸다. 스택은 처음에는 비어 있고, 프로그램이 끝날 때 비어 있지 않아도 된다.
프로그램은 여러 줄로 이루어지고, 각 줄은 세미콜론으로 구분된 하나 이상의 명령으로 이루어진다. 명령은 다음 중 하나이다.
-
"
input": 입력에서 숫자 를 읽어 스택에 넣는다. 프로그램 실행 중 "input"은 한 번만 실행할 수 있다. -
"
jumpj": 즉시 줄 j의 처음으로 이동한다. 줄은 0부터 까지 번호가 매겨지며, 은 줄의 수이다. 으로 이동하면 프로그램이 종료된다. 또는 으로 이동하면 오류이다. -
"
pop": 스택에서 꼭대기 원소를 제거한다. 스택이 비어 있으면 오류이다. -
"
print": 스택에서 꼭대기 원소를 제거하고 그 값을 출력한다. 스택이 비어 있으면 오류이다. 프로그램 실행 중 "print"는 한 번만 실행할 수 있다. -
"
pushp": 상수 p를 스택 꼭대기에 넣는다. -
"
dup": 스택 꼭대기 원소를 복제한다. 현재 꼭대기 원소가 t라면 "dup"은 "pusht"와 같은 일을 한다. 스택이 비어 있으면 오류이다. -
"
+", "-", "*", "/": 스택에서 꼭대기 원소 a를 꺼내고, 다음 원소 b를 꺼내고, 각각 a + b, a − b, a ⋅ b, a/b를 0 방향으로 반올림한 값을 스택에 넣는다. 스택에 숫자가 두 개 미만이면 오류이다. 0으로 나누는 것도 오류이다.
이 언어는 매우 엄격하다. 여분의 공백이나 세미콜론 같은 것은 쓸 수 없다.
−231 이상 231 − 1 이하의 정수만 지원한다. 이 범위를 벗어나는 정수를 스택에 넣으면 오류이다.
입력
입력이 없다.
출력
정수 를 읽어 를 출력하는 프로그램을 작성해야 한다. 단, 프로그램의 줄 순서를 반대로 뒤집으면(즉, 마지막 줄이 첫 줄이 되는 식으로) 새 프로그램은 를 출력해야 한다. 그리고 프로그램의 줄을 사전순으로 정렬하면 를 출력해야 한다.
이라고 가정할 수 있다.
프로그램은 최대 1000줄까지 가질 수 있다. 모든 유효한 에 대해 프로그램은 최대 10\ 000개의 명령을 실행한 뒤 종료해야 한다.
각 줄은 최대 1000개의 명령을 포함할 수 있다.
힌트
위 프로그램은 를 읽어 을 출력한다.
위 프로그램의 줄 순서를 뒤집으면 "print"가 첫 명령이 되고, 빈 스택의 꼭대기를 출력하려고 하므로 프로그램이 실패한다.