티스토리 뷰
요즘 노마드 코더로 챌린지를 하면서 백준 문제를 풀고 있다.
(푼 문제들은 깃헙에 올린다. https://github.com/AlgoRoots)
어차피 몇 번 더 풀어볼 생각이라 깃 헙에만 올리고 따로 적지는 않으려고 했는데
그날 푼 문제 중 가장 나에게 유용했던 혹은 새로운 것을 많이 알았던 문제는 정리 겸 올리기로 했다.
오늘의 문제는 4344번이다.
문제
대학생 새내기들의 90%는 자신이 반에서 평균은 넘는다고 생각한다. 당신은 그들에게 슬픈 진실을 알려줘야 한다.
입력
첫째 줄에는 테스트 케이스의 개수 C가 주어진다.
둘째 줄부터 각 테스트 케이스마다 학생의 수 N(1 ≤ N ≤ 1000, N은 정수)이 첫 수로 주어지고, 이어서 N명의 점수가 주어진다. 점수는 0보다 크거나 같고, 100보다 작거나 같은 정수이다.
출력
각 케이스마다 한 줄씩 평균을 넘는 학생들의 비율을 반올림하여 소수점 셋째 자리까지 출력한다.
A. shift(), reduce()를 사용하지 않는 방법
const fs = require("fs");
const filePath = process.platform === "linux" ? "/dev/stdin" : "./input.txt";
let input = fs.readFileSync(filePath).toString().trim().split("\n");
const testCount = +input[0];
const testCases = input.slice(1);
solution(testCount, testCases);
function solution(C, testCases) {
for (let i = 0; i < testCases.length; i++) {
let scores = testCases[i].split(" ").map(Number);
const N = scores[0];
let sum = 0;
let overAverageCnt = 0;
for (let j = 1; j <= N; j++) {
sum += scores[j];
}
const average = sum / N;
for (let k = 1; k <= N; k++) {
if (scores[k] > average) {
overAverageCnt++;
}
}
console.log(((overAverageCnt / N) * 100).toFixed(3) + "%");
}
}
1. 우선 input의 첫번 째 줄을 testCount라 선언하고 숫자로 바꿔 주었다.
그리고 나머지 줄을 slice()를 사용하여 잘라주고 testCases라고 선언하였다.
const testCount = +input[0];
const testCases = input.slice(1);
2. 각 줄의 배열들을 score라고 지정했는데, 그 과정에서 각 줄의 문자를 숫자로 바꾸고, 띄어쓰기 기준으로 나눠주는 과정이 필요했다. 띄어쓰기는 split(" ") 숫자는. map(Number)로 각각의 element를 숫자로 바꿔준다. 각 줄을 실행해야 하기 때문에 for문을 돌려준다.
solution(testCount, testCases);
function solution(C, testCases) {
for (let i = 0; i < testCases.length; i++) {
let scores = testCases[i].split(" ").map(Number);
const N = scores[0];
}
}
그럼 scores가 각 줄에 아래처럼 나열이된다.
Before | After |
[ '5 50 50 70 80 100', '7 100 95 90 80 70 60 50', '3 70 90 80', '3 70 90 81', '9 100 99 98 97 96 95 94 93 91' ] |
[ 5, 50, 50, 70, 80, 100 ] [ 7, 100, 95, 90, 80, 70, 60, 50] [ 3, 70, 90, 80 ] [ 3, 70, 90, 81 ] [ 9, 100, 99, 98, 97, 96, 95, 94, 93, 91] 각 줄의 첫번째 원소를 N 으로 변수를 지정해준다. |
3. 평균을 구하기 위해 각 scores들의 합을 sum, 평균을 넘는 점수를 overAverageCnt이라 선언하고 0으로 초기화해준다.
그리고 각 줄의 점수의 합을 구하는 for문을 적는다. 그럼 합(sum)이 나온다.
for문으로 나온 sum들을 평균을 구하기 위해 상수변수 const average를 선언해 평균을 구한다.
solution(testCount, testCases);
function solution(C, testCases) {
for (let i = 0; i < testCases.length; i++) {
let scores = testCases[i].split(" ").map(Number);
const N = scores[0];
let sum = 0;
let overAverageCnt = 0;
for (let j = 1; j <= N; j++) {
sum += scores[j];
}
const average = sum / N;
// console.log(scores);
// console.log("sum: ", sum);
// console.log("average: ", average);
}
헷갈리면 console.log();를 출력해가며 본다.
4. 평균을 넘는 점수들을 구하고 있으면 overAverageCnt값을 1씩 증가시킨다.
solution(testCount, testCases);
function solution(C, testCases) {
for (let i = 0; i < testCases.length; i++) {
let scores = testCases[i].split(" ").map(Number);
const N = scores[0];
let sum = 0;
let overAverageCnt = 0;
for (let j = 1; j <= N; j++) {
sum += scores[j];
}
const average = sum / N;
for (let k = 1; k <= N; k++) {
if (scores[k] > average) {
overAverageCnt++;
}
}
}
}
5. overAverageCnt를 %로 나타내기 위해 수식을 집어넣고 콘솔에 출력해준다.
** 마지막에 평군을 소수점 셋째 자리까지 끊어야 하는데 이는 toFixed()를 사용하면 된다.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed
solution(testCount, testCases);
function solution(C, testCases) {
for (let i = 0; i < testCases.length; i++) {
let scores = testCases[i].split(" ").map(Number);
const N = scores[0];
let sum = 0;
let overAverageCnt = 0;
for (let j = 1; j <= N; j++) {
sum += scores[j];
}
const average = sum / N;
for (let k = 1; k <= N; k++) {
if (scores[k] > average) {
overAverageCnt++;
}
}
console.log(((overAverageCnt / N) * 100).toFixed(3) + "%");
}
}
B. shift(), reduce()를 사용한 방법
shift() 는 배열의 첫 번째 요소를 제거해주면서 그 요소를 리턴해준다.
sores [0]의 값은 score.shift(); 한 값과 같다.
reduce() 메서드는 각 요소를 순회하며 callback함수의 실행 값을 누적하여 하나의 결괏값을 반환한다.
찾아보니 보통 reduce() 가르칠 때 모든 요소의 합을 구할 때로 많이 예를 드시는 것 같다.
하지만 이 함수로 요소의 중복 횟구나 평균, 중복요소 제거 등 더 많은 일을 할 수가 있다.
이 함수는 나중에 따로 포스팅하겠다.
아무튼, reduce()는 4개의 인수를 가진다.
- accumulator(previousValue) - accumulator는 callback함수의 반환값을 누적 (콜백이 첫 번째 호출이면서 초기값을 제공하는 경우에는 초기값이 accumulator가 된다.)
- currentValue - 배열의 현재 요소
- index(Optional) - 배열의 현재 요소의 인덱스 (초기값을 제공한 경우에 0, 아니면 1부터 시작한다)
- array(Optional) - reduce()를 호출한 배열
3 번에 하이라이트 부분은 이 메서드의 기능을 찾아보며 헷갈렸던 부분이었다. 다음에 쓸 때도 잊지 말고 꼭 써야겠다.
reduce()는 초기값을 제공하지 않으면 index가 1부터 시작한다. 즉 첫 번째 index 0을 건너뛴다는 말이다.
나는 scores를 index 0자리부터 testcase의 length개수까지 합해야 했다. 따라서 reduce()에 index인자를 넣어 초기값을 설정해주는 과정이 들어가야 한다.
sum = scores.reduce((acc, cur) => acc + cur, 0 );
참고로 mdn에서도 초기값을 제공하지 않을 시에 출력 가능한 형식이 여러개가 되므로 초기값을 제공하는 편이 더 안전하다고 한다.
const fs = require("fs");
const filePath = process.platform === "linux" ? "/dev/stdin" : "./input.txt";
let input = fs.readFileSync(filePath).toString().trim().split("\n");
const testCount = +input[0];
const testCases = input.slice(1);
solution(testCount, testCases);
function solution(C, testCases) {
for (let i = 0; i < testCases.length; i++) {
let scores = testCases[i].split(" ").map(Number);
const N = scores.shift();
let sum = 0;
let overAverageCnt = 0;
sum = scores.reduce((acc, cur) => acc + cur, 0);
const average = sum / N;
for (let k = 1; k <= N; k++) {
if (scores[k] > average) {
overAverageCnt++;
}
}
console.log(((overAverageCnt / N) * 100).toFixed(3) + "%");
}
}
Reference link : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
'알고리즘 > 백준-BACKJOON' 카테고리의 다른 글
[백준] 1966번 프린터큐 - 파이썬 python (0) | 2022.03.15 |
---|---|
[백준] 4673번- 자바스크립트(Javascript) | 콘솔 출력하면서 이해하는 백준 문제 풀이 (0) | 2022.02.11 |
[백준] Javascript 백준 공부법 (0) | 2022.01.11 |
- Total
- Today
- Yesterday
- 타입스크립트
- 무한스크롤
- 프로그래머스
- github
- 알고리즘자바스크립트
- 프로그래머스 자바스크립트
- React
- 모두를 위한 컴퓨터 과학
- 네트워크
- python
- 모두를위한컴퓨터과학
- css
- 자바스크립트 클로저
- 자바스크립트
- 자바스크립트알고리즘
- 프로그래머스 베스트앨범 자바스크립트
- 자바스크립트 비동기 처리
- 클로저
- html
- javascript
- network
- 리액트네이티브
- reactquery
- GIT
- 백준
- 실전프로젝트
- cs50
- 리액트
- 항해99
- React Query
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |