본문 바로가기
프로그램/C언어 1000제

C언어 203제] 인터프리터(Interpreter)

by 건티 2024. 12. 25.
728x90

출처 : 반크_백제역사 유적지구 및 이스탐블역사 유적지구

 

문제]

어떤 컴퓨터에 열 개의 레지스터와 1,000워드 분량의 램(RAM)이 있다. 각 레지스터 또는 램 위치에는 0 이상 999 이하의 세 자리 정수가 저장된다. 명령어는 세 자리 정수로 인코딩되며 램에 저장된다. 인코딩은 다음과 같다.

100 종료
2dn d레지스터를 n으로 설정(0이상 9이하) 
3dn d레지스터에  n을  더함.
4dn d레지스터를에  n을 곱함.
5ds d레지스터를  s레지스터의 값으로 설정.
6ds s 레지스터의 값을 d레지스터에 덤함.
7ds d 레지스터에 s레지스터의 값을 곱함. 
8da d레지스터를 a레지스터에 저장된 주소의 램에 들어있는 값으로 설정.
9da a레지스터에 저장된 주소의 램에 s레지스터의 값을 대입
0ds s레지스터에 0이 들어있지 않으면 d레지스터에 있는 위치로 이동



모든 레지스터의 초기값은 000이다. 램에 저장되는 초기값은 표준 입력으로부터 들어온다. 처음으로 실행될 명령은 주소가 0인 램에 들어있다. 모든 결과는 값이 1,000이 넘어가면 1,000으로 나눈 나머지로 줄어든다.

입력
입력은 입력 케이스의 개수를 나타내는 양의 정수 한개가 들어있는 줄로 시작되며 그 줄에는 그 숫자 밖에 입력되지 않는다. 그 뒤에는 빈 줄이 하나 들어가고 서로 다른 입력 케이스 사이에는 빈 줄 두 개가 입력된다. 각 입력 케이스는 최대 1,000개의 부호가 없는 세 자리 정수로 구성되며 그 숫자들은 0부터 시작하는 연속된 램 위치에 저장되는 내용을 나타낸다. 값이 지정되지 않는 램 위치는 000으로 초기화된다.

출력
각 테스트 케이스마다 하나씩의 정수를 출력한다. 출력되는 정수는 종료 명령어에 이르기까지(종료 명령어 포함) 실행된 명령어의 개수다. 프로그램이 종료된다고 미리 가정해도 된다. 케이스가 여러 개 있는 경우에는 각 출력 사이에 빈 줄을 출력한다.

입력 예
1

299
492
495
399
492
495
399
283
279
689
078
100
000
000
000


출력 예
16



출처]
Programming Challenges 알고리즘 트레이닝 북(한빛미디어) : 문제 6 인터프리터(Interpreter) p46


참고풀이]

#include <stdio.h>

int main()
{
   int cases, executed;
   int i, t, addr, pc, done, inst;
   int arg1, arg2;
   char Line[1000]={'\0'};
   int reg[10]={0};
   int ram[1000]={0};

   //케이스 수를 입력받는다.
   scanf("%d",&cases) ;
   //빈줄 두개를 입력한다.
   gets(Line);
   gets(Line);

   for(t=0; t<cases;t++)
   {
      //램값을 입력받는다.
      for(addr=0; gets(Line) && *Line; addr++) 
         sscanf(Line,"%d",&ram[addr]);

      //입력 후 나머지 램과 레지스터 초기화 
      for(;addr<1000;addr++) ram[addr]=0;
      for(i=0;i<10;i++) reg[i]=0;

      //시뮬레이션
      executed=0;
      pc = 0;
      done = 0;
      while(!done)
      {
         inst = ram[pc] / 100;
         arg1=(ram[pc]/10) % 10;
         arg2=ram[pc] % 10;
         pc++;
         executed++;

         switch(inst)
         {
            case 1: done=1; break;
            case 2: reg[arg1]=arg2; break;
            case 3:
               reg[arg1]=(reg[arg1]+arg2) % 1000;
               break;
            case 4:
               reg[arg1]=(reg[arg1]*arg2) % 1000;
               break;
            case 5:
               reg[arg1]=reg[arg2]; break;
            case 6:
               reg[arg1]=(reg[arg1]+reg[arg2]) % 1000;
               break;
            case 7:
               reg[arg1]=(reg[arg1]*reg[arg2]) % 1000;
               break;
            case 8:
               reg[arg1]=ram[reg[arg2]]; break;
            case 9:
               ram[reg[arg2]]=reg[arg1]; break;
            case 0:
               if(reg[arg2]) pc=reg[arg1];
               break;
         }
      }
      //결과출력
      if(t>0) putchar('\n');
      printf("%d\n",executed);
   }
   return 0;
}

 

참고풀이 결과]

 

 

 

 

 

대한민국의 아름다운 영토, 독도

 

반응형

댓글