일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 프로그래머스
- 자바스크립트 sort()
- 삼항연산자
- [파이썬 실습] 심화 문제
- [파이썬 실습] 중급 문제
- RN 프로젝트
- 엘리스 AI 트랙 5기
- 자바스크립트 split()
- HTML
- leetcode
- 코드스테이츠
- 엘리스
- 프론트개발
- 프론트개발공부
- 날씨 웹 만들기
- 엘리스 ai 트랙
- 개발공부
- reactnativecli
- [AI 5기] 연습 문제집
- 간단한 날씨 웹 만들기
- 개발일기
- 리트코드
- 자바스크립트 reduce()
- JavaScript
- [파이썬 실습] 기초 문제
- 코딩부트캠프
- 부트캠프
- 자바스크립트
- 자바스크립트 날씨
- 자바스크립트 날씨 웹 만들기
- Today
- Total
개발조각
[프로그래머스] 모음 사전 본문
점점 프로그래머스 힘드네요.😂
문제풀이가 있으면 풀겠는데...
문제를 이해하고 규칙을 정하는 과정까지가 너무 힘들고 어떻게 해야 될지 점점 모르겠습니다.
어렸을 때 수학문제를 풀 때 공식과 개념을 파악하는 것처럼 알고리즘 문제에서도 그런 과정이 필요한가 봐요...
솔직히 문제에 대한 예시도 별로 안 나와있고 이것만 봐서 어떻게 풀라는 거야!!!!!!
질문하기가 없었으면 이걸 풀 수 있긴 했을까 의문이에요...😔
해결방안에 대해 설명하자면
사전에 알파벳 모음 'A', 'E', 'I', 'O', 'U'만을 사용하여 만들 수 있는, 길이 5 이하의 모든 단어가 수록되어 있습니다. 사전에서 첫 번째 단어는 "A"이고, 그다음은 "AA"이며, 마지막 단어는 "UUUUU"입니다.
이 정보를 총 합쳤을 때 경우의 수의 총합은 3905입니다.
경우의 수의 총합 = 5의 1제곱(5) + 5의 2제곱(25) + 5의 3제곱(125) + 5의 4제곱(625) + 5의 5제곱(3125) = 3905
경우의 수의 총합을 가지고 문자열 각 자리마다 얼마씩 더해주면 되는지 확인하면 됩니다.
예를 들어 word의 문자열 길이가 5라고 하면
word문자열의 n번째 자리
- 0번째 : 3905 / 5 = 781
- 1번째 : 3905 / 25 = 156.2 -> 156
- 2번째 : 3905 / 125 = 31.24 -> 31
- 3번째 : 3905 / 5 = 6.248 -> 6
- 4번째 : 3905 / 3125 = 1.2496 -> 1
*여기서 소수점은 다 버림 했습니다.
위에 써둔 word문자열의 n번째가 어디인지
word문자열의 n번째가 [ 'A', 'E', 'I', 'O', 'U' ] 이 5개의 알파벳 중에 무엇인지 확인해주면 됩니다.
- word문자열의 n번째 자리 * [ 'A', 'E', 'I', 'O', 'U' ]에서 해당하는 알파벳 위치 +1
이건 말로 설명하기 애매해서 예시로 설명하겠습니다.
예시)
word = "AAAAE"
- 0번째(A) : word문자열의 0번째 자리 * ([ 'A', 'E', 'I', 'O', 'U' ]에서 해당하는 알파벳 위치) + 1 -> 781*0+1 -> 1
- 1번째(A) : word문자열의 1번째 자리 * ([ 'A', 'E', 'I', 'O', 'U' ]에서 해당하는 알파벳 위치) + 1 -> 156*0+1 -> 1
- 2번째(A) : word문자열의 2번째 자리 * ([ 'A', 'E', 'I', 'O', 'U' ]에서 해당하는 알파벳 위치) + 1 -> 31*0+1 -> 1
- 3번째(A) : word문자열의 3번째 자리 * ([ 'A', 'E', 'I', 'O', 'U' ]에서 해당하는 알파벳 위치) + 1 -> 6*0+1 -> 1
- 4번째(E) : word문자열의 4번째 자리 * ([ 'A', 'E', 'I', 'O', 'U' ]에서 해당하는 알파벳 위치) + 1 -> 1*1+1 -> 2
1+1+1+1+2 = 6
word = "AAAE"
- 0번째(A) : word문자열의 0번째 자리 * ([ 'A', 'E', 'I', 'O', 'U' ]에서 해당하는 알파벳 위치) + 1 -> 781*0+1 -> 1
- 1번째(A) : word문자열의 1번째 자리 * ([ 'A', 'E', 'I', 'O', 'U' ]에서 해당하는 알파벳 위치) + 1 -> 156*0+1 -> 1
- 2번째(A) : word문자열의 2번째 자리 * ([ 'A', 'E', 'I', 'O', 'U' ]에서 해당하는 알파벳 위치) + 1 -> 31*0+1 -> 1
- 3번째(E) : word문자열의 3번째 자리 * ([ 'A', 'E', 'I', 'O', 'U' ]에서 해당하는 알파벳 위치) + 1 -> 6*1+1 -> 7
1+1+1+7 = 10
word = "I"
- 0번째(I) : word문자열의 0번째 자리 * ([ 'A', 'E', 'I', 'O', 'U' ]에서 해당하는 알파벳 위치) + 1 -> 781*2+1 -> 1565
1563
word = "EIO"
- 0번째(E) : word문자열의 0번째 자리 * ([ 'A', 'E', 'I', 'O', 'U' ]에서 해당하는 알파벳 위치) + 1 -> 781*1+1 -> 782
- 1번째(I) : word문자열의 1번째 자리 * ([ 'A', 'E', 'I', 'O', 'U' ]에서 해당하는 알파벳 위치) + 1 -> 156*2+1 -> 313
- 2번째(O) : word문자열의 2번째 자리 * ([ 'A', 'E', 'I', 'O', 'U' ]에서 해당하는 알파벳 위치) + 1 -> 31*3+1 -> 94
E | I | O |
0번째 : 781 | 1번째 : 156 | 2번째 : 31 |
[ 'A', 'E', 'I', 'O', 'U' ]에서 1번째 : 1 | [ 'A', 'E', 'I', 'O', 'U' ]에서 2번째 : 2 | [ 'A', 'E', 'I', 'O', 'U' ]에서 3번째 : 3 |
781*1+1 | 156*2+1 | 31*3+1 |
782 + 313 + 94 = 1189
해결방안 설명을 토대로 코드를 짜면 됩니다.
해결방안
function solution(word) {
// 버전 1
let totalWord = 0;
for(let i=1; i<6; i++) totalWord += Math.pow(5, i);
var answer = 0;
for(let idx = 0; idx< word.length; idx++){
let idxValue = Math.floor(totalWord / Math.pow(5, idx+1))
if(word[idx] === 'A') answer+= 1;
else if(word[idx] === 'E') answer += idxValue +1;
else if(word[idx] === 'I') answer += idxValue*2 +1;
else if(word[idx] === 'O') answer += idxValue*3 +1;
else if(word[idx] === 'U') answer += idxValue*4 +1;
}
return answer;
// 버전 2
return [...word].reduce((acc, cur, idx) => acc + [781, 156, 31, 6, 1][idx] * ['A', 'E', 'I', 'O', 'U'].indexOf(cur) + 1, 0);
}
이번에도 2가지 버전으로 들고 왔습니다.
버전 1은 위에 설명을 정직하게 다 쓴 방법이고요.
버전 2는 위에 설명에서 생략 할 수 있는 것을 생각하고 쓴 방법입니다.
버전 1
// 버전 1
let totalWord = 0;
for(let i=1; i<6; i++) totalWord += Math.pow(5, i);
var answer = 0;
for(let idx = 0; idx< word.length; idx++){
let idxValue = Math.floor(totalWord / Math.pow(5, idx+1))
if(word[idx] === 'A') answer+= 1;
else if(word[idx] === 'E') answer += idxValue +1;
else if(word[idx] === 'I') answer += idxValue*2 +1;
else if(word[idx] === 'O') answer += idxValue*3 +1;
else if(word[idx] === 'U') answer += idxValue*4 +1;
}
return answer;
해결방안 순서
- 경우의 수의 총합을 구해서 totalWord에 담아준다.
- word문자열의 길이만큼 for문으로 돌려준다.
- word문자열이 몇 번째인지, 해당 알파벳이 알파벳 중에서 몇 번째 에인지 따라 값 구해주기
1단계. 경우의 수의 총합을 구해서 totalWord에 담아준다.
let totalWord = 0;
for(let i=1; i<6; i++) totalWord += Math.pow(5, i);
- Math.pow()함수는base^exponent처럼 base 에 exponent를 제곱한 값을 반환합니다.
- Math.pow(base, exponent)
- base : 밑 값.
- exponent : 밑 을 제곱하기 위해 사용하는 지수.
경우의 수의 총합 = 5의 1제곱(5) + 5의 2제곱(25) + 5의 3제곱(125) + 5의 4제곱(625) + 5의 5제곱(3125) = 3905
totalWord = 3905
2단계. word문자열의 길이만큼 for문으로 돌려준다.
for(let idx = 0; idx< word.length; idx++)
3단계. word문자열이 몇 번째인지, 해당 알파벳이 알파벳 중에서 몇 번째 에인지 따라 값 구해주기
let idxValue = Math.floor(totalWord / Math.pow(5, idx+1))
if(word[idx] === 'A') answer+= 1;
else if(word[idx] === 'E') answer += idxValue +1;
else if(word[idx] === 'I') answer += idxValue*2 +1;
else if(word[idx] === 'O') answer += idxValue*3 +1;
else if(word[idx] === 'U') answer += idxValue*4 +1;
- Math.floor() 함수는 주어진 숫자와 같거나 작은 정수 중에서 가장 큰 수를 반환합니다.
- Math.pow()함수는base^exponent처럼 base 에 exponent를 제곱한 값을 반환합니다.
idxValue = 경우의 수의 총합 / 5의 i+1의 제곱 -> word문자열의 n번째 자리
- A는 0을 곱하기 때문에 1이 나올 수밖에 없어서 +1이라고 썼습니다.
버전 2
return [...word].reduce((acc, cur, idx) => acc + [781, 156, 31, 6, 1][idx] * ['A', 'E', 'I', 'O', 'U'].indexOf(cur) + 1, 0);
해결방안 순서
- word문자열을 배열로 만들어준다.
- reduce를 사용한다.
- 배열에 미리 word문자열의 n번째 자리값을 담아주고 idx(현재 인덱스)를 사용하여 word문자열의 n번째 자리를 구한다.
- indexOf와 cur(현재 값)을 사용하여 해당 알파벳이 알파벳 중에서 몇 번째에 있는지 구한다.
- acc(누산기) + 앞에서 구한 word문자열의 n번째 자리* 해당 알파벳이 알파벳중에서 몇번째 + 1을 구해서 답을 리턴한다.
1단계. word문자열을 배열로 만들어준다.
[...word]
스프레드 연산자를 사용하면 문자열을 쉽게 배열로 만들 수 있습니다.
2단계. reduce를 사용한다.
// 버전 2
reduce((acc, cur, idx) => acc + [781, 156, 31, 6, 1][idx] * ['A', 'E', 'I', 'O', 'U'].indexOf(cur) + 1, 0);
1. 배열에 미리 word문자열의 n번째 자리값을 담아주고 idx(현재 인덱스)를 사용하여 word문자열의 n번째 자리를 구한다.
[781, 156, 31, 6, 1][idx]
여기서 [781, 156, 31, 6, 1]을 보시면 무슨 수를 넣었는지 알 수 있을 겁니다.
word문자열의 n번째 자리
- 0번째 : 3905 / 5 = 781
- 1번째 : 3905 / 25 = 156.2 -> 156
- 2번째 : 3905 / 125 = 31.24 -> 31
- 3번째 : 3905 / 5 = 6.248 -> 6
- 4번째 : 3905 / 3125 = 1.2496 -> 1
이 값을 배열로 담아 주었습니다.
idx는 현재 인덱스를 나타낸 값임으로
[781, 156, 31, 6, 1][idx]으로 쓰면 idx가 word배열의 idx가 몇 번째에 따라 word문자열의 n번째 자리를 구하게 됩니다.
2. indexOf와 cur(현재 값)을 사용하여 해당 알파벳이 알파벳 중에서 몇 번째에 있는지 구한다.
['A', 'E', 'I', 'O', 'U'].indexOf(cur)
여기서도 미리 알파벳 순서를 배열로 집어넣고
indexOf()를 사용하여 해당 알파벳이 배열에 몇번째에 위치했는지 구했습니다.
- indexOf() 메서드는 배열에서 지정된 요소를 찾을 수 있는 첫 번째 인덱스를 반환하고 존재하지 않으면 -1을 반환합니다.
여기서 cur(현재 값) 임으로 [ 'A', 'E', 'I', 'O', 'U' ]중 하나일 테고
indexOf(cur)를 하면 각 해당하는 알파벳의 위치를 찾아주게 됩니다.
여기서 참고할 점은
reduce를 쓸 때는 acc+cur일 경우에는 초기값을 안 써도 괜찮지만 변형을 하여 쓰거나 idx까지 쓰면 초기값을 설정해주어야 됩니다.
프로그래머스 모음 사전 해결방안 설명은 여기까지입니다.
'알고리즘🅰 > 프로그래머스' 카테고리의 다른 글
[프로그래머스] 이진 변환 반복하기 (0) | 2022.04.21 |
---|---|
[프로그래머스] 행렬의 곱셈 (0) | 2022.04.21 |
[프로그래머스] 짝지어 제거하기 (0) | 2022.04.18 |
[프로그래머스] [3차] n진수 게임 (0) | 2022.04.17 |
[프로그래머스] 최솟값 만들기 (0) | 2022.04.16 |