AtCoder に登録したら次にやること ~ これだけ解けば十分闘える!過去問精選 10 問 ~で
紹介されていた問題をJavaScript(Node.js)で解いてみました。
他言語で解いた記事はありますが、まだJavaScript版がない。
そして競技プログラミングだとJavaScriptはあまり使われない印象なので、
今回はあえてJavaScriptで挑みました。
競技プログラミングの問題を解くのが初なので、
最適解にはなっていないかもしれませんが、ご了承ください。
※問題の解説については、上記記事にわかりやすい解法が載っているので割愛します。
標準入出力
ここの「JavaScript(Node.js) での解答例」が非常にわかりやすいです。
function main(input) {
console.log(input);
}
main(require('fs').readFileSync('/dev/stdin', 'utf8'));
第1問: ABC 086 A - Product
二つの整数 a,bの積の偶奇を判定する。
function main(input) {
const args = input.split(' ');
const a = parseInt(args[0], 10);
const b = parseInt(args[1], 10);
if ((a * b) % 2 === 0) {
console.log('Even');
} else {
console.log('Odd');
}
}
main(require('fs').readFileSync('/dev/stdin', 'utf8'));
第2問: ABC 081 A - Placing Marbles
文字列内の、1の個数をカウントする。
function main(input) {
console.log(input.split('1').length - 1);
}
main(require('fs').readFileSync('/dev/stdin', 'utf8'));
第3問: ABC 081 B - Shift Only
N個の整数を同時に、割り切れなくなるまで割っていった場合、何回割ることができるかを求める。
function main(input) {
var nums = input.split('\n')[1].split(' ').map((n) => parseInt(n, 10));
var count = 0;
while(nums.every((n) => (n % 2) === 0)) {
count++;
nums = nums.map((n) => n / 2);
}
console.log(count);
}
main(require('fs').readFileSync('/dev/stdin', 'utf8'));
第4問: ABC 087 B - Coins
500円玉、100円玉、50円玉を使ってX円を支払う方法が何通りあるかを求める。
function main(input) {
const args = input.split('\n');
const A = parseInt(args[0], 10),
B = parseInt(args[1], 10),
C = parseInt(args[2], 10),
X = parseInt(args[3], 10);
var count = 0;
for (var a = 0; a <= A; ++a) {
for (var b = 0; b <= B; ++b) {
for (var c = 0; c <= C; ++c) {
var sum = (a * 500) + (b * 100) + (c * 50);
if (sum === X) ++count;
}
}
}
console.log(count);
}
main(require('fs').readFileSync('/dev/stdin', 'utf8'));
第5問: ABC 083 B - Some Sums
1以上N以下の整数のうち、各桁の和がA以上B以下であるものの総和を求める。
function main(input) {
const args = input.split(' ');
const N = parseInt(args[0], 10),
A = parseInt(args[1], 10),
B = parseInt(args[2], 10);
const nums = Array.from(new Array(N), (v, i) => ++i).filter((i) => {
var n = i.toString().split('').reduce((p, c) => p + parseInt(c), 0);
return (n >= A && n <= B);
});
console.log(nums.reduce((p, c) => p + c, 0));
}
main(require('fs').readFileSync('/dev/stdin', 'utf8'));
第6問: ABC 088 B - Card Game for Two
N枚のカードを交互に自身の得点が最大になるように取っていった場合の、二人の得点の差分を求める。
function main(input) {
const args = input.split('\n');
const N = parseInt(args[0], 10),
cards = args[1].split(' ').map(n => parseInt(n, 10));
var aSum = 0,
bSum = 0;
cards.sort((a, b) => (a < b ? 1 : -1)).forEach((n, i) => {
(i % 2 === 0)? aSum += n : bSum += n;
});
console.log(aSum - bSum);
}
main(require('fs').readFileSync('/dev/stdin', 'utf8'));
第7問: ABC 085 B - Kagami Mochi
N個の整数の重複しない値の数を求める。
function main(input) {
const args = input.split('\n');
const N = args[0],
nums = args.slice(1, args.length - 1);
console.log(nums.filter((n, i) => nums.indexOf(n) === i).length);
}
main(require('fs').readFileSync('/dev/stdin', 'utf8'));
第8問: ABC 085 C - Otoshidama
10000円札、5000円札、1000円札がある前提で、合計がN枚、Y円になる組み合わせを求める。
function main(input) {
const args = input.split(' ');
const N = parseInt(args[0], 10),
Y = parseInt(args[1], 10);
var result = '-1 -1 -1';
for (var a = 0; a <= N; a++) {
for (var b = 0; b <= N; b++) {
if ((a + b) > N) {
continue;
}
var sum = (a * 10000) + (b * 5000) + ((N - a - b) * 1000);
if (sum === Y) {
result = `${a} ${b} ${N - a - b}`;
break;
}
}
}
console.log(result);
}
main(require('fs').readFileSync('/dev/stdin', 'utf8'));
第9問: ABC 049 C - Daydream
文字列Sが、"dream", "dreamer", "erase", "eraser"の組み合わせで作れるかどうかを判定する。
function main(input) {
const reverse = (s) => {
return s.split('').reverse().join('');
};
const WORDS = ['dream', 'dreamer', 'erase', 'eraser'].map(reverse);
const S = reverse(input.split('\n')[0]);
var index = 0;
while(true) {
var w = WORDS.find((w) => S.startsWith(w, index));
if (!w) break;
index += w.length;
}
if (S.length === index) {
console.log('YES');
} else {
console.log('NO');
}
}
main(require('fs').readFileSync('/dev/stdin', 'utf8'));
第10問: ABC 086 C - Traveling
座標(0, 0)を出発地点とした場合、時刻ti時点で(xi, yi)にいることができるかどうかを判定する。
function main(input) {
const args = input.split('\n');
const N = parseInt(args[0], 10);
const nums = args.slice(1, N + 1);
const isValid = nums.every((n) => {
var ns = n.split(' ');
var t = parseInt(ns[0], 10),
x = parseInt(ns[1], 10),
y = parseInt(ns[2], 10);
var sum = x + y;
return (t >= sum) && ((t % 2) === (sum % 2));
});
if (isValid) {
console.log('Yes');
} else {
console.log('No');
}
}
main(require('fs').readFileSync('/dev/stdin', 'utf8'));
おわりに
分割代入を使いたい場面が多々あるので、Node.jsのサポートバージョンがv5.12なのが少し残念。
このバージョンだとサポートされていない...。(近いうちにサポートバージョンが上がるはず!)
次はもう少し難しい問題にも挑戦してみようと思います。もちろんJavaScriptで。