티스토리 뷰

1. 최소,최대

https://www.acmicpc.net/problem/10818

문제

최소, 최대

문제
N개의 정수가 주어진다. 이때, 최솟값과 최댓값을 구하는 프로그램을 작성하시오.

입력
첫째 줄에 정수의 개수 N (1 ≤ N ≤ 1,000,000)이 주어진다. 둘째 줄에는 N개의 정수를 공백으로 구분해서 주어진다. 모든 정수는 -1,000,000보다 크거나 같고, 1,000,000보다 작거나 같은 정수이다.

출력
첫째 줄에 주어진 정수 N개의 최솟값과 최댓값을 공백으로 구분해 출력한다.

예제 입력 1
5
20 10 35 30 7

예제 출력 1
7 35

해답

const fs = require("fs");

const inputData = fs
  .readFileSync(
    process.platform === "linux" ? "/dev/stdin" : "../../../../index.txt"
  )
  .toString()
  .split("\n");

const data = inputData[1].split(" ").map((value) => +value);
const maximum = Math.max(...data);
const minimum = Math.min(...data);

console.log(minimum, maximum);

풀이

inputData (입력값)

파일 읽어오기
const fs = require("fs");

const inputData = fs.readFileSync(
  process.platform === "linux" ? "/dev/stdin" : "../../../../index.txt"
);

console.log(inputData); // <Buffer 35 0a 32 30 20 31 30 20 33 35 20 33 30 20 37>
readFileSync()

백준에서 추천하는 방식은 node.js에서 fs 모듈의 readFileSync()를 이용하는 것입니다.

작동 시스템 구별
process.platform === "linux" ? "/dev/stdin" : "../../../../index.txt";
process.platform

process.platform"linux"인 경우 경로를 "/dev/stdin"으로 향하게 하고 그것이 아니면 사용자가 지정한 파일을 향하게 합니다.

문자열 형식으로 변환
const inputData = fs
  .readFileSync(
    process.platform === "linux" ? "/dev/stdin" : "../../../../index.txt"
  )
  .toString();

console.log(inputData);
// 5
// 20 10 35 30 7
toString()

Buffer 형식으로 출력된 값을 toString()을 통해 기본값인 "utf8" 형식으로 출력합니다.

배열 생성
const inputData = fs
  .readFileSync(
    process.platform === "linux" ? "/dev/stdin" : "../../../../index.txt"
  )
  .toString()
  .trim()
  .split("\n");

console.log(inputData); // [ '5', '20 10 35 30 7' ]
split()

split()을 활용하여 매개변수에 다음줄을 의미하는 "\n"를 넣어 배열을 만듭니다.

data (N개의 정수에 대한 배열)

const data = inputData[1].split(" ").map((value) => +value);
N개의 정수에 대한 배열 생성
const data = inputData[1].split(" ");

console.log(data); // [ '20', '10', '35', '30', '7' ]
split()

N개의 정수에 해당하는 요소인 inputData[1]split()에 공백을 의미하는 " "을 매개변수로 넣어 N개의 정수에 대한 배열을 생성합니다.

배열 형식 숫자로 변환
const data = inputData[1].split(" ").map((value) => +value);

console.log(data); // [ 20, 10, 35, 30, 7 ]
map()

생성된 배열의 형식은 문자열입니다. 배열의 형식을 숫자 형식으로 변환하기 위해 map() 메서드를 활용하여 매개변수 callback 함수를 (value) => +value로 하여 모든 배열내의 요소가 숫자 형식으로 변환되게 합니다.

maximun (최댓값)

const maximum = Math.max(...data);

console.log(maximun); // 35
최댓값 반환
Math.max()

Math.max() 함수를 통해 최댓값을 반환합니다.

전개 구문
const maximum1 = Math.max(...data);
console.log(maximum1); // 35

const maximum2 = Math.max(20, 10, 35, 30, 7);
console.log(maximum2); // 35

// maximum1과 maximum2 모두 같다.

Math.max() 함수 내에 매개변수로 전개 구문을 활용해 배열 내 요소...data로 넣습니다.

minimum (최솟값)

const minimum = Math.min(...data);

console.log(minimum); // 7
최솟값 반환
Math.min()

Math.min() 함수를 통해 최솟값을 반환합니다.

전개 구문
const minimum1 = Math.min(...data);
console.log(minimum1); // 7

const minimum2 = Math.max(20, 10, 35, 30, 7);
console.log(minimum2); // 7

// minimum1과 minimum2 모두 같다.

Math.min() 함수 내에 매개변수로 전개 구문을 활용해 배열 내 요소...data로 넣습니다.

결과값 출력하기

console.log(minimum, maximum); // 7 35
console.log()

console.log() 메서드를 통해 minimummaximum을 출력합니다.

2. 최댓값

https://www.acmicpc.net/problem/2562

문제

최댓값

문제
9개의 서로 다른 자연수가 주어질 때, 이들 중 최댓값을 찾고 그 최댓값이 몇 번째 수인지를 구하는 프로그램을 작성하시오.

예를 들어, 서로 다른 9개의 자연수

3, 29, 38, 12, 57, 74, 40, 85, 61

이 주어지면, 이들 중 최댓값은 85이고, 이 값은 8번째 수이다.

입력
첫째 줄부터 아홉 번째 줄까지 한 줄에 하나의 자연수가 주어진다. 주어지는 자연수는 100 보다 작다.

출력
첫째 줄에 최댓값을 출력하고, 둘째 줄에 최댓값이 몇 번째 수인지를 출력한다.

예제 입력 1
3
29
38
12
57
74
40
85
61

예제 출력 1
85
8

해답

const fs = require("fs");

const inputData = fs
  .readFileSync(process.platform === "linux" ? "/dev/stdin" : "src/index.txt")
  .toString()
  .split("\n")
  .map((value) => +value);

const maximum = Math.max(...inputData);
const index = inputData.findIndex((value) => value === maximum) + 1;

console.log(`${maximum}
${index}`);

풀이

inputData (입력값)

파일 읽어오기
const fs = require("fs");

const inputData = fs.readFileSync(
  process.platform === "linux" ? "/dev/stdin" : "../../../../index.txt"
);

console.log(inputData); // <Buffer 33 0a 32 39 0a 33 38 0a 31 32 0a 35 37 0a 37 34 0a 34 30 0a 38 35 0a 36 31>
readFileSync()

백준에서 추천하는 방식은 node.js에서 fs 모듈의 readFileSync()를 이용하는 것입니다.

작동 시스템 구별
process.platform === "linux" ? "/dev/stdin" : "../../../../index.txt";
process.platform

process.platform"linux"인 경우 경로를 "/dev/stdin"으로 향하게 하고 그것이 아니면 사용자가 지정한 파일을 향하게 합니다.

문자열 형식으로 변환
const inputData = fs
  .readFileSync(
    process.platform === "linux" ? "/dev/stdin" : "../../../../index.txt"
  )
  .toString();

console.log(inputData);
// 3
// 29
// 38
// 12
// 57
// 74
// 40
// 85
// 61
toString()

Buffer 형식으로 출력된 값을 toString()을 통해 기본값인 "utf8" 형식으로 출력합니다.

배열 생성
const inputData = fs
  .readFileSync(
    process.platform === "linux" ? "/dev/stdin" : "../../../../index.txt"
  )
  .toString()
  .split("\n");

console.log(inputData);
// [
//   '3',  '29', '38',
//   '12', '57', '74',
//   '40', '85', '61'
// ]
split()

split()을 활용하여 매개변수에 다음줄을 의미하는 "\n"를 넣어 배열을 만듭니다.

배열 형식 변환
const fs = require("fs");

const inputData = fs
  .readFileSync(
    process.platform === "linux" ? "/dev/stdin" : "../../../../index.txt"
  )
  .toString()
  .split("\n")
  .map((value) => +value);

console.log(inputData);
// [
//    3, 29, 38, 12, 57,
//   74, 40, 85, 61
// ]
map()

생성된 배열의 형식은 문자열입니다. 배열의 형식을 숫자 형식으로 변환하기 위해 map() 메서드를 활용하여 매개변수 callback 함수를 (value) => +value로 하여 모든 배열 내부의 요소가 숫자 형식으로 변환되게 합니다.

maximun (최댓값)

const maximum = Math.max(...inputData);

console.log(maximun); // 85
최댓값 반환
Math.max()

Math.max() 함수를 통해 최댓값을 반환합니다.

전개 구문
const maximum1 = Math.max(...inputData);
console.log(maximum1); // 85

const maximum2 = Math.max(3, 29, 38, 12, 57, 74, 40, 85, 61);
console.log(maximum2); // 85

// maximum1과 maximum2 모두 같다.

Math.max() 함수 내에 매개변수로 전개 구문을 활용해 배열 내 요소inputData로 넣습니다.

index (최댓값 배열의 위치)

const index = inputData.findIndex((value) => value === maximum) + 1;

console.log(index); // 8
배열에서 최댓값 index 위치 찾기
findIndex

inputData 배열에서 매개변수로 (value) => value === maximum배열의 각 요소를 순환하며 최댓값과 일치하는 요소를 찾는 callback 함수를 가지는 findIndex 메서드를 통해 최댓값에 해당하는 index를 찾습니다.

배열의 요소들은 처음 시작할 떄 index0을 가집니다. 시작하는 배열의 index1 이어야함으로 1을 더해줍니다.

결과값 출력하기

console.log(`${maximum}
${index}`);
// 85
// 8
console.log()

console.log() 메서드를 통해 Templete literals을 활용하여 maximumindex를 줄바꿈을 하여 출력합니다.

3. 숫자의 개수

https://www.acmicpc.net/problem/2577

문제

숫자의 개수

문제
세 개의 자연수 A, B, C가 주어질 때 A × B × C를 계산한 결과에 0부터 9까지 각각의 숫자가 몇 번씩 쓰였는지를 구하는 프로그램을 작성하시오.

예를 들어 A = 150, B = 266, C = 427 이라면 A × B × C = 150 × 266 × 427 = 17037300 이 되고, 계산한 결과 17037300 에는 0이 3번, 1이 1번, 3이 2번, 7이 2번 쓰였다.

입력
첫째 줄에 A, 둘째 줄에 B, 셋째 줄에 C가 주어진다. A, B, C는 모두 100보다 크거나 같고, 1,000보다 작은 자연수이다.

출력
첫째 줄에는 A × B × C의 결과에 0 이 몇 번 쓰였는지 출력한다. 마찬가지로 둘째 줄부터 열 번째 줄까지 A × B × C의 결과에 1부터 9까지의 숫자가 각각 몇 번 쓰였는지 차례로 한 줄에 하나씩 출력한다.

예제 입력 1
150
266
427

예제 출력 1
3
1
0
2
0
0
0
2
0
0

해답

const fs = require("fs");

const inputData = fs
  .readFileSync(
    process.platform === "linux" ? "/dev/stdin" : "../../../../index.txt"
  )
  .toString()
  .split("\n")
  .map((value) => +value);

const [A, B, C] = inputData;
const multiplied = A * B * C;

for (let i = 0; i < 10; i++) {
  const countOfEachDigit = String(multiplied)
    .split("")
    .filter((value) => +value === i).length;

  console.log(countOfEachDigit);
}

풀이

inputData (입력값)

파일 읽어오기
const fs = require("fs");

const inputData = fs.readFileSync(
  process.platform === "linux" ? "/dev/stdin" : "../../../../index.txt"
);

console.log(inputData); // <Buffer 31 35 30 0a 32 36 36 0a 34 32 37>
readFileSync()

백준에서 추천하는 방식은 node.js에서 fs 모듈의 readFileSync()를 이용하는 것입니다.

작동 시스템 구별
process.platform === "linux" ? "/dev/stdin" : "../../../../index.txt";
process.platform

process.platform"linux"인 경우 경로를 "/dev/stdin"으로 향하게 하고 그것이 아니면 사용자가 지정한 파일을 향하게 합니다.

문자열 형식으로 변환
const inputData = fs
  .readFileSync(
    process.platform === "linux" ? "/dev/stdin" : "../../../../index.txt"
  )
  .toString();

console.log(inputData);
// 150
// 266
// 427
toString()

Buffer 형식으로 출력된 값을 toString()을 통해 기본값인 "utf8" 형식으로 출력합니다.

배열 생성
const inputData = fs
  .readFileSync(
    process.platform === "linux" ? "/dev/stdin" : "../../../../index.txt"
  )
  .toString()
  .split("\n");

console.log(inputData); // [ '150', '266', '427' ]
split()

split()을 활용하여 매개변수에 다음줄을 의미하는 "\n"를 넣어 배열을 만듭니다.

배열 형식 변환
const fs = require("fs");

const inputData = fs
  .readFileSync(
    process.platform === "linux" ? "/dev/stdin" : "../../../../index.txt"
  )
  .toString()
  .split("\n")
  .map((value) => +value);

console.log(inputData); // [ 150, 266, 427 ]
map()

생성된 배열의 형식은 문자열입니다. 배열의 형식을 숫자 형식으로 변환하기 위해 map() 메서드를 활용하여 매개변수 callback 함수를 (value) => +value로 하여 모든 배열 내부의 요소가 숫자 형식으로 변환되게 합니다.

A, B, C (세 개의 자연수)

const [A, B, C] = inputData;

console.log(A, B, C); // 160 266 427
배열 구조 분해

구조 분해 할당배열 구조 분해를 통해 배열 inputData의 세 가지 요소를 각각 A, B, C에 할당합니다.

multiplied (A, B, C를 곱한 값)

const multiplied = A * B * C;

console.log(multiplied); // 17037300

A, B, C를 곱한 값을 multiplied라는 변수로 할당합니다.

for

for (let i = 0; i < 10; i++) {
  const countOfEachDigit = String(multiplied)
    .split("")
    .filter((value) => +value === i).length;

  console.log(countOfEachDigit);
}
for (let i = 0; i < 10; i++) {}

for문을 활용하여 i의 범위를 0부터 9까지 하여 multiplied의 각 자리의 숫자가 몇 번씩 쓰였는지 구합니다.

countOfEachDigit (각각의 숫자가 쓰인 횟수)
for (let i = 0; i < 10; i++) {
  const countOfEachDigit = String(multiplied)
    .split("")
    .filter((value) => +value === i).length;
}
String() (문자열 형식으로 변환)
const countOfEachDigit = String(multiplied);

console.log(countOfEachDigit); // 17037300

String()을 활용하여 숫자 형식으로 된 multiplied를 문자열 형식으로 변환합니다.

split() (각 자리의 숫자로 이루어진 요소로 배열화)
const countOfEachDigit = String(multiplied).split("");

console.log(countOfEachDigit);
// [
//   '1', '7', '0',
//   '3', '7', '3',
//   '0', '0'
// ]

매개변수가 ""가 포함된 split() 메서드를 활용해 문자열 형식으로 변환된 multiplied각 문자를 요소로 가지는 문자열 형식의 배열로 만듭니다.

filter() (일치하는 값이 포함된 새로운 배열)
for (let i = 0; i < 10; i++) {
  const countOfEachDigit = String(multiplied)
    .split("")
    .filter((value) => +value === i);

  console.log(countOfEachDigit);
  // [ '0', '0', '0' ]
  // [ '1' ]
  // []
  // [ '3', '3' ]
  // []
  // []
  // []
  // [ '7', '7' ]
  // []
  // []
}

매개변수로 각 배열의 요소가 i와 일치하면 반환하는 (value) => +value === icallback 함수를 가지는 filter() 메서드를 활용해 i와 일치하는 값이 반환된 새로운 배열을 반환합니다.

length (배열의 길이)
for (let i = 0; i < 10; i++) {
  const countOfEachDigit = String(multiplied)
    .split("")
    .filter((value) => +value === i).length;

  console.log(countOfEachDigit);
  // 3
  // 1
  // 0
  // 2
  // 0
  // 0
  // 0
  // 2
  // 0
  // 0
}

그 후 length 속성으로 배열마다의 길이를 구합니다.

console.log (개수 출력)

마지막으로 console.log()을 활용하여 출력하면 각각의 숫자가 몇 번씩 쓰였는지 개수를 알 수 있습니다.

4. 나머지

https://www.acmicpc.net/problem/3052

문제

나머지

문제
두 자연수 A와 B가 있을 때, A%B는 A를 B로 나눈 나머지 이다. 예를 들어, 7, 14, 27, 38을 3으로 나눈 나머지는 1, 2, 0, 2이다.

수 10개를 입력받은 뒤, 이를 42로 나눈 나머지를 구한다. 그 다음 서로 다른 값이 몇 개 있는지 출력하는 프로그램을 작성하시오.

입력
첫째 줄부터 열번째 줄 까지 숫자가 한 줄에 하나씩 주어진다. 이 숫자는 1,000보다 작거나 같고, 음이 아닌 정수이다.

출력
첫째 줄에, 42로 나누었을 때, 서로 다른 나머지가 몇 개 있는지 출력한다.

예제 입력 1
1
2
3
4
5
6
7
8
9
10

예제 출력 1
10

각 수를 42로 나눈 나머지는 1, 2, 3, 4, 5, 6, 7, 8, 9, 10이다.

예제 입력 2
42
84
252
420
840
126
42
84
420
126

예제 출력 2
1

모든 수를 42로 나눈 나머지는 0이다.

예제 입력 3
39
40
41
42
43
44
82
83
84
85

예제 출력 3
6

각 수를 42로 나눈 나머지는 39, 40, 41, 0, 1, 2, 40, 41, 0, 1이다.

해답

const fs = require("fs");

const inputData = fs
  .readFileSync(
    process.platform === "linux" ? "/dev/stdin" : "../../../../index.txt"
  )
  .toString()
  .trim()
  .split("\n");

const remainder = inputData.map((value) => +value % 42);

const deduplication = remainder.filter(
  (value, index) => remainder.indexOf(value) === index
);

console.log(deduplication.length);

풀이

inputData (입력값)

파일 읽어오기
const fs = require("fs");

const inputData = fs.readFileSync(
  process.platform === "linux" ? "/dev/stdin" : "../../../../index.txt"
);

console.log(inputData); // <Buffer 33 39 0a 34 30 0a 34 31 0a 34 32 0a 34 33 0a 34 34 0a 38 32 0a 38 33 0a 38 34 0a 38 35>
readFileSync()

백준에서 추천하는 방식은 node.js에서 fs 모듈의 readFileSync()를 이용하는 것입니다.

작동 시스템 구별
process.platform === "linux" ? "/dev/stdin" : "../../../../index.txt";
process.platform

process.platform"linux"인 경우 경로를 "/dev/stdin"으로 향하게 하고 그것이 아니면 사용자가 지정한 파일을 향하게 합니다.

문자열 형식으로 변환
const inputData = fs
  .readFileSync(
    process.platform === "linux" ? "/dev/stdin" : "../../../../index.txt"
  )
  .toString();

console.log(inputData);
// 39
// 40
// 41
// 42
// 43
// 44
// 82
// 83
// 84
// 85
toString()

Buffer 형식으로 출력된 값을 toString()을 통해 기본값인 "utf8" 형식으로 출력합니다.

공백 제거
const inputData = fs
  .readFileSync(
    process.platform === "linux" ? "/dev/stdin" : "../../../../index.txt"
  )
  .toString()
  .trim();

console.log(inputData);
// 39
// 40
// 41
// 42
// 43
// 44
// 82
// 83
// 84
// 85
trim()

trim() 메서드를 활용하여 문자열 양 끝의 공백을 제거합니다.

배열 생성
const inputData = fs
  .readFileSync(
    process.platform === "linux" ? "/dev/stdin" : "../../../../index.txt"
  )
  .toString()
  .split("\n");

console.log(inputData);
// [
//   '39', '40', '41',
//   '42', '43', '44',
//   '82', '83', '84',
//   '85'
// ]
split()

split()을 활용하여 매개변수에 다음줄을 의미하는 "\n"를 넣어 배열을 만듭니다.

remainder (나머지)

const remainder = inputData.map((value) => +value % 42);

console.log(remainder);
// [
//   39, 40, 41, 0, 1,
//    2, 40, 41, 0, 1
// ]
42로 나눈 나머지로 이루어진 배열
map()

각 수를 42로 나눈 나머지를 구하기 위해서 map() 메서드를 활용하여 매개변수 callback 함수를 (value) => +value % 42로 하여 모든 배열 내부의 요소를 문자열에서 숫자 형식으로 바꾼 후 42로 나눈 나머지를 반환합니다.

deduplication (중복 제거)

const deduplication = remainder.filter(
  (value, index) => remainder.indexOf(value) === index
);

console.log(deduplication); // [ 39, 40, 41, 0, 1, 2 ]
배열 내 중복 요소 제거
filter()

매개변수로 indexOf(value)index와 일치하면 반환하는 (value, index) => reaminder.indexOf(value) === indexcallback 함수를 가지는 filter() 메서드를 활용합니다.

indexOf()
indexOf(value) index value
0 0 39
1 1 40
2 2 41
3 3 0
4 4 1
5 5 2
1 6 40
2 7 41
0 8 39
1 9 40

위 표와 같이 indexOf 메서드를 활용하여 배열에서 지정된 요소를 찾을 수 있는 첫 번째에만 인덱스를 부여합니다.

따라서 fliter()callback 함수인 (value, index) => reaminder.indexOf(value) === index에 의한 새로운 배열은 index(value)의 값과 index의 값이 일치하는 것만 반환하므로 [ 39, 40, 41, 0, 1, 2 ]가 됩니다.

중복 제거된 배열의 길이 출력

console.log(deduplication.length); // 6
console.log(), length

마지막으로 console.log()length 속성을 활용하여 deduplication.length 즉 중복을 제거한 배열의 길이를 출력합니다.

5. 평균

https://www.acmicpc.net/problem/1546

문제

평균

문제
세준이는 기말고사를 망쳤다. 세준이는 점수를 조작해서 집에 가져가기로 했다. 일단 세준이는 자기 점수 중에 최댓값을 골랐다. 이 값을 M이라고 한다. 그리고 나서 모든 점수를 점수/M*100으로 고쳤다.

예를 들어, 세준이의 최고점이 70이고, 수학점수가 50이었으면 수학점수는 50/70*100이 되어 71.43점이 된다.

세준이의 성적을 위의 방법대로 새로 계산했을 때, 새로운 평균을 구하는 프로그램을 작성하시오.

입력
첫째 줄에 시험 본 과목의 개수 N이 주어진다. 이 값은 1000보다 작거나 같다. 둘째 줄에 세준이의 현재 성적이 주어진다. 이 값은 100보다 작거나 같은 음이 아닌 정수이고, 적어도 하나의 값은 0보다 크다.

출력
첫째 줄에 새로운 평균을 출력한다. 실제 정답과 출력값의 절대오차 또는 상대오차가 10-2 이하이면 정답이다.

예제 입력 1
3
40 80 60

예제 출력 1
75.0

예제 입력 2
3
10 20 30

예제 출력 2
66.666667
10-2 이하의 오차를 허용한다는 말은 정확히 소수 2번째 자리까지 출력하라는 뜻이 아니다.

예제 입력 3
4
1 100 100 100

예제 출력 3
75.25

예제 입력 4
5
1 2 4 8 16

예제 출력 4
38.75

예제 입력 5
2
3 10

예제 출력 5
65.0

예제 입력 6
4
10 20 0 100

예제 출력 6
32.5

예제 입력 7
1
50

예제 출력 7
100.0

예제 입력 8
9
10 20 30 40 50 60 70 80 90

예제 출력 8
55.55555555555556

해답

const fs = require("fs");

const inputData = fs
  .readFileSync(
    process.platform === "linux" ? "/dev/stdin" : "../../../../index.txt"
  )
  .toString()
  .trim()
  .split("\n");

const [N, inputDataScores] = inputData;
const scores = inputDataScores.split(" ");
const M = Math.max(...scores);
const newScores = scores.map((score) => (score / M) * 100);

let sum = 0;

for (let i = 0; i < N; i++) {
  sum += newScores[i];
}

console.log(sum / N);

풀이

inputData (입력값)

파일 읽어오기
const fs = require("fs");

const inputData = fs.readFileSync(
  process.platform === "linux" ? "/dev/stdin" : "../../../../index.txt"
);

console.log(inputData); // <Buffer 33 0a 31 30 20 32 30 20 33 30>
readFileSync()

백준에서 추천하는 방식은 node.js에서 fs 모듈의 readFileSync()를 이용하는 것입니다.

작동 시스템 구별
process.platform === "linux" ? "/dev/stdin" : "../../../../index.txt";
process.platform

process.platform"linux"인 경우 경로를 "/dev/stdin"으로 향하게 하고 그것이 아니면 사용자가 지정한 파일을 향하게 합니다.

문자열 형식으로 변환
const inputData = fs
  .readFileSync(
    process.platform === "linux" ? "/dev/stdin" : "../../../../index.txt"
  )
  .toString();

console.log(inputData);
// 3
// 10 20 30
toString()

Buffer 형식으로 출력된 값을 toString()을 통해 기본값인 "utf8" 형식으로 출력합니다.

공백 제거
const inputData = fs
  .readFileSync(
    process.platform === "linux" ? "/dev/stdin" : "../../../../index.txt"
  )
  .toString()
  .trim();

console.log(inputData);
// 3
// 10 20 30
trim()

trim() 메서드를 활용하여 문자열 양 끝의 공백을 제거합니다.

배열 생성
const inputData = fs
  .readFileSync(
    process.platform === "linux" ? "/dev/stdin" : "../../../../index.txt"
  )
  .toString()
  .split("\n");

console.log(inputData); // [ '3', '10 20 30' ]
split()

split()을 활용하여 매개변수에 다음줄을 의미하는 "\n"를 넣어 배열을 만듭니다.

N, inputDataScores

const [N, inputDataScores] = inputData;

console.log(N, inputDataScores); // 3 10 20 30
시험 본 과목의 개수, 현재 성적
배열 구조 분해

구조 분해 할당배열 구조 분해를 통해 배열 inputData의 두 가지 요소들을 각각 시험 본 과목의 개수를 의미하는 N, 현재 성적을 의미하는 inputDataScores에 할당합니다.

scores

const scores = inputDataScores.split(" ");

console.log(scores); // [ '10', '20', '30' ]
성적에 대한 배열 생성
split()

성적에 대한 변수인 inputDataScoressplit()을 활용하여 매개변수에 공백을 의미하는 " "를 넣어 배열을 만듭니다.

M

const M = Math.max(...scores);

console.log(M); // 30
성적 중 최댓값
Math.max()

Math.max() 함수를 통해 성적 중 최댓값을 반환하여 M 변수에 할당합니다.

전개 구문

Math.max() 함수 내에 매개변수로 전개 구문을 활용해 배열 scores의 요소들을 넣습니다.

newScores

const newScores = scores.map((score) => (score / M) * 100);

console.log(newScores); // [ 33.33333333333333, 66.66666666666666, 100 ]
성적을 고친 값

일단 세준이는 자기 점수 중에 최댓값을 골랐다. 이 값을 M이라고 한다. 그리고 나서 모든 점수를 점수/M*100으로 고쳤다.

map()

기존의 점수인 scoresmap() 메서드를 활용하여 매개변수 callback 함수를 위 주석대로 (score) => (score / M) * 100로 하여 각 점수들을 최댓값으로 나눈 후 100을 곱하여 조작한 값들에 대한 새로운 배열을 반환하고 newScores 변수에 할당합니다.

sum

let sum = 0;
조작된 점수들의 합

조작된 점수들의 합을 위한 변수sum0으로 초기화합니다.

for

for (let i = 0; i < N; i++) {
  sum += newScores[i];
}
for (let i = 0; i < N; i++) {}

for문으로 조작된 점수들의 합을 구하기 위하여 i0부터 N이전까지로 반복문의 범위를 정합니다.

조작된 점수들 합하기
for (let i = 0; i < N; i++) {
  sum += newScores[i];

  console.log(sum);
  // 33.33333333333333
  // 99.99999999999999
  // 200
}
더하기 할당

newScore[0]부터 newScore[N-1]까지 sum더하기 할당합니다.

조작된 점수들의 합에 과목 개수 나누기

console.log(sum / N); // 66.66666666666667
console.log()

마지막으로 console.log()을 활용하여 sum / N조작된 과목들에 과목의 개수를 나눈 값을 출력합니다.

6. OX퀴즈

https://www.acmicpc.net/problem/8958

문제

OX퀴즈

문제
"OOXXOXXOOO"와 같은 OX퀴즈의 결과가 있다. O는 문제를 맞은 것이고, X는 문제를 틀린 것이다. 문제를 맞은 경우 그 문제의 점수는 그 문제까지 연속된 O의 개수가 된다. 예를 들어, 10번 문제의 점수는 3이 된다.

"OOXXOXXOOO"의 점수는 1+2+0+0+1+0+0+1+2+3 = 10점이다.

OX퀴즈의 결과가 주어졌을 때, 점수를 구하는 프로그램을 작성하시오.

입력
첫째 줄에 테스트 케이스의 개수가 주어진다. 각 테스트 케이스는 한 줄로 이루어져 있고, 길이가 0보다 크고 80보다 작은 문자열이 주어진다. 문자열은 O와 X만으로 이루어져 있다.

출력
각 테스트 케이스마다 점수를 출력한다.

예제 입력 1
5
OOXXOXXOOO
OOXXOOXXOO
OXOXOXOXOXOXOX
OOOOOOOOOO
OOOOXOOOOXOOOOX

예제 출력 1
10
9
7
55
30

해답

const fs = require("fs");

const inputData = fs
  .readFileSync(
    process.platform === "linux" ? "/dev/stdin" : "../../../../index.txt"
  )
  .toString()
  .trim()
  .split("\n");

const count = inputData[0];

for (let i = 1; i <= count; i++) {
  let value = 0;
  let sum = 0;

  const quizs = inputData[i].split("");
  const newQuizs = quizs.map((quiz) => {
    if (quiz === "O") {
      value += 1;
      return value;
    }
    if (quiz === "X") {
      value = 0;
      return value;
    }
    return quiz;
  });

  for (y = 0; y < newQuizs.length; y++) {
    sum += newQuizs[y];
  }

  console.log(sum);
}

풀이

inputData (입력값)

파일 읽어오기
const fs = require("fs");

const inputData = fs.readFileSync(
  process.platform === "linux" ? "/dev/stdin" : "../../../../index.txt"
);

console.log(inputData); // <Buffer 35 0a 4f 4f 58 58 4f 58 58 4f 4f 4f 0a 4f 4f 58 58 4f 4f 58 58 4f 4f 0a 4f 58 4f 58 4f 58 4f 58 4f 58 4f 58 4f 58 0a 4f 4f 4f 4f 4f 4f 4f 4f 4f 4f 0a ... 15 more bytes>
readFileSync()

백준에서 추천하는 방식은 node.js에서 fs 모듈의 readFileSync()를 이용하는 것입니다.

작동 시스템 구별
process.platform === "linux" ? "/dev/stdin" : "../../../../index.txt";
process.platform

process.platform"linux"인 경우 경로를 "/dev/stdin"으로 향하게 하고 그것이 아니면 사용자가 지정한 파일을 향하게 합니다.

문자열 형식으로 변환
const inputData = fs
  .readFileSync(
    process.platform === "linux" ? "/dev/stdin" : "../../../../index.txt"
  )
  .toString();

console.log(inputData);
// 5
// OOXXOXXOOO
// OOXXOOXXOO
// OXOXOXOXOXOXOX
// OOOOOOOOOO
// OOOOXOOOOXOOOOX
toString()

Buffer 형식으로 출력된 값을 toString()을 통해 기본값인 "utf8" 형식으로 출력합니다.

공백 제거
const inputData = fs
  .readFileSync(
    process.platform === "linux" ? "/dev/stdin" : "../../../../index.txt"
  )
  .toString()
  .trim();

console.log(inputData);
// 5
// OOXXOXXOOO
// OOXXOOXXOO
// OXOXOXOXOXOXOX
// OOOOOOOOOO
// OOOOXOOOOXOOOOX
trim()

trim() 메서드를 활용하여 문자열 양 끝의 공백을 제거합니다.

배열 생성
const inputData = fs
  .readFileSync(
    process.platform === "linux" ? "/dev/stdin" : "../../../../index.txt"
  )
  .toString()
  .split("\n");

console.log(inputData);
// [
//   '5',
//   'OOXXOXXOOO',
//   'OOXXOOXXOO',
//   'OXOXOXOXOXOXOX',
//   'OOOOOOOOOO',
//   'OOOOXOOOOXOOOOX'
// ]
split()

split()을 활용하여 매개변수에 다음줄을 의미하는 "\n"를 넣어 배열을 만듭니다.

count

const count = inputData[0];

console.log(count); // 5
테스트 케이스의 개수

테스트 케이스의 개수를 뜻하는 inputData[0]을 변수 count에 할당합니다.

for (각 퀴즈 결과에 대한 반복문)

for (let i = 1; i <= count; i++) {
  let value = 0;
  let sum = 0;

  const quizs = inputData[i].split("");
  const newQuizs = quizs.map((quiz) => {
    if (quiz === "O") {
      value += 1;
      return value;
    }
    if (quiz === "X") {
      value = 0;
      return value;
    }
    return quiz;
  });

  for (y = 0; y < newQuizs.length; y++) {
    sum += newQuizs[y];
  }

  console.log(sum);
}
for (let i = 1; i <= count; i++) {}

for문으로 inputData[i]에 대한 반복문을 실행할 것이기 때문에 i의 범위를 테스트 케이스의 개수를 의미하는 0이 아닌 1부터 count까지로 합니다.

value (O, X에 대한 점수)
let value = 0;

OX에 대한 점수를 의미하는 변수 value를 선언하고 0으로 초기화합니다.

sum (점수들의 합)
let sum = 0;

점수들의 합산을 의미하는 변수 sum을 선언하고 0으로 초기화합니다.

quizs (각 OX퀴즈의 결과 배열화하기)
for (let i = 1; i <= count; i++) {
  let value = 0;
  let sum = 0;

  const quizs = inputData[i].split("");

  console.log(quizs);
}
// expected output:
// [
//   'O', 'O', 'X', 'X',
//   'O', 'X', 'X', 'O',
//   'O', 'O'
// ]
// [
//   'O', 'O', 'X', 'X',
//   'O', 'O', 'X', 'X',
//   'O', 'O'
// ]
// [
//   'O', 'X', 'O', 'X',
//   'O', 'X', 'O', 'X',
//   'O', 'X', 'O', 'X',
//   'O', 'X'
// ]
// [
//   'O', 'O', 'O', 'O',
//   'O', 'O', 'O', 'O',
//   'O', 'O'
// ]
// [
//   'O', 'O', 'O', 'O',
//   'X', 'O', 'O', 'O',
//   'O', 'X', 'O', 'O',
//   'O', 'O', 'X'
// ]
split()

매개변수 ""를 가지는 split() 메서드를 활용하여 문자열에 있는 각 문자들을 요소로 가지는 배열로 배열화한 후 quizs 변수에 할당합니다.

newQuizs (점수를 매긴 각 OX퀴즈들의 배열)
for (let i = 1; i <= count; i++) {
  let value = 0;
  let sum = 0;

  const quizs = inputData[i].split("");
  const newQuizs = quizs.map((quiz) => {
    if (quiz === "O") {
      value += 1;
      return value;
    }
    if (quiz === "X") {
      value = 0;
      return value;
    }
    return quiz;
  });

  console.log(newQuizs);
}
// expected output:
// [
//   1, 2, 0, 0, 1,
//   0, 0, 1, 2, 3
// ]
// [
//   1, 2, 0, 0, 1,
//   2, 0, 0, 1, 2
// ]
// [
//   1, 0, 1, 0, 1, 0,
//   1, 0, 1, 0, 1, 0,
//   1, 0
// ]
// [
//   1, 2, 3, 4,  5,
//   6, 7, 8, 9, 10
// ]
// [
//   1, 2, 3, 4, 0, 1,
//   2, 3, 4, 0, 1, 2,
//   3, 4, 0
// ]
map()
const newQuizs = quizs.map((quiz) => {
  if (quiz === "O") {
    value += 1;
    return value;
  }
  if (quiz === "X") {
    value = 0;
    return value;
  }
  return quiz;
});

map() 메서드를 활용하여 매개변수 callback 함수 내의 if...else문으로 OX별로 점수를 매깁니다. 그 후 과정이 끝나면 값을 newQuizs 변수에 할당합니다.

if...else
if (quiz === "O") {
  value += 1;
  return value;
}
if (quiz === "X") {
  value = 0;
  return value;
}
return quiz;

O는 문제를 맞은 것이고, X는 문제를 틀린 것이다. 문제를 맞은 경우 그 문제의 점수는 그 문제까지 연속된 O의 개수가 된다. 예를 들어, 10번 문제의 점수는 3이 된다.

"OOXXOXXOOO"의 점수는 1+2+0+0+1+0+0+1+2+3 = 10점이다.

퀴즈의 값이 O인 경우

점수는 연속된 O의 개수가 되기 때문에 X가 나오기 전까진 1씩 증가해야합니다. 따라서 더하기 할당을 통해 value += 1value 값이 0, 1, 2 이런식으로 할당시키고, 할당된 value 값을 배열 내 요소에 반환합니다.

퀴즈의 값이 X인 경우

배열의 요소가 X가 나오는 순간 점수는 0점이 됩니다. 그러므로 value = 0value 값을 0으로 초기화시킵니다. 그리고 그 값을 X인 배열의 요소에 반환합니다.

O, X 둘 다 아닌 경우

둘 다 아닌 경우는 문제상 존재하진 않지만 quiz 즉 배열의 요소 그대로 반환합니다.

for (점수 합하기)
for (y = 0; y < newQuizs.length; y++) {
  sum += newQuizs[y];
}
for (y = 0; y < newQuizs.length; y++) {}

배열 내의 모든 점수를 합해야하기 때문에 변수 y의 범위를 시작인 0부터 newQuizs 배열의 전체 길이를 의미하는 newQuizs.length 전까지 반복문을 수행하게 합니다.

더하기 할당
for (y = 0; y < newQuizs.length; y++) {
  sum += newQuizs[y];
}

더하기 할당을 통해 newQuize 배열 내의 모든 요소들을 합하여 sum에 할당합니다.

console.log()
console.log(sum);
// 10
// 9
// 7
// 55
// 30

마지막으로 console.log()을 활용하여 sum을 출력합니다.

7. 평균은 넘겠지

https://www.acmicpc.net/problem/4344

문제

평균은 넘겠지

문제
대학생 새내기들의 90%는 자신이 반에서 평균은 넘는다고 생각한다. 당신은 그들에게 슬픈 진실을 알려줘야 한다.

입력
첫째 줄에는 테스트 케이스의 개수 C가 주어진다.

둘째 줄부터 각 테스트 케이스마다 학생의 수 N(1 ≤ N ≤ 1000, N은 정수)이 첫 수로 주어지고, 이어서 N명의 점수가 주어진다. 점수는 0보다 크거나 같고, 100보다 작거나 같은 정수이다.

출력
각 케이스마다 한 줄씩 평균을 넘는 학생들의 비율을 반올림하여 소수점 셋째 자리까지 출력한다.

예제 입력 1
5
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

예제 출력 1
40.000%
57.143%
33.333%
66.667%
55.556%

해답

const fs = require("fs");

const inputData = fs
  .readFileSync(
    process.platform === "linux" ? "/dev/stdin" : "../../../../index.txt"
  )
  .toString()
  .split("\n");

const C = +inputData[0];

for (let i = 1; i <= C; i++) {
  let sum = 0;

  const testCase = inputData[i].split(" ").map((value) => +value);
  const N = testCase[0];

  for (let y = 1; y <= N; y++) {
    sum += testCase[y];
  }
  const avg = sum / N;

  let overStudent = 0;
  for (let z = 1; z <= N; z++) {
    if (testCase[z] > avg) {
      overStudent++;
    }
  }
  const overAvg = ((overStudent / N) * 100).toFixed(3);

  console.log(overAvg + "%");
}

풀이

inputData (입력값)

readFileSync() (파일 읽어오기)
const fs = require("fs");

const inputData = fs.readFileSync(
  process.platform === "linux" ? "/dev/stdin" : "../../../../index.txt"
);

console.log(inputData); // <Buffer 35 0a 35 20 35 30 20 35 30 20 37 30 20 38 30 20 31 30 30 0a 37 20 31 30 30 20 39 35 20 39 30 20 38 30 20 37 30 20 36 30 20 35 30 0a 33 20 37 30 20 39 ... 45 more bytes>

백준에서 추천하는 방식은 node.js에서 fs 모듈의 readFileSync()를 이용하는 것입니다.

process.platform (작동 시스템 구별)
process.platform === "linux" ? "/dev/stdin" : "../../../../index.txt";

process.platform"linux"인 경우 경로를 "/dev/stdin"으로 향하게 하고 그것이 아니면 사용자가 지정한 파일을 향하게 합니다.

toString() (문자열 형식으로 변환)
const inputData = fs
  .readFileSync(
    process.platform === "linux" ? "/dev/stdin" : "../../../../index.txt"
  )
  .toString();

console.log(inputData);
// 5
// 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

Buffer 형식으로 출력된 값을 toString()을 통해 기본값인 "utf8" 형식으로 출력합니다.

split() (배열 생성)
const inputData = fs
  .readFileSync(
    process.platform === "linux" ? "/dev/stdin" : "../../../../index.txt"
  )
  .toString()
  .split("\n");

console.log(inputData);
// [
//   '5',
//   '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'
// ]

split()을 활용하여 매개변수에 다음줄을 의미하는 "\n"를 넣어 배열을 만듭니다.

C (테스트 케이스의 개수)

const C = +inputData[0];

console.log(C); // 5
+ (숫자 형식으로 변환)

inputData의 테스트 케이스의 개수를 뜻하는 요소 inputData[0]에 숫자 형식으로 변환을 하여 +inputData[0]을 변수 C에 할당합니다.

for (각 테스트 케이스를 위한 반복문)

for (let i = 1; i <= C; i++) {
  let sum = 0;

  const testCase = inputData[i].split(" ").map((value) => +value);
  const N = testCase[0];

  for (let y = 1; y <= N; y++) {
    sum += testCase[y];
  }
  const avg = sum / N;

  let overStudent = 0;
  for (let z = 1; z <= N; z++) {
    if (testCase[z] > avg) {
      overStudent++;
    }
  }
  const overAvg = ((overStudent / N) * 100).toFixed(3);

  console.log(overAvg + "%");
}
for (let i = 1; i <= C; i++) {}

for문으로 각 테스트 케이스를 위한 즉 inputData[i]에 대한 반복문을 실행할 것이기 때문에 i의 범위를 테스트 케이스의 개수를 의미하는 0이 아닌 1부터 C까지로 합니다.

sum (점수들의 합)
let sum = 0;

점수들의 합산을 의미하는 변수 sum을 선언하고 0으로 초기화합니다.

testCase (각 테스트 케이스 내의 점수들의 배열)
for (let i = 1; i <= C; i++) {
  let sum = 0;

  const testCase = inputData[i].split(" ").map((value) => +value);

  console.log(testCase);
}
// expected output:
// [ 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
// ]
split() (배열 형식으로 변환)

학생의 수와 점수들을 의미하는 inputData[i]로부터 공백을 의미하는 매개변수 " "를 가지는 split() 메서드를 활용하여 공백을 기준으로 새로운 배열을 생성합니다.

map() (배열 내 요소 숫자 형식으로 변환)

map() 메서드를 활용하여 매개변수 callback 함수 (value) => +value)문자열 형식의 배열을 숫자 형식으로 변환한 후 testCase에 할당합니다.

N (학생들의 점수의 개수)
for (let i = 1; i <= C; i++) {
  let sum = 0;

  const testCase = inputData[i].split(" ").map((value) => +value);
  const N = testCase[0];

  cossole.log(N);
}
// expected output:
// 5
// 7
// 3
// 3
// 9

testCase의 첫 번째 인덱스인 testCase[0]에서 학생들의 점수의 수를 변수 N에 할당합니다.

for (testCase 내의 점수들에 대한 반복문)
for (let i = 1; i <= C; i++) {
  let sum = 0;

  const testCase = inputData[i].split(" ").map((value) => +value);
  const N = testCase[0];

  for (let y = 1; y <= N; y++) {
    sum += testCase[y];
  }
}
for (let y = 1; y <= N; y++) {}

testCase 내부 점수들에 관한 for문이기에 y의 범위를 점수의 개수를 의미하는 배열 인덱스인 0이 아닌 1부터 N까지로 합니다.

더하기 할당
for (let i = 1; i <= C; i++) {
  let sum = 0;

  const testCase = inputData[i].split(" ").map((value) => +value);
  const N = testCase[0];

  for (let y = 1; y <= N; y++) {
    sum += testCase[y];
  }
}

console.log(sum);
// 350
// 545
// 240
// 241
// 863

더하기 할당 연산자를 활용하여 testCase 배열 내의 모든 요소들을 합하여 sum에 할당합니다.

avg (점수들의 평균)
for (let i = 1; i <= C; i++) {
  let sum = 0;

  const testCase = inputData[i].split(" ").map((value) => +value);
  const N = testCase[0];

  for (let y = 1; y <= N; y++) {
    sum += testCase[y];
  }
  const avg = sum / N;

  console.log(avg);
}
// expected output:
// 70
// 77.85714285714286
// 80
// 80.33333333333333
// 95.88888888888889

sum에 점수의 개수를 의미하는 N을 나눠줘 평균을 구한 후 변수 avg에 할당합니다.

overStudent (평균을 넘긴 학생의 수)
let overStudent = 0;

평균을 넘은 학생들의 수를 뜻하는 변수 overStudent을 선언하고 0으로 초기화합니다.

for (평균을 넘은 학생들을 추려내는 반복문)
for (let z = 1; z <= N; z++) {
  if (testCase[z] > avg) {
    overStudent++;
  }
}
for (let z = 1; z <= N; z++) {}

y와 같이 testCase 내부 점수들에 관한 for문이기에 z의 범위를 개수를 의미하는 배열 인덱스인 0이 아닌 1부터 N까지로 합니다.

if...else
for (let i = 1; i <= C; i++) {
  let sum = 0;

  const testCase = inputData[i].split(" ").map((value) => +value);
  const N = testCase[0];

  for (let y = 1; y <= N; y++) {
    sum += testCase[y];
  }
  const avg = sum / N;

  let overStudent = 0;
  for (let z = 1; z <= N; z++) {
    if (testCase[z] > avg) {
      overStudent++;
    }
  }
}

console.log(overStudent);
// 2
// 4
// 1
// 2
// 5

if...else문을 통해 testCase 배열의 요소들 중 avg즉 평균보다 큰 요소일 경우 Increment (++)을 통해 overStudent++overStudent를 하나씩 증가시켜줍니다.

overAvg (평균이 넘는 학생들의 비율)
const overAvg = ((overStudent / N) * 100).toFixed(3);

console.log(overAvg);
// 40.000
// 57.143
// 33.333
// 66.667
// 55.556

평균 점수를 넘는 학생들의 수인 변수 overStudent에 학생들의 점수의 수인 변수 N을 나눈 후 비율을 위해 100을 곱해줍니다.

toFixed() (숫자를 고정 소수점 표기법으로)

그 후 매개변수로 3을 가지는 toFixed() 메서드를 통해 소수점 셋째 자리까지 출력하도록 합니다.

결과값 출력하기
console.log(overAvg + "%");
// 40.000%
// 57.143%
// 33.333%
// 66.667%
// 55.556%
console.log()

마지막으로 console.log()을 활용하여 overAvg% 기호가 필요하기 때문에 overAvg + "%을 출력합니다.

댓글