만드는 중입니다

아직 만드는 중이라 바뀔 수 있습니다

주석은 전부 무시해 (Large)

시간 제한5초메모리 제한512 MB

요약
문서에서 중첩된 /* */ 주석 블록을 왼쪽에서 오른쪽으로 한 번 훑어 지우고 나머지 텍스트를 그대로 출력합니다.
난이도

보통10점 중 4점

유형
스택, 문자열, 시뮬레이션
정답자
아직 제출이 없습니다

문제

좋은 프로그래머는 주석을 잘 쓴다. 이고르도 프로그래머이고, /* ... */ 블록으로 쓰는 옛 C 스타일 주석을 좋아한다. 파이썬이든 하스켈이든 HTML/XML 문서든, 모든 언어와 모든 문서에서 이 형식 하나로 주석을 쓸 수 있다면 이고르에게는 그것이 가장 좋다.

이고르가 보기에 이 일은 그리 어렵지 않다. /*로 열고 주석 내용이 이어지다가 */로 닫는 블록을 모두 지우는 전처리기 하나면 된다. 주석을 지운 텍스트는 그 텍스트가 속한 컴파일러나 문서 렌더러에 그대로 넘기면 된다.

다만 이고르의 전처리기는 몇 가지 일을 더 한다.

  • 전처리기가 읽는 주석은 대부분의 프로그래밍 언어에서 괄호가 중첩되듯이 중첩된다. 주석 안에 주석이 들어갈 수 있다. 예를 들어 아래 코드 블록에는 전처리기가 지워야 할 바깥쪽 주석이 하나 있고, 그 안에 주석이 둘 더 들어 있다.

    printf("Hello /* a comment /* a comment inside comment */ 
            inside /* another comment inside comment */ 
            string */ world");
    

    전처리를 거치면 다음과 같이 바뀐다.

    printf("Hello  world");
    
  • 주석은 텍스트 어디에서나 시작한다. 문자열 "/*...*/" 안에서도, 숫자 상수 12/*...*/34 가운데에서도, 문자 이스케이프 \/*...*/n 안에서도 시작한다.

    형식을 갖춰 쓰면 다음과 같다.

    text:
      text-piece
      text-piece remaining-text
    text-piece:
      char-sequence-without-/*
      empty-string
    remaining-text:
      comment-block text
    
    comment-block:
      /* comment-content */
    comment-content:
      comment-piece
      comment-piece remaining-comment
    comment-piece:
      char-sequence-without-/*-or-*/
      empty-string
    remaining-comment:
      comment-block comment-content
    
    char:
      letters
      digits
      punctuations
      whitespaces
    

전처리기는 주어진 text에서 위 규칙에 맞는 comment-block을 모두 지운다.

입력

/*와 */로 둘러싼 주석 블록이 들어 있는 텍스트 문서가 주어진다. 입력은 항상 올바르고, 문제에서 정의한 text 형식을 따른다. 입력 파일은 항상 줄바꿈 문자로 끝난다.

출력

이 문제의 테스트 케이스는 하나뿐이다. 먼저 다음 줄을 출력한다.

Case #1:

그다음에 문제에서 정한 방식으로 주석을 모두 지운 문서를 출력한다. 주석 바깥의 공백과 빈 줄은 하나도 지우지 않는다.

제한

입력 프로그램의 크기는 100k 바이트 미만이다.

입력 프로그램에는 다음 문자만 들어 있다.

  • 영문자: a-z, A-Z
  • 숫자: 0-9
  • 문장 부호: ~ ! @ # % ^ & * ( ) - + = : ; " ' < > , . ? | / \ { } [ ] _
  • 공백 문자: 공백, 줄바꿈

힌트

  • 이고르는 주석을 한 번만 훑으며 지운다. 주석 블록을 지운 결과로 새로 생긴 주석 블록은 다시 지우지 않는다. 예를 들어

    //*no recursion*/* file header */
    

    는 다음과 같이 바뀐다.

    /* file header */
    
  • /*나 */에 쓰인 * 문자는 다른 /*나 */에 다시 쓰지 못한다. 예를 들어 다음은 올바른 주석 블록이 아니다.

    /*/
    

예제6

  1. 예제 1

    입력
    //*no recursion*/* file header
    ***********/************
    * Sample input program *
    **********/*************
    */
    int spawn_workers(int worker_count) {
      /* The block below is supposed to spawn 100 workers.
         But it creates many more.
         Commented until I figure out why.
      for (int i = 0; i < worker_count; ++i) {
        if(!fork()) {
          /* This is the worker. Start working. */
          do_work();
        }
      }
      */
      return 0; /* successfully spawned 100 workers */
    }
    
    int main() {
      printf("Hello /*a comment inside string*/ world");
      int worker_count = 0/*octal number*/144;
      if (spawn_workers(worker_count) != 0) {
        exit(-1);
      }
      return 0;
    }
    
    예상 출력
    Case #1:
    /* file header
    ************************
    */
    int spawn_workers(int worker_count) {
      
      return 0; 
    }
    
    int main() {
      printf("Hello  world");
      int worker_count = 0144;
      if (spawn_workers(worker_count) != 0) {
        exit(-1);
      }
      return 0;
    }
    
  2. 예제 2

    입력
    //*no recursion*/* file header */
    
    예상 출력
    Case #1:
    /* file header */
    
  3. 예제 3

    입력
    a/*/ still a comment */b
    
    예상 출력
    Case #1:
    ab
    
  4. 예제 4

    입력
    printf("Hello /* a comment /* a comment inside comment */
            inside /* another comment inside comment */
            string */ world");
    
    예상 출력
    Case #1:
    printf("Hello  world");
    
  5. 예제 5

    입력
    int a = 12/*octal?*/34;
    char c = '\/*escape*/n';
    
    예상 출력
    Case #1:
    int a = 1234;
    char c = '\n';
    
  6. 예제 6

    입력
    int main() {
        int x = 1;
    
        return x;
    }
    
    예상 출력
    Case #1:
    int main() {
        int x = 1;
    
        return x;
    }