# 프로그래머스/Javascript : 기초 문제 5일차

- Author: @laetipark
- Published: 2024-02-04
- Updated: 2024-03-26
- Source: http://blex.me/@laetipark/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4javascript-%EA%B8%B0%EC%B4%88-%EB%AC%B8%EC%A0%9C-5%EC%9D%BC%EC%B0%A8
- Tags: 프로그래머스, 코딩테스트, 기초문제

---

## [코드 처리하기](https://school.programmers.co.kr/learn/courses/30/lessons/181932)

### 문제
문자열 `code`가 주어집니다.
`code`를 앞에서부터 읽으면서 만약 문자가 "1"이면 `mode`를 바꿉니다. `mode`에 따라 `code`를 읽어가면서 문자열 `ret`을 만들어냅니다.

`mode`는 0과 1이 있으며, `idx`를 0 부터 `code의 길이 - 1` 까지 1씩 키워나가면서 `code[idx]`의 값에 따라 다음과 같이 행동합니다.

- `mode`가 0일 때
	- `code[idx]`가 "1"이 아니면 `idx`가 짝수일 때만 `ret`의 맨 뒤에 `code[idx]`를 추가합니다.
	- `code[idx]`가 "1"이면 `mode`를 0에서 1로 바꿉니다.
- `mode`가 1일 때
	- `code[idx]`가 "1"이 아니면 `idx`가 홀수일 때만 `ret`의 맨 뒤에 `code[idx]`를 추가합니다.
	- `code[idx]`가 "1"이면 `mode`를 1에서 0으로 바꿉니다.
문자열 `code`를 통해 만들어진 문자열 `ret`를 return 하는 solution 함수를 완성해 주세요.

단, 시작할 때 `mode`는 0이며, return 하려는 `ret`가 만약 빈 문자열이라면 대신 "EMPTY"를 return 합니다.

- 제한사항
	- 1 ≤ code의 길이 ≤ 100,000
		- `code`는 알파벳 소문자 또는 "1"로 이루어진 문자열입니다.

### 소스 코드
```javascript
const readline = require('readline');
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

let input = '';

rl.on('line', (line) => {
  input = line;
  rl.close();
}).on('close', () => {
  const answer = solution(input);
  console.log(answer);
});

const solution = (code) => {
  let answer = '';
  let mode = 0;

  // idx를 0 부터 code의 길이 - 1 까지 1씩 키워나가면서
  for (let i = 0; i < code.length; i++) {

    // code[idx] === '1'
    if (code[i] === '1') {
      // mode = 0 => (0 + 1)1을 2로 나눈 나머지 = 1
      // mode = 1 => (1 + 1)2를 2로 나눈 나머지 = 0
      mode = (mode + 1) % 2;
    }
    // code[idx] !== '1'
    else if (mode === 0 && i % 2 === 0) { // mode가 0일 때 && idx가 짝수일 때
      answer += code[i];
    } else if (mode === 1 && i % 2 === 1) { // mode가 1일 때 && idx가 홀수일 때
      answer += code[i];
    }
  }

  if (answer !== '') {
    return answer;
  } else {
    return 'EMPTY';
  }
};
```

## [등차수열의 특정한 항만 더하기](https://school.programmers.co.kr/learn/courses/30/lessons/181931)

### 문제
두 정수 `a`, `d`와 길이가 n인 boolean 배열 `included`가 주어집니다. 첫째항이 `a`, 공차가 `d`인 등차수열에서 `included[i]`가 i + 1항을 의미할 때, 이 등차수열의 1항부터 n항까지 `included`가 true인 항들만 더한 값을 return 하는 solution 함수를 작성해 주세요.

- 제한사항
	- 1 ≤ `a` ≤ 100
	- 1 ≤ `d` ≤ 100
	- 1 ≤ `included`의 길이 ≤ 100
	- `included`에는 true가 적어도 하나 존재합니다.

### 소스 코드
```javascript
const readline = require('readline');
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

let input = '';
let booleanArray = [];
let count = 0;

rl.on('line', (line) => {
  if (count === 0) {
    input = line.split(' ').map(Number);
  } else {
    booleanArray = (line.split(' ')).map(item => Number(item) === 1);
  }
  count++;

  if (count > 1) {
    rl.close();
  }
}).on('close', () => {
  const answer = solution(input[0], input[1], booleanArray);
  console.log(answer);
});

const solution = (a, d, included) => {
  let answer = 0;
  included.map((item, index) => {
    if (item) {
      answer += a + (d * (index));
    }
  });

  return answer;
};
```

## [주사위 게임 2](https://school.programmers.co.kr/learn/courses/30/lessons/181930)

### 문제
1부터 6까지 숫자가 적힌 주사위가 세 개 있습니다. 세 주사위를 굴렸을 때 나온 숫자를 각각 a, b, c라고 했을 때 얻는 점수는 다음과 같습니다.

세 숫자가 모두 다르다면 `a` + `b` + `c` 점을 얻습니다.
세 숫자 중 어느 두 숫자는 같고 나머지 다른 숫자는 다르다면 (`a` + `b` + `c`) × (`a`^2 + `b`^2 + `c`^2 )점을 얻습니다.
세 숫자가 모두 같다면 (`a` + `b` + `c`) × (`a`^2 + `b`^2 + `c`^2 ) × (`a`^3 + `b`^3 + `c`^3 )점을 얻습니다.
세 정수 `a`, `b`, `c`가 매개변수로 주어질 때, 얻는 점수를 return 하는 solution 함수를 작성해 주세요.

- 제한사항
	- `a`, `b`, `c`는 1이상 6이하의 정수입니다.

### 소스 코드
```javascript
const readline = require('readline');
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

let input = '';

rl.on('line', (line) => {
  input = line.split(' ').map(Number);
  rl.close();
}).on('close', () => {
  const answer = solution(input[0], input[1], input[2]);
  console.log(answer);
});

const solution = (a, b, c) => {
  let number = {};
  let answer;
  number[a] = 1;
  number[b] = ++number[b] || 1;
  number[c] = ++number[c] || 1;

  let maxValue = -Infinity;

  for (let key in number) {
    let value = number[key];
    if (value > maxValue) {
    	maxValue = value;
		}
  }
  if (maxValue === 3) {
    answer = (a + b + c) * (a ** 2 + b ** 2 + c ** 2) * (a ** 3 + b ** 3 + c ** 3);
  } else if (maxValue === 2) {
    answer = (a + b + c) * (a ** 2 + b ** 2 + c ** 2);
  } else {
    answer = (a + b + c);
  }

  return answer;
};
```

- `number` object에 세 개의 숫자를 받기 떄문에, 나온 숫자별로 `number`의 `key`값 `value`를 추가해준다. for문을 통해 `key`에 접근하면서 `number[key]`에 있는 `maxValue`보다 크면 `maxValue`의 값을 변경해준다. 이것이 `같은 숫자의 개수`가 되며, 개수별로 계산식을 적용해주었다.

#### Infinity와 NaN
- `Infinity` : 무한대를 나타내는 변수로, 양의 무한대와 음의 무한대로 표현할 수 있다.

```
console.log(Infinity); /* Infinity */
console.log(Infinity + 1); /* Infinity */
console.log(Math.pow(10, 1000)); /* 10의 1000제곱, Infinity */ 
console.log(Math.log(0)); /* log0, -Infinity */
console.log(1 / Infinity); /* 0 */
console.log(1 / 0); /* Infinity */
```

- `NaN` : `Not-A-Number`을 나타내는 변수로, `문자열`이나 `undefined` 형태를 숫자 형태로 변환하려다 실패했거나, `0 * Infinity1 ** InfinityInfinity / InfinityInfinity - Infinity`와 같이 확정되지 않는 계산 형식인 경우, 표현된다.

## [원소들의 곱과 합](https://school.programmers.co.kr/learn/courses/30/lessons/181929)

### 문제
정수가 담긴 리스트 `num_list`가 주어질 때, 모든 원소들의 곱이 모든 원소들의 합의 제곱보다 작으면 1을 크면 0을 return하도록 solution 함수를 완성해주세요.

- 제한사항
	- 2 ≤ `num_list`의 길이 ≤ 10
	- 1 ≤ `num_list`의 원소 ≤ 9

### 소스 코드
```javascript
const readline = require('readline');
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

let input = '';

rl.on('line', (line) => {
  input = line.split(' ').map(Number);
  rl.close();
}).on('close', () => {
  const answer = solution(input);
  console.log(answer);
});

const solution = (num_list) => {
  const product = num_list.reduce((acc, curr) => acc * curr, 1);
  const sum = (num_list.reduce((acc, curr) => acc + curr, 0)) ** 2;
  return product < sum ? 1 : 0;
};
```

- `reduce()`를 이용하여, 모든 원소들의 곱과 모든 원소들의 합에 대한 변수를 만든 다음, 비교해주었다.

#### reduce()
- `reduce(callbackFn, initialValue)` : 배열의 요소를 순차적으로 순회하여, 하나의 값으로 줄이는 함수
	- `callbackFn` : `reduce()`에 사용하는 callback 함수
		- `callback(누적값, 현재값, 인덱스, 요소)`
	- `initialValue` : `reduce()` 초기값

**사용 예시**
```javascript
num_list.reduce((acc, curr) => { // num_list 배열에서 누적값과 현재값을 받음
	return acc * curr // 배열을 순회하면서 acc * curr 값을 return하면서 하나의 값으로 줄여감
}, 1 // 초기값 1
);
```


## [이어 붙인 수](https://school.programmers.co.kr/learn/courses/30/lessons/181928)

### 문제
정수가 담긴 리스트 `num_list`가 주어집니다. `num_list`의 홀수만 순서대로 이어 붙인 수와 짝수만 순서대로 이어 붙인 수의 합을 return하도록 solution 함수를 완성해주세요.

- 제한사항
	- 2 ≤ `num_list`의 길이 ≤ 10
	- 1 ≤ `num_list`의 원소 ≤ 9
	- `num_list`에는 적어도 한 개씩의 짝수와 홀수가 있습니다.

### 소스 코드
```javascript
const readline = require('readline');
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

let input = '';

rl.on('line', (line) => {
  input = line.split(' ').map(Number);
  rl.close();
}).on('close', () => {
  const answer = solution(input);
  console.log(answer);
});

const solution = (num_list) => {
  let odd = '';
  let even = '';

  num_list.map(item => {
    if (item % 2 === 0) {
      even += item;
    } else {
      odd += item;
    }
  });

  return Number(odd) + Number(even);
};
```

## 참고 자료
- [Infinity, MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Infinity)
- [NaN, MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN)
