문제
문제: 두 자연수 A와 B가 있을 때, A%B는 A를 B로 나눈 나머지 이다. 예를 들어, 7, 14, 27, 38을 3으로 나눈 나머지는 1, 2, 0, 2이다. 수 10개를 입력받은 뒤, 이를 42로 나눈 나머지를 구한다. 그 다음 서로 다른 값이 몇 개 있는지 출력하는 프로그램을 작성하시오.
입력: 첫째 줄부터 열번째 줄 까지 숫자가 한 줄에 하나씩 주어진다. 이 숫자는 1,000보다 작거나 같고, 음이 아닌 정수이다.
출력: 첫째 줄에, 42로 나누었을 때, 서로 다른 나머지가 몇 개 있는지 출력한다.
예제 입력: 1 또는 42 또는 39
2 84 40
3 252 41
4 420 42
5 840 43
6 126 44
7 42 82
8 84 83
9 420 84
10 126 85
예제 출력: 10 또는 1 또는 6
※ 각 수를 42로 나눈 첫 번째 입력의 나머지는 1, 2, 3, 4, 5, 6, 7, 8, 9, 10이다.
두 번째 입력은 나머지는 0이다.
세 번째 입력은 나머지는 39, 40, 41, 0, 1, 2, 40, 41, 0, 1이다. 서로 다른 값은 6개가 있다.
풀이
const fs = require('fs');
const input = fs.readFileSync(0, "utf-8").trim().split("\n").map(Number);
const a = input.map(num=>num%42);
const b = a.filter((value,index,arr)=>{
return arr.indexOf(value)===index;
});
console.log(b.length);
풀이 해석
1. 입력 받고 숫자로 변환(map(Number))
- 표준 입력( fs.readFileSync(0, "utf-8"))을 이용하여 10개의 숫자를 배열로 저장한다.
- trim().split("\n") → 개행 문자(\n)를 기준으로 분리한다.
- .map(Number) → 문자열을 숫자로 변환한다.
2. map()을 활용해서 42로 나눈 나머지를 구하기(const a = input.map(num => num % 42);)
- 배열의 각 숫자를 42로 나눈 나머지를 새로운 배열로 저장한다.
3. filter()를 사용
- indexOf(value) === index 조건을 사용해 배열에서 중복된 요소를 제거한다.
- length를 출력해서 서로 다른 나머지 개수를 구한다.
★ MDN문서의 filter() 중 callbackFn의 세 번째 인수 사용하기부분 참고!! ★
Array.prototype.filter() - JavaScript | MDN
Array 인스턴스의 filter() 메서드는 주어진 배열의 일부에 대한 얕은 복사본을 생성하고, 주어진 배열에서 제공된 함수에 의해 구현된 테스트를 통과한 요소로만 필터링 합니다.
developer.mozilla.org
더 알아보기
1. 효율적인 방법(Set 사용)★
const fs = require('fs');
const input = fs.readFileSync(0, "utf-8").trim().split("\n").map(Number);
const remainders = input.map(num => num % 42); // 42로 나눈 나머지 계산
const uniqueRemainders = new Set(remainders); // 중복 제거
console.log(uniqueRemainders.size); // 서로 다른 나머지 개수 출력
1. Set을 사용해서 중복 제거(const uniqueRemainders = new Set(remainders);)
- Set은 중복을 자동으로 제거하는 데이터 구조이다.
- remainders 배열에서 중복된 값을 제거하여 유일한 값만 남긴다.
- Set.size를 사용해서 서로 다른 나머지 개수를 출력할 수 있다.
2. 최종 결과 출력(console.log(uniqueRemainders.size);)
- Set.size는 유일한 값의 개수를 반환한다.
2. filter()보다 Set사용을 추천하는 이유
- filter()방식은 배열을 여러 번 순회해야해서 Set보다 성능이 떨어질 수 있다.
- Set사용이 중복제거O(1) 빠르다.
3. map(), for반복문, includes()를 사용한 방법
const fs = require('fs');
const input = fs.readFileSync(0, "utf-8").trim().split("\n").map(Number);
const a = input.map(num => num % 42); // 42로 나눈 나머지 계산
let b = []; // 서로 다른 나머지를 저장할 배열
for (let i = 0; i < a.length; i++) {
if (!b.includes(a[i])) {
b.push(a[i]); // 중복이 아니면 추가
}
}
console.log(b.length); // 서로 다른 나머지 개수 출력
1. for문을 사용해 includes()로 중복을 체크하며 추가한다.
- 중복되지 않은 값만 b배열에 추가한다.
- 중복된 값은 includes()조건에서 걸러진다!
2. 최종 결과 출력
- 서로 다른 나머지 개수를 출력한다.
4. for반복문, includes()를 사용한 방법(map()사용X)
const fs = require('fs');
const input = fs.readFileSync(0, "utf-8").trim().split("\n").map(Number);
let a = [];
for (let i = 0; i < 10; i++) {
let b = input[i] % 42;
if (!a.includes(b)) {
a.push(b);
}
}
console.log(a.length); // 서로 다른 나머지 개수 출력
1. 각 숫자를 42로 나눈 나머지를 구함.
2. a배열에 없는 값만 추가해서 중복을 제거.
3. 최종적으로 a.length를 출력.
'알고리즘 Node.js' 카테고리의 다른 글
백준 1546문제. 평균(스페셜 저지) (0) | 2025.03.13 |
---|---|
백준 10811문제. 바구니 뒤집기 (0) | 2025.03.13 |
백준 5597문제. 과제 안 내신 분..? (0) | 2025.03.12 |
백준 10813문제. 공 바꾸기 (0) | 2025.03.11 |
백준 10810문제. 공 넣기 (0) | 2025.03.11 |