일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
- ESLint
- dp
- notion
- react
- webpack
- 백준
- 1003
- 발자취
- 코딩테스트
- DFS
- 접근법
- spring
- Prettier
- 완전탐색
- java
- vsCode
- 다이나믹프로그래밍
- 개발상식
- 면접
- 현파랑
- CONVERTER
- 알고리즘
- 패스트캠퍼스
- js
- 프로그래멋
- 동적계획법
- IT-Note
- spring-mvc
- BFS
- Notion to Github Markdown
- Today
- Total
두 번째 뇌
[JS] 완전탐색(brute-force) : 자릿수의 합 본문
개요
생각치도 못한 부분에서 틀려버렸습니다... 2중 loop를 돌긴 하지만, 숫자를 효율적으로 사용하지 못해 예상 테스트 케이스도 깨지 못해서 강의를 보았더니... 훨씬 좋은 내용이 있네요. 다시 풀어봐야겠습니다.
문제
N개의 자연수가 입력되면 각 자연수의 자릿수의 합을 구하고, 그 합이 최대인 자연수를 출력하는 프로그램을 작성하라.
자릿수의 합이 같은 경우 원래 숫자가 큰 숫자를 답으로 한다.
만약 235와 1234가 동시에 답이 될 수 있다면 1234를 답으로 출력한다.
▣ 입력설명
첫 줄에 N(3<=N<=100)개의 자연수가 주어진다.
각 자연수의 크기는 10,000,000를 넘지 않는다.
▣ 출력설명
자릿수의 합이 최대인 자연수를 출력한다.
▣ 입력예제 1
128 460 603 40 521 137 123
▣ 출력예제 1
137
코드
🤐 : 최초 작성, 틀린 코드
function solution(arr) {
let answer = Number.MIN_SAFE_INTEGER;
// 문자열 배열로
arr = arr.map(String);
let originItem = Number.MIN_SAFE_INTEGER;
for (let item of arr) {
let sum = 0;
for (let i = 0; i < item.length; i++) {
sum += Number(item[i]);
}
if (answer < sum) {
answer = sum;
originItem = item;
} else if (answer === sum) {
answer = originItem <= Number(item) ? Number(item) : originItem;
originItem = item;
}
}
return answer;
}
// 테스트
describe('자리수의 합', () => {
it('기본 테스트 케이스1', () => {
let arr = [128, 460, 603, 40, 521, 137, 123];
expect(solution(arr)).toEqual(137);
}); // passed
it('기본 테스트 케이스2', () => {
let arr = [460, 603, 40, 521, 127, 123, 235, 1234];
expect(solution(arr)).toEqual(1234);
}); // failed, 460이 나옴
});
- 주어진 배열의 원소를 full-scan 하는 형태로 짰는데, 효율성은 고사하고 정확도도 맞지 않습니다.
- 형변환을 어거지로 두 번 실행하는 것도 비효율적이고, 테스트 케이스2에서 460을 반환하면서 끝나버립니다.
🤩 : 반복 풀이하기
function solution(n, arr) {
let answer = Number.MIN_SAFE_INTEGER;
let max = Number.MIN_SAFE_INTEGER;
for (let item of arr) {
let sum = 0;
let temp = item;
/**
* temp temp % 10
* 128 8
* 12 2
* 1 1
* 0 break
*/
while (temp) {
sum += temp % 10;
temp = Math.floor(temp / 10);
}
if (sum > max) {
max = sum;
answer = item;
} else if (sum === max && item > answer) {
answer = item;
}
}
return answer;
}
// 테스트
describe('자리수의 합', () => {
it('기본 테스트 케이스1', () => {
let arr = [128, 460, 603, 40, 521, 137, 123];
expect(solution(7, arr)).toEqual(137);
}); // passed
it('기본 테스트 케이스2', () => {
let arr = [460, 603, 40, 521, 127, 123, 235, 1234];
expect(solution(7, arr)).toEqual(1234);
}); // passed
});
- 가장 큰 차이점은 각 자릿수를 10으로 나누어 나머지끼리 더하는 부분입니다. 코드가 더 깔끔해지고 가독성도 좋네요.
- 이 코드를 내장 함수를 사용하여 조금 더 줄여보자면...
😎 : 코드 줄이기
function solution(n, arr) {
let answer = Number.MIN_SAFE_INTEGER;
let max = Number.MIN_SAFE_INTEGER;
for (let item of arr) {
// while문을 변형
let sum = item.toString().split('').reduce((a, b) => a + Number(b), 0);
if (sum > max) {
max = sum;
answer = item;
} else if (sum === max && item > answer) {
answer = item;
}
}
return answer;
}
- reduce를 사용하여 각 자릿수의 값을 더해줍니다. 결과는 위와 같습니다.
생각해야 할 것
주어진 배열을 처리할 때, 배열이 가진 원소의 타입에 따라 어떻게 로직을 처리할 건지 많은 선택지를 염두에 두고 있어야 합니다. 무작정 코드를 짜려고 하니 이렇게 허점이 보이네요. 개선해야겠습니다.
'개발자 지식 > Algorithm' 카테고리의 다른 글
[ Python ] 1003번 피보나치 함수 (0) | 2021.08.01 |
---|---|
[ Python ] BOJ 단계별 풀어보기 - 동적계획법 1 (0) | 2021.07.31 |
[ Python ] BOJ 단계별 풀어보기 - 문자열 (0) | 2021.07.31 |
[JS] DFS : 거리 두기 확인하기(2021 카카오 인턴십) (0) | 2021.07.09 |
[JS] 투 포인터(Two-Pointers) : 연속 부분수열 (0) | 2021.07.04 |