• TOC {:toc}

이 글은 프로그래머스의 84512번 문제를 JavaScript로 풀이한 것을 모아놓은 글입니다.

일종의 연습 기록이며 제가 정답을 받은 코드와 참고할만한 다른 코드를 같이 기록합니다. 필요한 경우 코드에 대한 해설을 기록합니다만 코드는 통과했어도 해설은 틀릴 수 있기 때문에 가볍게 참고해주시길 부탁드립니다. 피드백은 편하신 방법으로 자유롭게 주시면 감사하겠습니다.

2023.11.29

테스트 통과 시간 메모리
테스트 1 통과 0.06ms 33.5MB
테스트 2 통과 0.06ms 33.4MB
테스트 3 통과 0.06ms 33.4MB
테스트 4 통과 0.06ms 33.4MB
테스트 5 통과 0.06ms 33.4MB
테스트 6 통과 0.06ms 33.5MB
테스트 7 통과 0.06ms 33.4MB
테스트 8 통과 0.06ms 33.4MB
테스트 9 통과 0.10ms 33.4MB
테스트 10 통과 0.09ms 33.4MB
테스트 11 통과 0.06ms 33.5MB
테스트 12 통과 0.06ms 33.4MB
테스트 13 통과 0.06ms 33.4MB
테스트 14 통과 0.08ms 33.4MB
테스트 15 통과 0.08ms 33.4MB
테스트 16 통과 0.06ms 33.4MB
테스트 17 통과 0.06ms 33.5MB
테스트 18 통과 0.06ms 33.4MB
테스트 19 통과 0.06ms 33.5MB
테스트 20 통과 0.07ms 33.4MB
테스트 21 통과 0.06ms 33.5MB
테스트 22 통과 0.09ms 33.4MB
테스트 23 통과 0.06ms 33.5MB
테스트 24 통과 0.07ms 33.4MB
테스트 25 통과 0.09ms 33.4MB
테스트 26 통과 0.07ms 33.5MB
테스트 27 통과 0.06ms 33.4MB
테스트 28 통과 0.06ms 33.3MB
테스트 29 통과 0.06ms 33.4MB
테스트 30 통과 0.06ms 33.5MB
테스트 31 통과 0.06ms 33.4MB
테스트 32 통과 0.07ms 33.4MB
테스트 33 통과 0.06ms 33.4MB
테스트 34 통과 0.06ms 33.4MB
테스트 35 통과 0.09ms 33.4MB
테스트 36 통과 0.10ms 33.4MB
테스트 37 통과 0.10ms 33.5MB
테스트 38 통과 0.06ms 33.4MB
테스트 39 통과 0.09ms 33.6MB
테스트 40 통과 0.06ms 33.4MB
단계 시작 시각 끝난 시각 걸린 시간
문제 이해 23:51:41 23:52:20
풀이 생각 1 23:52:23 00:16:58
코딩 1 00:17:01 00:49:37
풀이 생각 2 15:21:49 15:41:17
코딩 2 15:41:17 15:41:52
const toNum = {
    A: 0,
    E: 1,
    I: 2,
    O: 3,
    U: 4,
};
const digit = [781, 156, 31, 6, 1];

function solution(word) {
    const num = [...word].map((w) => toNum[w]);
    return [...num].reduce((acc, curr, i) => acc + curr * digit[i], 0) + word.length;
}

아이디어 & 풀이

각 문자의 전개를 수로 나타내면 다음과 같다.

A____ 1, AA___ 2, AAA__ 3, AAAA_ 4, AAAAA 5, AAAAE 6, AAAAI 7, AAAAO 8, AAAAU 9, AAAE_ 10, AAAI_ 16, AAAO_ 22, AAAU_ 28, AAE__ 34 AAEA_ 35, AAEE_ 41, AAEI_ 47, AAEO_ 53, AAEU_ 59, AAI__ 65, AAO__ 96, AAU__ 127, AE___ 158,

  • 특정 자리의 문자가 변하기 위해서는 이전 자리 묶음이 A, E, I, O, U 5세트 반복된 뒤 다음 값으로 넘어가기 위해 1을 더해준 만큼의 값을 증가시켜야 한다.
    • e.g., AAAA_AAAE_로 가려면 위해서는 AAAA*의 (AAAAA, AAAAE, AAAAI, AAAAO, AAAAU)5에 다음으로 넘어가기 위한 1을 더해주어야 한다.
  • 즉 각 자리의 값은 이전 자리값에 5를 곱한 뒤 1을 더한 값과 같으며 이를 계산하면 앞에서부터 781, 156, 31, 6, 1 이다.

주어진 문자를 다음의 규칙에 따라 각 자리의 값을 계산해 더하면 된다.

  • A는 하위 문자 조합을 순회하지 않고 바로 추가되므로 각 자리의 값이 아닌 1씩 증가한다. A는 자리 값을 곱할 때 고려되지 않도록 0으로 매핑한다.
  • E부터는 하위 문자 조합을 순회한 뒤에 증가하므로 순회한 하위 문자 조합의 수(자리 수)만큼 증가할 수 있도록 순서대로 1 ~ 4로 매핑한다.
  • word를 위의 규칙에 따라 매핑한 뒤 reduce의 인덱스를 이용해 자리에 맞는 값을 곱해가면서 각 값을 더한다.
  • 마지막으로 문자가 추가될 때마다 1씩 증가하는 것을 반영하기 위해 word 문자의 개수만큼 추가로 더해 반환한다.

피드백

  • 규칙을 더 빨리 찾았어야 했을 것 같다. 각 자리의 문자가 증가할 때마다 증가하는 수의 규칙을 찾는 데 너무 오랜 시간을 쓴 것 같다.
  • 참고 답안과 같이 AEIOU 맵과 자리수 배열을 reduce 내부로 집어 넣어 조금 더 간결하게 작성할 수 있다.

참고 답안

테스트 통과 시간 메모리
테스트 1 통과 0.04ms 33.6MB
테스트 2 통과 0.04ms 33.4MB
테스트 3 통과 0.05ms 33.4MB
테스트 4 통과 0.04ms 33.5MB
테스트 5 통과 0.06ms 33.4MB
테스트 6 통과 0.04ms 33.5MB
테스트 7 통과 0.05ms 33.4MB
테스트 8 통과 0.05ms 33.5MB
테스트 9 통과 0.04ms 33.4MB
테스트 10 통과 0.04ms 33.4MB
테스트 11 통과 0.04ms 33.1MB
테스트 12 통과 0.04ms 33MB
테스트 13 통과 0.04ms 33.4MB
테스트 14 통과 0.05ms 33.4MB
테스트 15 통과 0.04ms 33.4MB
테스트 16 통과 0.04ms 33.4MB
테스트 17 통과 0.04ms 33.3MB
테스트 18 통과 0.04ms 33.5MB
테스트 19 통과 0.04ms 33MB
테스트 20 통과 0.04ms 33.1MB
테스트 21 통과 0.05ms 33.6MB
테스트 22 통과 0.04ms 33.4MB
테스트 23 통과 0.04ms 33.6MB
테스트 24 통과 0.04ms 33.6MB
테스트 25 통과 0.04ms 33.5MB
테스트 26 통과 0.04ms 33.3MB
테스트 27 통과 0.04ms 33.3MB
테스트 28 통과 0.04ms 33.4MB
테스트 29 통과 0.04ms 33.4MB
테스트 30 통과 0.05ms 33.4MB
테스트 31 통과 0.04ms 33.4MB
테스트 32 통과 0.04ms 33.5MB
테스트 33 통과 0.05ms 33.5MB
테스트 34 통과 0.04ms 33.5MB
테스트 35 통과 0.08ms 33.4MB
테스트 36 통과 0.05ms 33.4MB
테스트 37 통과 0.04ms 33.4MB
테스트 38 통과 0.04ms 33.5MB
테스트 39 통과 0.04ms 33.5MB
테스트 40 통과 0.04ms 33.4MB
function solution(words) {
    return [...words].reduce((a, c, i) => a + "AEIOU".indexOf(c) * [781, 156, 31, 6, 1][i] + 1, 0);
}

아이디어 & 풀이

위의 풀이와 원리는 동일하지만 다음을 사용해 훨씬 더 간결하게 작성했다.

  • 모음 → 숫자를 직접 매핑하는 대신 "AEIOU".indexOf(c)를 사용했다.
  • 자리수 배열 역시 밖에 별도로 선언하지 않고 reduce 내부에 직접 선언했다.
  • 자리가 넘어갈 때마다 1씩 더해주는 걸 word.length를 별도로 더해주는 대신 reduce로 각 문자를 순회할 때마다 1을 추가로 더해주는 것으로 대체했다.

피드백

  • 자리 값이 이전 값에 5를 곱해 1을 더하는 등비수열에 가까우므로 자리 값 배열을 사용하지 않고 Math.trunc(781 / 5 ** i)와 같이 계산해도 된다.