문제 설명
1부터 6까지 숫자가 적힌 주사위가 네 개 있습니다. 네 주사위를 굴렸을 때 나온 숫자에 따라 다음과 같은 점수를 얻습니다.
- 네 주사위에서 나온 숫자가 모두 p로 같다면 1111 × p점을 얻습니다.
- 세 주사위에서 나온 숫자가 p로 같고 나머지 다른 주사위에서 나온 숫자가 q(p ≠ q)라면 (10 × p + q)2 점을 얻습니다.
- 주사위가 두 개씩 같은 값이 나오고, 나온 숫자를 각각 p, q(p ≠ q)라고 한다면 (p + q) × |p - q|점을 얻습니다.
- 어느 두 주사위에서 나온 숫자가 p로 같고 나머지 두 주사위에서 나온 숫자가 각각 p와 다른 q, r(q ≠ r)이라면 q × r점을 얻습니다.
- 네 주사위에 적힌 숫자가 모두 다르다면 나온 숫자 중 가장 작은 숫자 만큼의 점수를 얻습니다.
네 주사위를 굴렸을 때 나온 숫자가 정수 매개변수 a, b, c, d로 주어질 때, 얻는 점수를 return 하는 solution 함수를 작성해 주세요.
제한사항
- a, b, c, d는 1 이상 6 이하의 정수입니다.
입출력 예
a | b | c | d | result |
2 | 2 | 2 | 2 | 2222 |
4 | 1 | 4 | 4 | 1681 |
6 | 3 | 3 | 6 | 27 |
2 | 5 | 2 | 6 | 30 |
6 | 4 | 2 | 5 | 2 |
입출력 예 설명
입출력 예 #1
- 예제 1번에서 네 주사위 숫자가 모두 2로 같으므로 1111 × 2 = 2222점을 얻습니다. 따라서 2222를 return 합니다.
입출력 예 #2
- 예제 2번에서 세 주사위에서 나온 숫자가 4로 같고 나머지 다른 주사위에서 나온 숫자가 1이므로 (10 × 4 + 1)2 = 412 = 1681점을 얻습니다. 따라서 1681을 return 합니다.
입출력 예 #3
- 예제 3번에서 a, d는 6으로, b, c는 3으로 각각 같으므로 (6 + 3) × |6 - 3| = 9 × 3 = 27점을 얻습니다. 따라서 27을 return 합니다.
입출력 예 #4
- 예제 4번에서 두 주사위에서 2가 나오고 나머지 다른 두 주사위에서 각각 5, 6이 나왔으므로 5 × 6 = 30점을 얻습니다. 따라서 30을 return 합니다.
입출력 예 #5
- 예제 5번에서 네 주사위 숫자가 모두 다르고 나온 숫자 중 가장 작은 숫자가 2이므로 2점을 얻습니다. 따라서 2를 return 합니다.
나의 접근 방법
1. Map을 사용해서 a,b,c,d 에 대한 개수를 key, value 형식으로 담는다.
- (2=>4 : 2가 나온 주사위가 4개)
- (4=>3, 1=>1, 4가 나온 주사위 3개, 1이 나온 주사위 3개)
2. 4개의 주사위 값이 모두 같을 때, 3개의 주사위 값이 같고 1개가 다를때 이렇게 케이스를 분기로 조건문으로 처리한다.
(2개 주사위가 같고 다른 2개가 같을때, 2개 주사위가 같고 각각 다른 1개씩 주사위)
나의 JS 코드
function solution(a, b, c, d) {
const map = new Map();// key: 주사위값, value: 나온 숫자
[a, b, c, d].forEach((num) =>
map.set(num, map.has(num) ? map.get(num) + 1 : 1)
);
const arr = Array.from(map);// [[주사위값, 나온 숫자]...]
// 네 주사위에서 나온 숫자가 모두 p로 같다면 1111 x p점
if (arr.length === 1) {
answer = 1111 * arr[0][0];
} else if (arr.length === 2) {
let p = 0,
q = 0,
r = 0,
s = 0;
arr.forEach(([key, value]) => {
if (value === 2) {
// 두 개씩 같은 값이 나오고, 나온 숫자를 p,q라고하면
// (p + q) * ㅣp -qㅣ
if (r === 0) r = key;
else s = key;
} else {
// 세 주사위에서 나온 숫자가 p로 같고
// 나머지 다른 주사위 나온 숫자가 q라면 (10 x p + q)2
if (value === 3) {
p = key;
} else if (value === 1) {
q = key;
}
}
});
if (r === 0) answer = Math.pow(10 * p + q, 2);
else answer = (r + s) * Math.abs(r - s);
} else if (arr.length === 3) {
let p = 0,
q = 0,
r = 0;
arr.forEach(([key, value]) => {
if (value === 2) p = key;
else if (value === 1 && q === 0) q = key;
else r = key;
});
answer = q * r;
} else {
let [min] = Array.from(map.keys()).sort((a, b) => a - b);
answer = min;
}
return answer;
}
개선할 포인트
1. 코드 중복 제거: arr 배열을 forEach로 순회하면서 같은 로직을 반복하는 부분이 있습니다. 이를 함수로 분리하거나 조건에 맞는 값을 한 번만 추출하도록 개선할 수 있습니다.
2. 조건문 최적화: 값의 빈도에 따라 점수를 계산하는 과정에서 다소 복잡한 조건문이 많습니다. 이 부분을 좀 더 직관적이고 효율적으로 바꿀 수 있습니다.
3. Map을 Object로 대체: Map 대신 객체를 사용하는 것이 메모리 효율성 면에서 유리할 수 있습니다. 물론, Map은 삽입 순서를 보장하지만, 여기서는 순서가 중요하지 않으므로 객체로도 충분히 처리할 수 있습니다.
개선 된 코드
function solution(a, b, c, d) {
const counts = [a, b, c, d].reduce((acc, num) => {
acc[num] = (acc[num] || 0) + 1;
return acc;
}, {});
const uniqueValues = Object.entries(counts);
// 4개의 주사위 값이 모두 같을 때
if (uniqueValues.length === 1) {
return 1111 * uniqueValues[0][0];
}
// 같은 주사위 3개-나머지1개 인 경우, 같은 주사위 2개-2개 인 경우
if (uniqueValues.length === 2) {
let [p, q] = [0, 0];
uniqueValues.forEach(([key, value]) => {
// key를 숫자로 변환하여 계산
const numKey = Number(key); // 문자열을 숫자로 변환
if (value === 3) {
p = numKey;
} else if (value === 1) {
q = numKey;
}
});
if (p) {
return Math.pow(10 * p + q, 2);
}
// (p + q) * |p - q|
let [r, s] = uniqueValues.map(([key]) => Number(key));
return (r + s) * Math.abs(r - s);
}
// 3개의 주사위 값이 같고, 하나는 다른 값일 때
if (uniqueValues.length === 3) {
let p = 0, q = 0, r = 0;
uniqueValues.forEach(([key, value]) => {
if (value === 2) p = key;
if (value === 1) q = key;
if (value === 1 && r === 0) r = key;
});
return q * r;
}
// 4개의 주사위 값이 모두 다를 때
return Math.min(...Object.keys(counts).map(Number));
}
속도 체크
크게 차이는 없지만, 33,34번 케이스에서 차이가 있다.
케이스 | 개선 전 | 개선 후 |
테스트 1 〉 | 통과 (0.15ms, 33.5MB) | 통과 (0.14ms, 33.4MB) |
테스트 2 〉 | 통과 (0.15ms, 33.4MB) | 통과 (0.15ms, 33.5MB) |
테스트 3 〉 | 통과 (0.15ms, 33.5MB) | 통과 (0.14ms, 33.5MB) |
테스트 4 〉 | 통과 (0.15ms, 33.4MB) | 통과 (0.13ms, 33.4MB) |
테스트 5 〉 | 통과 (0.14ms, 33.4MB) | 통과 (0.13ms, 33.5MB) |
테스트 6 〉 | 통과 (0.15ms, 33.4MB) | 통과 (0.14ms, 33.5MB) |
테스트 7 〉 | 통과 (0.15ms, 33.4MB) | 통과 (0.13ms, 33.5MB) |
테스트 8 〉 | 통과 (0.14ms, 33.4MB) | 통과 (0.13ms, 33.3MB) |
테스트 9 〉 | 통과 (0.14ms, 33.6MB) | 통과 (0.14ms, 33.5MB) |
테스트 10 〉 | 통과 (0.16ms, 33.5MB) | 통과 (0.13ms, 33.5MB) |
테스트 11 〉 | 통과 (0.16ms, 33.4MB) | 통과 (0.13ms, 33.4MB) |
테스트 12 〉 | 통과 (0.16ms, 33.5MB) | 통과 (0.14ms, 33.5MB) |
테스트 13 〉 | 통과 (0.13ms, 33.5MB) | 통과 (0.11ms, 33.4MB) |
테스트 14 〉 | 통과 (0.15ms, 33.4MB) | 통과 (0.14ms, 33.5MB) |
테스트 15 〉 | 통과 (0.14ms, 33.6MB) | 통과 (0.15ms, 33.4MB) |
테스트 16 〉 | 통과 (0.15ms, 33.5MB) | 통과 (0.15ms, 33.4MB) |
테스트 17 〉 | 통과 (0.13ms, 33.4MB) | 통과 (0.11ms, 33.3MB) |
테스트 18 〉 | 통과 (0.15ms, 33.6MB) | 통과 (0.15ms, 33.5MB) |
테스트 19 〉 | 통과 (0.14ms, 33.6MB) | 통과 (0.15ms, 33.5MB) |
테스트 20 〉 | 통과 (0.13ms, 33.4MB) | 통과 (0.12ms, 33.4MB) |
테스트 21 〉 | 통과 (0.14ms, 33.5MB) | 통과 (0.14ms, 33.4MB) |
테스트 22 〉 | 통과 (0.14ms, 33.6MB) | 통과 (0.14ms, 33.5MB) |
테스트 23 〉 | 통과 (0.13ms, 33.5MB) | 통과 (0.11ms, 33.4MB) |
테스트 24 〉 | 통과 (0.14ms, 33.5MB) | 통과 (0.16ms, 33.4MB) |
테스트 25 〉 | 통과 (0.14ms, 33.4MB) | 통과 (0.24ms, 33.5MB) |
테스트 26 〉 | 통과 (0.15ms, 33.4MB) | 통과 (0.13ms, 33.6MB) |
테스트 27 〉 | 통과 (0.14ms, 33.5MB) | 통과 (0.14ms, 33.5MB) |
테스트 28 〉 | 통과 (0.15ms, 33.4MB) | 통과 (0.13ms, 33.4MB) |
테스트 29 〉 | 통과 (0.14ms, 33.4MB) | 통과 (0.14ms, 33.5MB) |
테스트 30 〉 | 통과 (0.14ms, 33.5MB) | 통과 (0.24ms, 33.5MB) |
테스트 31 〉 | 통과 (0.14ms, 33.5MB) | 통과 (0.13ms, 33.5MB) |
테스트 32 〉 | 통과 (0.15ms, 33.5MB) | 통과 (0.14ms, 33.6MB) |
테스트 33 〉 | 통과 (2.36ms, 33.5MB) | 통과 (0.11ms, 33.5MB) |
테스트 34 〉 | 통과 (2.57ms, 33.6MB) | 통과 (0.11ms, 33.5MB) |
테스트 35 〉 | 통과 (0.13ms, 33.5MB) | 통과 (0.11ms, 33.6MB) |
테스트 36 〉 | 통과 (0.14ms, 33.4MB) | 통과 (0.13ms, 33.6MB) |
테스트 37 〉 | 통과 (0.15ms, 33.4MB) | 통과 (0.13ms, 33.6MB) |
테스트 38 〉 | 통과 (0.15ms, 33.4MB) | 통과 (0.14ms, 33.4MB) |
테스트 39 〉 | 통과 (0.14ms, 33.4MB) | 통과 (0.23ms, 33.4MB) |
테스트 40 〉 | 통과 (0.15ms, 33.5MB) | 통과 (0.15ms, 33.4MB) |
테스트 41 〉 | 통과 (0.14ms, 33.5MB) | 통과 (0.14ms, 33.5MB) |
테스트 42 〉 | 통과 (0.14ms, 33.5MB) | 통과 (0.14ms, 33.6MB) |
'Algorithm > Programmers' 카테고리의 다른 글
[프로그래머스] 연습문제 / 마법의 엘리베이터 / Lv2 / JS / 접근법 (0) | 2024.11.24 |
---|---|
[프로그래머스] 연습문제 / 달리기 경주 / Lv1 / JS / 접근법 (0) | 2024.11.23 |
[프로그래머스] 연습문제 / 콜라 문제 / Lv1 / JS / 탐욕알고리즘 (0) | 2024.11.23 |
[프로그래머스] 연습문제 / 삼총사 / Lv1 / JS (0) | 2024.11.21 |
[프로그래머스] 연습문제 / 크기가 작은 부분 문자열 / Lv1 / JS (0) | 2024.11.20 |