
파이썬만 하다가 JS하니까 왜... 재밌지?
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin").toString().trim().split(" ");
/* readline Module */
// 문제 풀이
function solution(input) {
// 답변 출력
console.log(input);
}
/* readline Module */
const readline = require("readline");
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
let input;
rl.on("line", function (line) {
input = line; // 입력받은 문자열, line
input = parseInt(line); // 형변환, parseInt
rl.close(); // 입력 종료
}).on("close", function () {
solution(input); // 문제 풀이 함수 호출
process.exit(); // 프로세스 종료
});
백준 문제를 풀이할 때는 더 간편한 fs 모듈을 이용하여 풀고 있지만,
회사별 코테 플랫폼마다 JS 입출력 방식이 다르기 때문에 미리 확인할 것.
let example = 'hello'
example.split('')
let arr = [...example]
let arr = Array.from(example)
let example = "hello";
console.log(example.at(-1)); // 출력: 'o'
console.log(example.at(-2)); // 출력: 'l'
혹은 위의 방법으로 리스트로 변경 후 arr.length - 1 로 접근해도 된다.
❌ 아래 코드는 100000000% 틀린 코드 ❌
switch (score) {
case score >= 90:
console.log("A")
break
case score >= 80:
console.log("B")
break
case score >= 70:
console.log("C")
break
case score >= 60:
console.log("D")
break
default:
console.log("F")
break
}
case score = 90: 처럼 정확한 값을 주어야 한다.
이런경우는 switch가 아닌 if~else 문으로 작성해주어야 함.
if (score >= 90) {
console.log("A")
} else if (score >= 80) {
console.log("B")
} else if (score >= 70) {
console.log("C")
} else if (score >= 60) {
console.log("D")
} else {
console.log("F")
}
JS에서 배열을 만드는 것은 []템플릿을 활용하면 쉽다.
다만, 알고리즘 문제를 풀면서 모든 인덱스의 값을 0으로 초기화하고
해당 인덱스의 해당하는 값에 1씩 더하면서
무언가를 카운트 할때는 템플릿 보단 아래의 방법으로 생성하는게 좋다.
answer_array = new Array(10).fill(0)
위 처럼 안하고 템플릿에 접근하면 undefined + 1 이되어 NaN이 되기 때문.
for...of 문 => 파이썬의 for in 문과 정확히 동일한 역할을 한다.forEach => 배열 요소 각각에 대해 제공한 콜백함수를 실행하게 된다.for (let cases of arr) {
let A = cases[0]
let B = cases[1]
console.log(A + B)
}
arr.forEach(pair => {
let A = pair[0]
let B = pair[1]
console.log(A + B)
})
forEach각 요소를 순차적으로 실행(즉, 요소를 하나씩 다룰때)const numbers = [1, 2, 3, 4, 5];
numbers.forEach(num => console.log(num)); // 1 2 3 4 5
reduce하나의 값으로 누적시 사용const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((acc, num) => acc + num, 0);
console.log(sum); // 출력: 15
JS에선 append 아니고 push!
result = []
for (let elems of arr) {
if (elems < X) {
result.push(elems)
}
}
전개 연산자로 배열을 풀어준 다음에 Math.max 메서드를 활용
Math.max(...arr);
indexOf()인덱스를 리턴한다find()첫 요소를 반환findIndex()첫 요소를 반환const people = [
{ name: "Alice", age: 25 },
{ name: "Bob", age: 30 },
{ name: "Charlie", age: 35 },
{ name: "David", age: 40 }
];
const names = ["Alice", "Bob", "Charlie", "David"];
// indexOf
const index = names.indexOf("Charlie");
console.log(index); // 출력: 2
// find
const foundPerson = people.find(person => person.name === "Charlie");
console.log(foundPerson); // 출력: { name: "Charlie", age: 35 }
// findIndex
const indexOfPerson = people.findIndex(person => person.age === 35);
console.log(indexOfPerson); // 출력: 2
concat()
두 개의 배열을 하나로 만들때 + 연산자가 아니고 concat을 활용해야 한다.
slice(start, end)
어떤 배열을 start 부터 end -1 까지 자른다(파이썬의 range 와 범위가 똑같다)
단, 원본을 대체하지 않고, 새로운 배열로 복사한다.
// ✅
merged_arr = merged_arr.concat(low_arr.slice(l)).concat(high_arr.slice(h));
// ❌
merged_arr += low_arr.slice(l,)
merged_arr += high_arr.slice(h,)
filter(callbackFn)const words = ["spray", "elite", "exuberant", "destruction", "present"];
// 문자열 길이가 6 미만인 것 제거
const result = words.filter((word) => word.length > 6);
console.log(result);
// Expected output: Array ["exuberant", "destruction", "present"]
splice(start[, deleteCount[, item1[, item2[, ...]]]])원본배열의 값을 바꾼다는 것에 유의!var myFish = ["angel", "clown", "drum", "mandarin", "sturgeon"];
var removed = myFish.splice(3, 1); //["angel", "clown", "drum", "sturgeon"]
JS는 파이썬처럼 문자열에 숫자를 곱한다고 문자열 반복이 발생하지 않는다.
아래와 같이 repeat() 메서드를 활용해야 한다.
console.log("*".repeat(i))
console.log(input.charCodeAt())
숫자 정렬하듯이 문자열의 길이를 넘겨주면 된다.
string_list.sort((prev, cur) => prev.length - cur.length)
console.log 활용 코드const fs = require('fs')
const input = fs.readFileSync('/dev/stdin').toString().trim()
let N = parseInt(input)
function hanoi(N, start, end, sub) {
if (N == 1) {
console.log(start, end)
} else {
hanoi(N - 1, start, sub, end)
console.log(start, end)
hanoi(N - 1, sub, end, start)
}
}
console.log((BigInt(2) ** BigInt(N) - BigInt(1)).toString());
if (N <= 20) {
hanoi(N, 1, 3, 2)
}
// 하노이탑
// hanoi(3) => 2개의 원판 A -> B (C 경유)
// 3번째 원판 A -> C
// 나머지 2개의 원판 B -> C (A 경유)
const fs = require('fs')
const input = fs.readFileSync('input.txt').toString().trim()
let N = parseInt(input)
// console.log는 시간 초과가 날 수 있다
let result = []; // 결과 출력용 배열
function hanoi(N, start, end, sub) {
if (N == 1) {
result.push(`${start} ${end}`)
} else {
hanoi(N - 1, start, sub, end)
result.push(`${start} ${end}`)
hanoi(N - 1, sub, end, start)
}
}
console.log((BigInt(2) ** BigInt(N) - BigInt(1)).toString());
if (N <= 20) {
hanoi(N, 1, 3, 2);
console.log(result.join('\n'))
}
sort()
파이썬은 문자, 숫자 가리지 않고 정렬해주지만 우리의 JS는 그렇지 않다.
아무런 인자 없이 sort()만 사용하게 되면 문자열을 기준으로 정렬하게 된다.
오름차순으로 숫자를 정렬하려면?
arr.sort((a,b) => a - b);
위와 같이 해야 숫자가 오름차순으로 정렬되며,b - a를 하게 되면 내림차순으로 큰 수부터 앞에 온다.
JS에는 Itertools 처럼 모듈이 없기 때문에 직접 한땀한땀 구현해야한다.
const getPerm = (arr, n) => {
// 하나만 뽑는 경우 원소 하나씩 리턴
if (n == 1) return arr.map(el => [el]);
const result = [];
// 입력으로 받은 배열을 반복문 돌리기
// fixed : 고정된 부분, 이 고정된 부분을 제외하고 나머지 모든 배열이 순열 대상
// 해당 원소를 다시 포함시켜 순서가 다른 경우도 고려
arr.forEach((fixed, idx, origin) => {
// Fixed 부분을 제외한 나머지 원소들로 배열 다시 제작
const rest = [...origin.slice(0, idx), ...origin.slice(idx + 1)]
// 순열 재귀적으로 돌리기
const perms = getPerm(rest, n - 1)
// 각각 만들어진 순열 앞에 고정된 부분 붙이기
const attached = perms.map(perm => [fixed, ...perm])
// 결과 값 모아두는 배열에 푸시
result.push(...attached)
});
return result
}
const getCombination = (arr, n) => {
if (n === 1) return arr.map(el => [el]);
// 최종 결과를 담을 배열
const result = [];
// fixed : 고정할 원소, origin : 원본 배열
arr.forEach((fixed, idx, origin) => {
// 현재 고정한 원소 이후의 배열을 나머지로 선언
const rest = origin.slice(idx + 1);
// 나머지와 n-1을 다시 전달하여 재귀호출
const combis = getCombination(rest, n - 1);
// 재귀호출이 끝나고 돌아오는 시점은
// 처음 고정한 fixed로 구성 가능한 모든 조합을 리턴받은 이후
// 따라서 리턴받은 값과 fixed를 다시 합쳐주어 조합 구성
const attached = combis.map(combi => [fixed, ...combi]);
// 구성된 조합 배열을 결과에 푸시
result.push(...attached);
});
// 위에서 모든 재귀호출이 종료되면 저장된 조합 경우의 수 리턴
return result;
}
파이썬에서 모듈을 통해 쉽게 구현했던 것을
직접 구현할 때 조금 어려움을 겪었다, 추후 C언어 활용시 정렬도 다 구현해야하는데...
기본 원리를 좀 더 이해하는 노력이 필요하다.