[BOJ 7607] 리스트 계산기

View as PDF

Submit solution

Points: 5
Time limit: 1.0s
Memory limit: 128M

Problem types
Allowed languages
Assembly, Awk, C, C++, Java, Pascal, Perl, Python, Sed, Text

리스트를 계산할 수 있는 인터프리터를 만들어보자. 이 인터프리터는 (우선순위가 높은 것에서 낮은 것 순으로) 괄호, 배열 슬라이싱, 단항 연산자, 이항 연산자, 리스트 이어붙이기, 대입 연산자를 포함하는 여러 표현식을 다룰 수 있어야 한다.

배열 슬라이싱 연산자는 [begin:end] 형식을 따르며, 표현식 뒤에 놓여 해당 리스트의 부분 리스트를 반환한다. 인덱스는 0부터 세고, begin은 포함하지만 end는 포함하지 않는다. 따라서 L[1:3]은 리스트 L의 2번째 원소부터 3번째 원소까지를 의미한다. begin이나 end는 생략할 수 있다. begin이 생략되면 0, end가 생략되면 리스트의 길이인 것으로 보면 된다. 만약 end가 begin보다 작거나 같으면 결과는 빈 리스트이다. begin과 end는 15를 넘지 않는다. 인덱스가 범위를 벗어나는 일 또한 없다.

단항 연산자(+, -, *, /)는 리스트 앞에 놓여 리스트의 첫 두 원소를 삭제하고, 두 원소에 해당 연산자를 이항 연산자로 적용한 다음, 결과를 다시 리스트의 제일 앞에 넣는 작업을 반복한다. 예를 들어 +(1:2:4)는 1과 2를 삭제하고, 둘을 더한 3을 리스트 앞에 넣어서 +(3:4)가 된다. 다시 3과 4를 삭제하고, 둘을 더한 7을 리스트 앞에 넣으면 +(7)이 된다. 이제 리스트가 원소 하나만을 포함하므로 결과값은 7이 된다. 계산 과정에서 단항 연산자가 무한하거나 빈 리스트에 적용되는 일은 없다.

이항 연산자(+, -, *, /)는 두 리스트의 대응하는 위치에 있는 원소끼리 연산한다. 만약 한 리스트가 다른 쪽보다 짧으면, 짧은 쪽의 마지막 원소를 뒤에 더 넣어 둘의 길이를 맞춘다. 따라서 (1:2:3)+(4:5)는 (4:5)의 뒤에 마지막 원소인 5를 하나 더 넣어 (4:5:5)로 길이를 맞춰주고, 대응하는 위치끼리 더하여 (5:7:8)이 된다. 한쪽 리스트가 아예 빈 리스트이면 연산 결과는 빈 리스트이다. 예시로 A-A[2:2]는 뒤쪽이 빈 리스트이므로 결과도 빈 리스트이다. 이항 곱셈과 나눗셈은 덧셈과 뺄셈보다 우선순위가 높다.

리스트 이어붙이기는 쌍점(:) 연산자로 주어진다. 상수는 길이 1짜리 리스트로 본다.

대입은 등호(=) 연산자로 주어진다. 모든 변수는 한 글자이고, 대소문자를 구분하며 재정의되지 않는다. 변수의 정의는 이전에 정의되지 않은 변수를 포함하지 않지만, 자기 자신을 재귀적 정의로 포함하는 건 가능하다.

모든 나눗셈은 정수 나눗셈이고 C/C++의 정수 나눗셈 규칙을 따른다. 0으로 나누는 일은 발생하지 않는다. 표현식에 있는 상수는 항상 정수이고, 단항 연산자가 상수 바로 앞에 놓이는 경우는 없다. 계산 과정에서 나타나는 모든 정수는 32비트 정수형으로 표현할 수 있다.

입력 형식

입력은 여러 줄로 구성된다. 각 줄은 대입문 또는 “print” 키워드로 시작하는 출력문이다. 각 줄의 길이는 50보다 작거나 같고, 입력은 30줄을 넘지 않는다.

출력 형식

각 출력문마다 키워드 뒤에 오는 리스트의 원소를 공백 없이 쌍점(:)으로 구분하여 출력한다. 출력할 리스트의 길이는 항상 15보다 크지 않다.

예제 입력

print +(1:2:4)
print (1:2:3:4:5)[1:3]
print (1:2:3)+(4:5)
N=1:(N+1)
E=2*N
print E[:5]
print +E[:10]
F=1:1:(F+F[1:])
print F[:10]
#

예제 출력

7
2:3
5:7:8
2:4:6:8:10
110
1:1:2:3:5:8:13:21:34:55

Comments

There are no comments at the moment.