Poylib
기록형 프론트엔드
Poylib
전체 방문자
오늘
어제
  • 분류 전체보기 (91)
    • Programing (38)
      • Javascript (17)
      • Typescript (1)
      • React (9)
      • React-Native (6)
      • Git (4)
      • Next (1)
    • Study (36)
      • Algorithm (35)
      • Etc. (1)
    • Record (17)
      • Memoirs (12)
      • Group (5)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • typescript
  • react
  • 리액트
  • 회고
  • 프로그래머스
  • 코칭스터디
  • Git
  • 코딩테스트
  • Object
  • 기초
  • ReactNative
  • react-native
  • Error
  • vite
  • 알고리즘
  • javascript
  • 자바스크립트
  • 백준

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Poylib

기록형 프론트엔드

[BEAKJOON / node.js] 5533 유니크
Study/Algorithm

[BEAKJOON / node.js] 5533 유니크

2022. 5. 2. 15:58
https://www.acmicpc.net/problem/5533

 


삼중 for문으로 배열을 만들어 해결하려 했다. 이중 for문까지는 각 행을 탐색하고, 삼중 for문에서 각 열에 동일한 숫자가 있는지 확인하는 방법이다. 애초에 for문이 삼중으로 들어가는 논리도 아직 낯설뿐더러 scope 지정에서 문제가 생기고 결정적으로 코드가 너무 더러워 보였다,, for문을 최대한 자제하는 방법으로 찾아보았다.

const [n, ...strs] = require('fs').readFileSync('test.txt').toString().trim().split('\n');
const arr = strs.map(str => str.split(' ').map(Number));

let arrMap = Array.from({length : 3})
.map((_,i) => arr
.map((v) => v[i])
.reduce((acc,k) => (acc[k] ? acc[k]+=1 : acc[k]=1, acc),{}));

let answer = arr
.map((arr) => arr
.map((v,i) => arrMap[i][v] === 1 ? v : 0)
.reduce((acc,v) => acc+v),0);

for(let i =0;i<answer.length;i++) {
  console.log(answer[i])
};

 

1. 구조 분해 할당

 처음 input을 받을 때 부터 입력의 첫 번째 요소와 분리한 후 받는다.

const fs = require('fs');
const [n,...strs] = fs.readFileSync('test.txt').toString().trim().split('\n');

console.log(strs) //[ '100 99 98', '100 97 92', '63 89 63', '99 99 99', '89 97 98' ]

2. 각 요소도 배열로 분리

 비교를 위해서 각각 배열에 담아 새로운 배열로 만들어야 한다. split()은 string에만 쓸 수 있기 때문에, 1번의 배열 그대로 사용하면 오류가 발생한다. 따라서 매핑해서 각 요소마다 split() 해주는 식으로 나눠야 한다. split()은 문자열을 나눠 배열로 반환하기 때문에, 바로 map() 메서드 사용이 가능하고 각 배열 요소의 자료형을 숫자로 바꿔준다.

const arrs = strs.map(str => str.split(' ').map(Number));
console.log(arrs)
// [
//   [ 100, 99, 98 ],
//   [ 100, 97, 92 ],
//   [ 63, 89, 63 ],
//   [ 99, 99, 99 ],
//   [ 89, 97, 98 ]
// ]

 

3. 배열을 게임 단위로 정렬하고 객체에 담기

  빈 배열에 각 열의 요소들을 모은다. 첫번째 맵은 인덱스를 제공하기 위한 콜백 함수 이므로 요소 값은 필요 없다(_).  인덱스를 넘겨받은 두 번째 맵의 콜백함수에서 각 열끼리 모은 배열이 완성된다. 즉, 이차원 배열 arr의 가로와 세로를 바꾼 배열이 완성된다. reduce() 메서드를 이용해 중복을 체크한 후 객체로 반환한다. 게임당 객체가 하나 생성될 테고 (3게임, 3객체) n명의 참가자가 있다면 각 객체의 value 합은 n이 된다.

let arrMap = Array.from({length : 3})
.map((_,i) => arr
.map((v) => v[i])	// 여기까지의 과정은 이차원 배열의 가로 세로를 바꾸는 방법이다.
.reduce((acc,k) => (acc[k] ? acc[k]+=1 : acc[k]=1, acc),{}));

console.log(arrMap)

// [
//   { '63': 1, '89': 1, '99': 1, '100': 2 },
//   { '89': 1, '97': 2, '99': 2 },
//   { '63': 1, '92': 1, '98': 2, '99': 1 }
// ]

 

4. 중복된 숫자를 걸러내고, 결과값의 합계 구하기

 첫번째 맵에서 각 요소에 적용할 콜백함수를 정의하고 두 번째 맵에서 객체의 요소가 중복이 없는지 확인한다. 두 번째 맵에서 arrMap [i] 번째 객체를 지정하고, [v]는 객체의 대괄호 표기법으로 키값인 v의 value 값을 가리킨다.

let answer = arr
.map((x) => x
.map((v,i) => arrMap[i][v] === 1 ? v : 0)
.reduce((acc,v) => acc+v),0);
console.log(answer)

//[ 0, 92, 215, 198, 89 ]

5. 요구사항에 맞게 출력

 배열에서 각 요소들을 꺼내도록 for문 작성

for(let i of solution(arrs)) {
  console.log(i)
}
// 0
// 92
// 215
// 198
// 89

 

  • 백준 문제를 node.js 로 풀 때는 입력받는 것부터 난제다.. 각 문제에 맞게 처음부터 입력을 어떻게 받을지 한참 고민해야 한다. 자료를 원하는 모양으로 받고 배열로, 숫자로 바로 바꿀 수 있을 만큼 연습해야겠다.
  • 메서드들의 특징이나, 알맞은 용도에 대해 숙달이 부족했다. split()이 문자열에만 적용되는 줄 몰랐다던지, 객체를 표기할 때 대괄호 표기법을 사용해야만 하는 상황이 있다는 것, new Array와 Array.from()의 차이 등등 꼭 정리하고 넘어가도록 한다. 
  • 함수형 객체지향 언어를 쓰고 있으면 그에 알맞게 써야한다. 활용하지 못하고 기초문법의 반복이나 재선언으로 작성하려 하면 이해하기 어렵고 보기 더러운 코드가 된다.

 

저작자표시 비영리 변경금지 (새창열림)

'Study > Algorithm' 카테고리의 다른 글

<programmers / JavaScript> 로또의 최고 순위와 최저 순위  (0) 2022.05.18
[programmers / JavaScript] K번째 수  (0) 2022.05.06
[programmers / JavaScript] 숫자 문자열과 영단어  (0) 2022.04.30
<BEAKJOON / node.js> 10828 스택  (0) 2022.04.29
<BEAKJOON> 4344 JavaScript  (0) 2022.04.26
    'Study/Algorithm' 카테고리의 다른 글
    • <programmers / JavaScript> 로또의 최고 순위와 최저 순위
    • [programmers / JavaScript] K번째 수
    • [programmers / JavaScript] 숫자 문자열과 영단어
    • <BEAKJOON / node.js> 10828 스택
    Poylib
    Poylib
    모시깽 기록

    티스토리툴바