const readFileSyncAddress = '/dev/stdin';
const fs = require('fs');
let [N] = fs
.readFileSync(readFileSyncAddress)
.toString()
.trim()
.split(' ')
.map((v) => +v);
const solution = function (n) {
let i = 1;
let range = 1;
// n이 범위를 넘어가면 도달한 것.
while (range < n) {
//range : 해당 회차까지 접근가능한 수의 범위, 이전 수 + 6의 배수.
range += 6 * i;
//n이 range까지 도달하기 위한 횟수
i++;
}
return i;
};
console.log(solution(N));
풀이과정
이번 문제는 너무 어려워서 다른 답안들을 참고했다. 기존에 틀린 답안은 아래와 같다.
const solution = function (n) {
if (n === 1) return 1;
if (n >= 1 && n <= 6) return 2;
let k = 1;
let j = 2;
let f = k;
for (let i = 1; i < n; i++) {
if (n >= 6 * f && n <= 6 * k) return i + 1;
f = k;
k += j;
j++;
}
};
console.log(solution(N));
처음에 접근할 수 있는 수의 범위가 회차에 따라 6*1, 6*3, 6*6 ... 와 같이 증가한다는 것을 발견했다. 그래서 입력된 숫자인 n이 어느 범위에 위치하는지 알면, 그에 맞는 답안을 도출할 수 있을거라는 생각으로 접근했다. 문제는 회차에 따라 6 * k 에서 k의 값이 달라지고, 이에 따른 모든 범위를 다 체크할 수 없다는 점이었다. 따라서 이전 k 값을 저장할 변수 f와, 계속 증가하는 k 값을 업데이트할 변수 j를 추가했다.
그런데 위 답안에서는 n의 크기에 따라서 답안이 기대와 다르게 (1이 작던지, 1이 크던지) 도출되었다. 추측으로는 범위를 체크하는 부분에서 잘못된 것 같은데, 해당 범위를 파악하기 위해서 선언한 변수가 많아지니 복잡해져서 이를 줄이기 위해 고민하다가 다른 풀이를 참고했다.
다른 풀이에서는 회차별로 접근할 수 있는 숫자의 합을 누적하고, 이 범위를 넘어갈 때 까지 카운트를 해서 이 카운트를 리턴하는 방식으로 푸는 것 같다. 내 풀이방식에서는 n이 정확히 어디에 위치하는지 알야아 한다는 강박때문에 이것을 계속 추적하려고 해서 점점 더 복잡해진 것 같다. 그냥 몇 번 만에 지정된 범위를 넘어서는지가 문제의 핵심이었는데... 핵심에 가까워지는 노력이 필요할 것 같다.