🟦/백준

[골드 1] Brainf**k 인터프리터 (의문점)

진뚱이용 2023. 8. 27. 15:59

https://www.acmicpc.net/problem/3954

 

3954번: Brainf**k 인터프리터

각 테스트 케이스에 대해서, 프로그램이 종료된다면 "Terminates"를, 무한 루프에 빠지게 된다면 "Loops"를 출력한다. 무한 루프에 빠졌을 때는, 프로그램의 어느 부분이 무한 루프인지를 출력한다. ([

www.acmicpc.net

하루 걸림 거의 24시간

1. ', '에서 문자를 넣는 작업에서 문자에 -'0'을 해줘야 하나?

-> 안 하는 걸로 왜 안 하는 건지 모름

2. 해쉬 맵으로 스택 짝 위치 기억하기 -> 안 하면 시간초과 난다고 정답 찾아보다가 알게 됨

-> '[' , ']'을 만나면 매번 자신의 짝을 찾으러 다니는 비용이 너무 큼

// 조건 실행
codes_index++;
count++;

if (codes_index >= c)
    break;

if (count >= 50000000)
    loop = true;

if (loop) {
    loops[codes_index] = true;
    count2++;
}

if (count2 >= 50000000)
    break;

1. 조건 실행하고

2.count++;

3. 그래야 이제 count가 5천만 일 때 5천만 번 한 거다 -> loop다

4. 5천만 번째부터 바로 그때부터 방문하는 지점들을 모두 true로 처리한다

5. 한 번의 무한 루프에서 실행되는 명령어의 개수는 50,000,000개 이하이다.

->라고 했으므로 5천만 번을 했으면 또 보장이 되므로 최소 5천만 번 돌리기

import java.io.*;
import java.util.*;

public class Main {
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringBuilder sb = new StringBuilder();
		StringTokenizer st;

		int t = Integer.parseInt(br.readLine());
		for (int test_case = 1; test_case <= t; test_case++) {
			int m, c, i;
			int[] memories;
			char[] codes;
			char[] inputs;

			st = new StringTokenizer(br.readLine());
			m = Integer.parseInt(st.nextToken());
			c = Integer.parseInt(st.nextToken());
			i = Integer.parseInt(st.nextToken());

			memories = new int[m];
			codes = new char[c];
			inputs = new char[i];

			String line = br.readLine();
			for (int index = 0; index < c; index++) {
				codes[index] = line.charAt(index);
			}

			line = br.readLine();
			for (int index = 0; index < i; index++) {
				inputs[index] = line.charAt(index);
			}

			/////////////////////////////////////////////
			HashMap<Integer, Integer> hashMap = new HashMap<>();
			Stack<Integer> stack = new Stack<>();
			for (int codes_index = 0; codes_index < c; codes_index++) {
				if (codes[codes_index] == '[')
					stack.add(codes_index);
				else if (codes[codes_index] == ']') {
					int tmp = stack.pop();
					hashMap.put(tmp, codes_index);
					hashMap.put(codes_index, tmp);
				}
			}

			int pointer = 0;
			int codes_index = 0;
			int inputs_index = 0;
			int count = 0;
			int count2 = 0;

			boolean loop = false;
			boolean[] loops = new boolean[codes.length];

			while (true) {
				if (codes[codes_index] == '-') {
					memories[pointer]--;
					if (memories[pointer] == -1)
						memories[pointer] = 255;
				} else if (codes[codes_index] == '+') {
					memories[pointer]++;
					if (memories[pointer] == 256)
						memories[pointer] = 0;
				} else if (codes[codes_index] == '<') {
					pointer--;
					if (pointer == -1)
						pointer = memories.length - 1;
				} else if (codes[codes_index] == '>') {
					pointer++;
					if (pointer == memories.length)
						pointer = 0;
				} else if (codes[codes_index] == '[') {
					if (memories[pointer] == 0) {
						codes_index = hashMap.get(codes_index);
					}

				} else if (codes[codes_index] == ']') {
					if (memories[pointer] != 0) {
						codes_index = hashMap.get(codes_index);
					}

				} else if (codes[codes_index] == '.') {

				} else if (codes[codes_index] == ',') {
					if (inputs_index < i) {
						memories[pointer] = inputs[inputs_index];
						inputs_index++;
					} else {
						memories[pointer] = 255;
					}
				}
				codes_index++;
				count++;

				if (codes_index >= c)
					break;

				if (count >= 50000000)
					loop = true;

				if (loop) {
					loops[codes_index] = true;
					count2++;
				}

				if (count2 >= 50000000)
					break;

			}

			if (loop) {
				sb.append("Loops").append(" ");
				for (int index = 0; index < loops.length; index++) {
					if (loops[index]) {
						sb.append(index - 1).append(" ");
						break;
					}
				}
				for (int index = loops.length - 1; index >= 0; index--) {
					if (loops[index]) {
						sb.append(index).append(" ");
						break;
					}
				}
				sb.append("\n");

			} else {
				sb.append("Terminates").append("\n");
			}

		}

		System.out.println(sb);

	}

}