칸토어 집합은 0과 1사이의 실수로 이루어진 집합으로, 구간 [0, 1]에서 시작해서 각 구간을 3등분하여 가운데 구간을 반복적으로 제외하는 방식으로 만든다.
전체 집합이 유한이라고 가정하고, 다음과 같은 과정을 통해서 칸토어 집합의 근사를 만들어보자.
-가 3N개 있는 문자열에서 시작한다.
문자열을 3등분 한 뒤, 가운데 문자열을 공백으로 바꾼다. 이렇게 하면, 선(문자열) 2개가 남는다.
이제 각 선(문자열)을 3등분 하고, 가운데 문자열을 공백으로 바꾼다. 이 과정은 모든 선의 길이가 1일때 까지 계속 한다.
예를 들어, N=3인 경우, 길이가 27인 문자열로 시작한다.
---------------------------
여기서 가운데 문자열을 공백으로 바꾼다.
--------- ---------
남은 두 선의 가운데 문자열을 공백으로 바꾼다.
--- --- --- ---
한번 더
- - - - - - - -
모든 선의 길이가 1이면 멈춘다. N이 주어졌을 때, 마지막 과정이 끝난 후 결과를 출력하는 프로그램을 작성하시오.
입력을 여러 줄로 이루어져 있다. 각 줄에 N이 주어진다. 파일의 끝에서 입력을 멈춘다. N은 0보다 크거나 같고, 12보다 작거나 같은 정수이다.
입력으로 주어진 N에 대해서, 해당하는 칸토어 집합의 근사를 출력한다.
0
1
3
2
-
- -
- - - - - - - -
- - - -
-- --일 경우에는 "--", " ", "--"의 덩어리가 있게 되고, j는 0, 2, 4가 된다.)const fs = require('fs');
let N = fs.readFileSync(0, 'utf-8').toString().trim().split('\n');
for (let i = 0; i < N.length; i++) {
let n = Number(N[i].trim());
n = 3 ** n;
let string = Array.from({ length: n }, () => '-');
if (n !== 1) {
while (true) {
if (n === 1) break;
for (let j = 0; j < string.length; j += n) {
if (string[j] === '-') {
for (let k = j + n / 3; k < j + 2 * (n / 3); k++) {
string[k] = ' ';
}
} else continue;
}
n /= 3;
}
}
console.log(string.join(''));
}
직전에 풀었던 문제랑 비슷한 문제였는데, 조금 더 복잡해진? 문제이다. 아무래도 이전 문제는 배열을 그냥 합쳐주기만 하면 됐는데 이번에는 중간에 연산을 생략해야하는 범위가 나오고 그 길이도 제각각이다보니 다음 연산을 수행해주어야 할 위치를 찾기를 어떻게 구현해야할지 생각하다보니 더 복잡하게 생각한 것 같다.