[알고리즘] 124 나라의 숫자

2022. 5. 12. 13:23·알고리즘
목차
  1. 문제 설명
  2. 나의 풀이
반응형

문제 설명

124 나라가 있습니다. 124 나라에서는 10진법이 아닌 다음과 같은 자신들만의 규칙으로 수를 표현합니다.

  1. 124 나라에는 자연수만 존재합니다.
  2. 124 나라에는 모든 수를 표현할 때 1, 2, 4만 사용합니다.

예를 들어서 124 나라에서 사용하는 숫자는 다음과 같이 변환됩니다.

10진법 124 나라 10진법 124 나라
1 1 6 14
2 2 7 21
3 4 8 22
4 11 9 24
5 12 10 41

자연수 n이 매개변수로 주어질 때, n을 124 나라에서 사용하는 숫자로 바꾼 값을 return 하도록 solution 함수를 완성해 주세요.

제한사항

  • n은 500,000,000이하의 자연수 입니다.

입출력

n result
1 1
2 2
3 4
4 11

나의 풀이

let n = 10;

function solution(n) {
  let answer = "0";
  let Lang = ["1", "2", "4"];

  for (let i = 0; i < n; i++) {
    answer = (parseInt(answer) + 1).toString();

    for (let j = 1; j <= answer.length; j++) {
      let current = parseInt(answer[answer.length - j]);
      let prev = answer[answer.length - (j + 1)];

      if (current === 4) {
        answer = answer.replace(
          `${prev ? prev : ``}` + `${current}`,
          `${parseInt(prev ? prev : 0) + 1}` + `1`
        );
      }
    }
  }

  let result = "";

  for (let i = answer.length - 1; i >= 0; i--) {
    result = Lang[parseInt(answer[i] - 1)] + result;
  }

  return result;
}

const t0 = performance.now();
console.log(solution(n));
const t1 = performance.now();
console.log(t1 - t0, "milliseconds");

최초의 나의 풀이다. 

1부터 n까지 반복하면서 1씩 증가시키는 방법으로 작업하였다. 

 

하지만 500,000,000번 반복할 경우 작업 시간이 너무 오래걸리면서 코드 최적화가 필요하다고 느꼈다. 

let n = 500000000;
//  41 10
//  42 11
//  44 12
//  111 13
//  112 14
//  114 15
//  121 16
//  122 17
//  124 18
//  141 19
//  142 20
//  144 21
//  211 22
//  212 23
function solution(n) {
  const LANG = [1, 2, 4];

  let check = parseInt(n % 3 === 0 ? n / 3 : n / 3 + 1);

  let temp = n - (check - 1) * 3 - 1;
  let baseArray = [0];

  for (let i = 1; i < check; i++) {
    baseArray[0] += 1;

    for (let j = 0; j < baseArray.length; j++) {  -- 1
      if (baseArray[j] === 4) {
        if (baseArray[j + 1]) {
          baseArray[j + 1] += 1;
        } else {
          baseArray.push(1);
        }
        baseArray[j] = 1;
      }
    }
  }

  let result = "";

  baseArray.reverse();

  if (!(baseArray[0] === 0 && baseArray.length === 1)) {
    for (let i = 0; i < baseArray.length; i++) {
      result = result + LANG[baseArray[i] - 1];
    }
  }

  return result + LANG[temp];
}

const t0 = performance.now();
console.log(solution(n));
const t1 = performance.now();
console.log(t1 - t0, "milliseconds");
// for (let i = 1; i <= 25; i++) {
//   console.log(i, " = ", solution(i));
// }

그래서 이번에는 배열을 활용해서 값이 3보다 크면 다음으로 넘겨주는 방식으로 작업을 하였다. 

 

즉, baseArray의 첫 번째 인자에 우선 값을 계속 더해주고, 다음 인자로 넘어가서 다시 값을 확인해 4보다 크면 

또 다음 값으로 넘기는 방식이다. 

 

check, 앞자리가 3번씩 반복되는 특징을 이용해서 만들었지만 여전히 500,000,000번 실행할 경우 

시간이 오래걸리는 것을 확인했다. 

let n = 500000000;
//  41 10
//  42 11
//  44 12
//  111 13
//  112 14
//  114 15
//  121 16
//  122 17
//  124 18
//  141 19
//  142 20
//  144 21
//  211 22
//  212 23
function solution(n) {
  const LANG = [1, 2, 4];

  let check = parseInt(n % 3 === 0 ? n / 3 : n / 3 + 1);

  let temp = n - (check - 1) * 3 - 1;
  let baseArray = new Array(20).fill(0);
  baseArray[0] = check - 1;

  for (let i = 0; i < baseArray.length; i++) {
    while (baseArray[i] !== 0 && baseArray[i] - 3 > 0) {
      baseArray[i + 1]++;
      baseArray[i] = baseArray[i] - 3;
    }
  }

  baseArray = baseArray.filter((value) => value);

  baseArray.reverse();

  let result = "";

  if (!(baseArray[0] === 0 && baseArray.length === 1)) {
    for (let i = 0; i < baseArray.length; i++) {
      result = result + LANG[baseArray[i] - 1];
    }
  }

  return result + LANG[temp];
}
const t0 = performance.now();
console.log(solution(n));
const t1 = performance.now();
console.log(t1 - t0, "milliseconds");
// for (let i = 1; i <= 25; i++) {
//   console.log(i, " = ", solution(i));
// }

이번엔 처음부터 n의 값을 배열의 첫 번째 인자에 넣고 3씩 빼서 다음 인자에 + 1 시키는 방법으로 작업해보았다. 

 

500,000,000번 실행을 하면 265ms 정도 시간이 걸리는것을 확인했다. 

실행속도가 확실히 줄었지만, 여전히 오래 걸린다고 판단해 수정하였다. 

let n = 9;
//  41 10
//  42 11
//  44 12
//  111 13
//  112 14
//  114 15
//  121 16
//  122 17
//  124 18
//  141 19
//  142 20
//  144 21
//  211 22
//  212 23

// 1 2 3
// 1 2 10

// 12

// 1 2 0
// 1 2 4

// 001 1   1
// 002 2   2
// 010 3   0
// 011 4  11
// 012 5  12
// 020 6  10
// 021 7  21
// 022 8  22
// 100 9  20
// 101 10 01

//  10 => 3 => 1
//   1    0    1
//  10 => 3 => 0
//   9 => 2 => 0
function deep(n, a) {
  if (n === 0) return;
  a.push(n % 3);

  deep(parseInt((n - 1) / 3), a);
}

function solution(n) {
  var answer = "";

  const arr = [];
  deep(n, arr);

  const LANG = ["4", "1", "2"];

  for (let i = 0; i < arr.length; i++) {
    answer = LANG[arr[i]] + answer;
  }

  return answer;
}

const t0 = performance.now();
console.log(solution(n));
const t1 = performance.now();
console.log(t1 - t0, "milliseconds");
// for (let i = 1; i <= 25; i++) {
//   console.log(i, " = ", solution(i));

// }

3진수를 만드는 방식을 활용해 코드를 작업했다. 

 

10진수 1, 2, 3이 각각 3진수에서는 1, 2, 10이고 124 나라에서는 1, 2, 4이다. 

3진수에서 0, 1, 2를 4, 1, 2 순으로 생각한다면 

 

10진수 1, 2, 3이 1, 2, 0이 된다. 즉 3을 n으로 넣었을 때, 0이 배열에 들어가면 성공인 것이다. 

 

그러면 deep 함수에서는 n % 3 을 한 값을 배열에 넣어주고 재귀함수로 다시 deep 함수를 호출한다. 

 

처음 n 은 3이기 때문에 n %  3 ( 3 % 3 )은 0이 된다. 

우리가 목표로 하는 0이 배열에 들어갔기 때문에 다음 재귀함수에서 n을 0으로 만들어서 재귀함수를 탈출해야한다. 

그러므로 deep(n / 3, a) 일반적인 3진수 만드는 재귀함수에서 n - 1을 해주면 3 => 2가 되어 (n - 1) / 3은 0이 된다.

 

한 문제를 풀기위해서 하루라는 시간을 전부 사용해서 푼적은 처음이였다. 

알고리즘을 쉽게 생각했는데, 풀다보니 개발을 하는 폭을 넓혀주고, 자주 사용하지 않는 함수나 개발 방법을 사용하며, 

개발 능력도 증가하는 것 같다. 

 

출처: 프로그래머스 코딩 테스트 연습, https://programmers.co.kr/learn/challenges

반응형
저작자표시 비영리 변경금지

'알고리즘' 카테고리의 다른 글

[알고리즘] 타겟 넘버  (1) 2022.05.15
[알고리즘] 기능 개발  (1) 2022.05.13
[알고리즘] 멀쩡한 사각형  (1) 2022.05.11
[알고리즘] 없는 숫자 더하기  (3) 2022.05.07
[알고리즘] 크레인 인형뽑기 게임  (2) 2022.05.06
  1. 문제 설명
  2. 나의 풀이
'알고리즘' 카테고리의 다른 글
  • [알고리즘] 타겟 넘버
  • [알고리즘] 기능 개발
  • [알고리즘] 멀쩡한 사각형
  • [알고리즘] 없는 숫자 더하기
잉여개발자
잉여개발자
풀스택 개발자를 목표로 잉여롭게 개발 공부도 하면서 다양한 취미 생활도 즐기고 있는 잉여 개발자입니다.
  • 잉여개발자
    잉여로운 개발일지
    잉여개발자
    • 분류 전체보기 (789)
      • 개발정보 (36)
      • 개발환경 (7)
      • 개발생활 (19)
      • React (141)
        • 이론 (23)
        • 기능 (12)
        • 실험실 (88)
        • 버그 (6)
        • 패스트캠퍼스 (9)
        • Npm (3)
      • React Native (28)
        • 공통 (6)
        • TypeScript (3)
        • JavaScript (18)
        • 버그 (1)
      • Next.js (30)
        • 이론 (13)
        • 실험실 (13)
        • 버그 (3)
      • Web (35)
      • 알고리즘 (202)
        • 풀이 힌트 (39)
      • JavaScript (47)
      • TypeScript (29)
        • 기초 (27)
        • 실험실 (2)
      • Node.js (13)
        • 이론 (0)
        • 기능 (3)
        • 실험실 (9)
        • 버그 (1)
      • 도커 (4)
      • CCNA (22)
        • 이론 (4)
        • 문제 (18)
      • 취미생활 (167)
        • 잉여로운 칵테일 (2)
        • 잉여의 식물키우기 (130)
        • 잉여로운 여행기 (11)
        • 잉여의 제2외국어 (21)
        • 잉여로운 책장 (2)
      • Java (1)
        • Java의 정석 (1)
      • 꿀팁 공유 (3)
  • 태그

    알고리즘
    webpack
    리얼학습일기
    식물
    타입스크립트
    네트워크
    Docker
    CSS
    ChatGPT
    리얼클래스
    next.js
    javascript
    다이소
    네이버 부스트캠프
    CCNA
    자바스크립트
    리액트
    redux
    바질 키우기
    바질
    영어독학
    ReactNative
    영어회화
    typescript
    덤프
    react
    Node.js
    Babel
    프로그래머스
    타일러영어
  • hELLO· Designed By정상우.v4.10.1
잉여개발자
[알고리즘] 124 나라의 숫자

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.