리스트를 계산하는 인터프리터를 만들자. 이 인터프리터는 여러 표현식을 처리할 수 있어야 하며, 연산자의 우선순위는 높은 것부터 낮은 것 순으로 괄호, 배열 슬라이싱, 단항 연산자, 이항 연산자, 리스트 이어붙이기, 대입이다.
배열 슬라이싱은 [begin:end] 형태로 표현식 뒤에 붙어 그 리스트의 부분 리스트를 돌려준다. 인덱스는 0부터 세며 begin은 포함하고 end는 포함하지 않는다. 따라서 L[1:3]은 리스트 L의 인덱스 1, 2번 원소로 이루어진 리스트다. 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을 향해 버림)을 따른다. 0으로 나누는 일은 없다. 표현식의 상수는 항상 정수이고, 단항 연산자가 상수 바로 앞에 오는 경우는 없다. 계산 도중 나타나는 모든 정수는 32비트 정수형으로 나타낼 수 있다.
입력은 여러 줄로 이루어진다. 각 줄은 대입문이거나 print 키워드로 시작하는 출력문이다. 각 줄의 길이는 50자를 넘지 않고, 전체 입력은 30줄을 넘지 않는다. 입력의 마지막에 # 한 글자만 있는 줄이 올 수 있으며, 그 줄은 무시한다.
각 출력문마다, print 뒤에 오는 표현식이 나타내는 리스트의 원소를 공백 없이 쌍점 :으로 구분해 한 줄에 출력한다. 리스트가 비어 있으면 빈 줄을 출력한다. 출력하는 리스트의 길이는 항상 15를 넘지 않는다.