프로그래밍/알고리즘 풀이
[node.js] 단어 수학 ( 백준 1339번)
카카수(kakasoo)
2021. 7. 31. 15:59
반응형
const readline = require("readline");
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
let count;
const input = [];
let maxValue = -987654321;
rl.on("line", (line) => {
if (!count) {
count = Number(line);
} else {
input.push(line);
if (input.length === count) {
main();
}
}
});
const getPermutations = function* (elements) {
if (elements.length === 1) {
yield elements;
} else {
const [first, ...rest] = elements;
for (const a of getPermutations(rest)) {
for (let i = 0; i < elements.length; i++) {
const start = a.slice(0, i);
const ended = a.slice(i);
yield [...start, first, ...ended];
}
}
}
};
const isMax = function* (iterable) {
for (const a of iterable) {
const numberChanged = input
.map((el) => {
const arr = el.split("");
return arr
.map((el) => {
return a.findIndex((target) => target === el);
})
.join("");
})
.map(Number);
const sum = numberChanged.reduce((acc, cur) => (acc += cur), 0);
if (sum > maxValue) {
maxValue = sum;
yield sum;
}
}
};
const main = () => {
const alphabets = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J"];
[...isMax(getPermutations(alphabets))];
console.log(maxValue);
};
원래는 이처럼 순열을 이용해서 풀려고 했다.
다른 언어에서도 아마 이런 방법을 사용해서 풀려고 하지 않았을까 싶었지만, 자바스크립트는 콜 스택이 터지면서 문제가 발생했다.
그래서 메모리와 스택의 소모를 줄이기 위해서 제너레이터를 만들어 적극 활용하기로 했다.
결과적으로 시간초과가 발생했다...
Lazy하게 함수를 만드는 것은 좋지만, 이로 인해 지연 함수는 더 느리다는 단점이 부각된 것으로 보인다.
원래대로면 불필요한 연산을 줄임으로써 빨라지기도 하지만, 이 경우에는 어차피 모든 경우를 탐색해야 함에도 불구하고, Lazy를 썼으니 메모리를 아끼고자 성능을 줄인 것에 불과했을 것이다.
const readline = require("readline");
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
// 2
// AAA
// AAA => { A: 222 }
// 위와 같은 형태로, 자릿수에 맞게 사용된 횟수를 기록한 후, 높은 자릿수부터 큰 수를 대입해본다.
const makeAlphabetObj = (input) => {
const obj = {};
input.slice(1).map((str) => {
str.split("")
.reverse()
.forEach((el, i) => {
obj[el] = !obj[el] ? 10 ** i : obj[el] + 10 ** i;
});
});
return obj;
};
const solution = (input) => {
const obj = makeAlphabetObj(input);
const objToArr = Object.entries(obj).sort((a, b) => b[1] - a[1]);
let number = 9;
let sum = 0;
for (const a of objToArr) {
sum += a[1] * number--;
}
return sum;
};
const input = [];
rl.on("line", (line) => {
input.push(line);
}).on("close", () => {
console.log(solution(input));
process.exit();
});
그래서 자료구조를 적극 활용하는 방법을 사용했다.
이 코드는 다른 분의 블로그를 참고해서 작성한 것인데, 내 나름대로 코드를 수정해보았다.
( 핵심이 되는 생각은, 그 분의 생각을 참고했다. )
자바스크립트는 아직 다른 언어에 비해 불리한 점이 많은 것 같은데, 이를 어떻게 극복할지가 앞으로의 관건으로 보인다.
하면서도 스트레스를 받는 일이긴 하지만, 극복해가는 과정 속에서, 자바스크립트를 더 효율적으로 다루는 법을 알 수 있을 것 같다
반응형