[프로그래머스 lev2/JS] n진수 게임

woolee의 기록보관소·2022년 11월 8일
0

알고리즘 문제풀이

목록 보기
51/178

문제 출처

프로그래머스 lev2 - n진수 게임

문제

나의 풀이

1차 시도 (96.2/100)

toString(진수)로 문자열로 변환해준뒤,
문자열에 대해 for문을 순회하면서 순서를 측정한다. 이때 순서 측정할 때 i%m으로 하면 전체 순서를 측정할 수 없으므로 전역변수 cnt로 순서를 측정한다.

cnt%m==p-1이 되는 지점이 튜브의 순서이므로 이때 answer에 추가해준다.

하지만 tc1에서만 무한루프에 빠진다..왜!?

function solution(n, t, m, p) {
  let answer = '';
  let num = 0;
  let cnt = 0;

  while (answer.length!==t) {
    let str = num.toString(n);
    for (let i=0; i<str.length; i++) {
      if (cnt%m==p-1) {
        if (isNaN(str[i])) answer += str[i].toUpperCase();
        else answer += str[i];
      }
      cnt++;
    }
    num++;
  }

  return answer;
}

console.log(solution(2, 4, 2, 1));
// console.log(solution(16, 16, 2, 1));
// console.log(solution(16, 16, 2, 2));

2차 시도 (통과)

문제가 생겼을 때는 항상 log를 찍어보자.
answer 값이 011에서 01110로 한번에 넘어가버려서 answer.length==4인 경우를 판별하지 못하므로
중간에 answer.length == 4면 즉시 멈추도록 break; 장치 추가

function solution(n, t, m, p) {
  let answer = '';
  let num = 0;
  let cnt = 0;

  while (answer.length<t) {
    let str = num.toString(n);
    for (let i=0; i<str.length; i++) {
      if (cnt%m==p-1) {
        if (isNaN(str[i])) {
          answer += str[i].toUpperCase();
          if (answer.length == t) break;
        }
        else {
          answer += str[i];
          if (answer.length == t) break;
        }
      }
      cnt++;
    }
    num++;
  }

  return answer;
}

console.log(solution(2, 4, 2, 1));
// console.log(solution(16, 16, 2, 1));
// console.log(solution(16, 16, 2, 2));

다른 풀이

seq 문자열로 자른 후, seq 문자열에서의 [p-1]를 찾는 방법

function solution(n, t, m, p) {
    let res = ''
    let num = 0
    let seq = ''
    while (res.length < t) {
        if (seq.length >= m) {
            res += seq[p - 1]
            seq = seq.slice(m)
        }
        else {
            seq += num.toString(n).toUpperCase()
            num++
        }
    }
    return res
}

애초에 for문을 순회할 때, p부터 t까지를 m 간격으로 순회하도록 설정하는 방법

function solution(n, t, m, p) {
    let answer = '',
        numbers = [],
        j = 0;

    for (let i = p; answer.length < t; i += m) {
        let order = i - 1;

        while (numbers[order] === undefined) {
            j.toString(n).toUpperCase().split('').forEach(v => numbers.push(v));

            j++;
        }

        answer += numbers[order];
    }

    return answer;
}

배열 요소를 idx로 채워넣고,
변수 numberedNumbers에 reduce로 모든 숫자에 대한 진수를 문자열로 집어넣은 후,
for문을 돌면서 해당하는 순번의 문자열을 answer에 집어넣는 방식.

function solution(n, t, m, p) {
  const numbers = [
    ...new Array(1000000)
  ].map((n, idx) => idx)

  const numberedNumbers = numbers.reduce((p,c) => p + `${c.toString(n)}`)

  // console.log(numberedNumbers)

  let answers = []
  for (let i=0; i<t; i++) {
    answers.push(numberedNumbers[p+(i*m)-1])
  }

  // console.log(answers.join('').toUpperCase())
  return answers.join('').toUpperCase()
}

위 배열을 이용한 풀이와 유사한 논리인듯?

function solution(n, t, m, p) {
  var tubeT = Array.apply(null,Array(t)).map((a,i)=>i*m+p-1);
  var line = '';
  var max = m*t + p;
  for (var i =0;line.length <= max; i++) {
      line += i.toString(n);
  }
  return tubeT.map(a=>line[a]).join('').toUpperCase();
}

console.log(solution(2, 4, 2, 1));
profile
https://medium.com/@wooleejaan

0개의 댓글