Gooseberry Tart BASIC

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

요약
LET, GOTO, IF, FOR/NEXT, OUT, COMMENT로 이루어진 BASIC 부분집합을 해석하는 인터프리터를 구현하고, 각 프로그램의 출력을 순서대로 인쇄한다.
난이도

보통10점 중 7점

유형
구현, 시뮬레이션, 문자열, 완전 탐색
정답자
아직 제출이 없습니다

문제

많은 사람이 초창기 가정용 컴퓨터와 거기에 내장되어 있던 BASIC 언어를 정겹게 기억합니다. 최근에는 여러 팀이 이 상징적인 시스템을 현대적으로 되살리려 경쟁하면서 향수를 자극하는 개발이 활발합니다. 당신은 "Gooseberry Tart" 팀을 도와 GTB1이라는 BASIC 인터프리터를 만들게 되었습니다. 요즘 컴퓨터는 메모리가 넉넉하고 영상 스트림을 실시간으로 처리해야 하므로, 이 인터프리터는 빠르게 동작해야 합니다. 아래에 명시된 제한된 부분 집합을 해석하는 인터프리터를 구현하세요.

GTB1 언어

  • 변수 타입은 오직 하나, 32비트 부호 있는 정수뿐입니다. 모든 <식>은 정숫값을 가집니다. 비교(불리언) 문법은 IF 문 안에서만 등장합니다.
  • 변수 이름은 문자(A–Z, a–z)로 시작하고 그 뒤에 문자나 숫자가 올 수 있습니다. 길이에는 제한이 없지만 앞의 두 글자만 의미가 있으며, 대소문자를 구분하지 않습니다. 예를 들어 Fred, Fr, Freda, fRE는 모두 같은 변수입니다.
  • 예약어도 대소문자를 구분하지 않고 앞의 두 글자만 의미가 있습니다. 어떤 변수 이름도 예약어와 앞 두 글자가 같아서는 안 됩니다. 예약어는 LET, GOTO, IF, FOR, TO, NEXT, OUT, COMMENT입니다.
  • 산술식에는 괄호 ( )와 이항 연산자 + - * / %(덧셈, 뺄셈, 곱셈, 정수 나눗셈, 나머지)를 통상적인 우선순위로 사용할 수 있습니다.
  • 단항 마이너스는 식의 맨 앞이나 괄호로 묶인 부분식의 맨 앞에만 올 수 있으며, 이항 +, -와 같은 우선순위를 가집니다.
  • 프로그램은 명령어 줄의 나열입니다. 각 줄은 줄 번호로 시작합니다. 줄 번호는 항상 오름차순이며 11 이상 1000010000 이하입니다. 각 줄은 대입, GOTO, IF, FOR, NEXT, OUT, 주석 중 정확히 하나의 문장을 담습니다.

문장 형식

  • 대입: LET <변수> = <식>
  • GOTO: GOTO <줄 번호>
  • IF: IF <식> <비교> <식> GOTO <줄 번호>. 여기서 <비교>는 =, <, >, <=, >=, <>(같다, 작다, 크다, 작거나 같다, 크거나 같다, 다르다) 중 하나입니다.
  • FOR: FOR <변수> = <시작식> TO <끝식>
  • NEXT: NEXT <변수>
  • 주석: COMMENT <임의의 텍스트>
  • OUT: OUT <식>

FOR / NEXT 반복

반복문은 같은 변수를 쓰는 FOR와 NEXT 한 쌍으로 이루어집니다. FOR 문으로 시작해 반복 본문이 이어지고 NEXT 문으로 끝납니다. FOR 문이 실행되면 시작식의 값이 변수에 대입되고 본문이 최소 한 번 실행됩니다. NEXT 문이 실행될 때마다 변수에 11을 더하고, 그 결과가 끝식보다 작거나 같으면 본문을 다시 실행합니다. 끝식은 NEXT가 실행될 때마다 다시 계산됩니다. 반복은 중첩될 수 있으며, 중첩은 반드시 올바르게(안쪽 FOR/NEXT가 바깥쪽 FOR와 NEXT 사이에 완전히 들어가도록) 이루어져야 합니다. GOTO로 FOR/NEXT 구조 안으로 들어가거나 밖으로 나올 수 있습니다.

실행

문장은 기본적으로 작성된 줄 번호 순서대로, 첫 줄부터 실행됩니다. GOTO와 IF는 이 순서를 바꿀 수 있습니다. 실행이 마지막 줄을 지나면 프로그램이 끝납니다. 변수는 미리 선언할 필요가 없으며, 처음 대입되거나 참조될 때 생겨납니다. 대입되기 전에 참조된 변수의 값은 00입니다. OUT 문은 식의 값을 한 줄로 출력합니다.

입력

입력은 여러 프로그램의 나열입니다. 각 프로그램은 그 프로그램의 줄 수를 나타내는 정수 NN(1≤N≤10001 \le N \le 1000)으로 시작하고, 이어서 NN개의 문장 줄이 옵니다. 어떤 문장도 8080자를 넘지 않습니다. 토큰 사이는 공백 하나 이상으로 구분될 수 있고, 줄의 앞이나 끝에 공백이 있을 수 있습니다. 탭은 없으며, 연산자나 괄호 주위에 공백이 없어도 됩니다. 각 문장 줄은 줄 번호와 문장으로 이루어집니다. 입력은 NN이 00인 프로그램으로 끝납니다. 모든 프로그램은 문법적으로 올바르며 반드시 종료됨이 보장됩니다.

출력

각 프로그램마다 Programme <i>(여기서 <i>는 1,2,3,…1, 2, 3, \dots) 줄을 먼저 출력하고, 이어서 그 프로그램의 OUT 문이 만들어 낸 모든 줄을 순서대로 출력합니다.

원본 테스트 데이터는 최대 10910^9개의 명령을 실행해야 할 수 있으므로, 효율적인 인터프리터가 필요합니다.

예제4

  1. 예제 1

    입력
    1
    1000 OUT 225
    6
    10 OUT 1
    20 LET S = 0
    30 FOR I = 1 TO 100
    40 LET S = S + I
    50 NEXT I
    60 OUT S
    0
    
    예상 출력
    Programme 1
    225
    Programme 2
    1
    5050
    
  2. 예제 2

    입력
    6
    10 OUT 2+3*4
    20 OUT (2+3)*4
    30 OUT -5+3
    40 OUT -(2+3)*2
    50 OUT 17/5
    60 OUT 17%5
    0
    
    예상 출력
    Programme 1
    14
    20
    -2
    -10
    3
    2
    
  3. 예제 3

    입력
    4
    10 LET Fred = 3
    20 LET fRE = Fred + 4
    30 OUT FR
    40 OUT freddy
    0
    
    예상 출력
    Programme 1
    7
    7
    
  4. 예제 4

    입력
    7
    10 let s = 0
    20 let i = 1
    30 if i > 10 goto 70
    40 let s = s + i
    50 let i = i + 1
    60 goto 30
    70 out s
    0
    
    예상 출력
    Programme 1
    55