본문 바로가기
알고리즘 Node.js

백준 3052문제. 나머지

by 반갑조? 2025. 3. 12.

문제

문제: 두 자연수 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의 세 번째 인수 사용하기부분 참고!!

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/filter#callbackfn%EC%9D%98_%EC%84%B8_%EB%B2%88%EC%A7%B8_%EC%9D%B8%EC%88%98_%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0

 

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를 출력.