この記事は、mae616 Advent of Code Advent Calendar 2024 の7日目の記事です。
このアドベントカレンダーは皆勤賞のQiitaくんのぬいぐるみに惹かれて挑戦している大変ゆるい挑戦のものです。そんな感じで読んでいただければ幸いです。
今日は出かける予定があったので、そういう時はアドベントカレンダーを毎日書くのは結構大変ですね ꉂꉂ( ᐛ )
前の日: [Advent of Code 2024] Day 6: Guard Gallivant
次の日: [Advent of Code 2024] Day 8: Resonant Collinearity
今日のお題
7日目の物語
■ 7日目: 橋の修理
歴史学者たちは、ジャングルの中にある川を渡る『見覚えのあるロープ橋』へと案内してくれます。でも、橋のこちら側には長老がいませんね。もしかしたら向こう側にいるのかも?
今度はジャングルですね。
『見覚えのあるロープ橋』は、Advent of Code 2022と繋がっているようです。
長老もその時登場したのですかね。初見なのでよくわかってないです٩( ᐛ )و
橋を渡ろうとしたとき、修理中のエンジニアたちのグループに気づきます。(どうやら、この橋はよく壊れるみたいです。)修理が終わるまで、渡れません。
前に出てきたプリンター🖨️といい、いろんなものがよく壊れますね ꉂꉂ( ᐛ )
どれくらい時間がかかるか尋ねると、エンジニアたちは、「最終調整が必要なだけだ」と言います。ただ、近くで遊んでいた若いゾウたちが、調整用の方程式に使う演算子を全部持って行っちゃったらしいんです!
もし誰かが、どのテスト値がその方程式に演算子を組み合わせて作れるかを判断できれば、調整を終わらせることができるのに…(これがあなたのパズルの入力です)。
今度はゾウ🐘ですか。いろいろ大変ですね ꉂꉂ( ᐛ )
ところでこのいつもパズルを解いてる”あなた”はどういう人なのでしょうか?
歴史学者とは違うようですよね。
今度、Advent of Codeの過去のやってみようかな٩( ᐛ )و
1問目
例:
190: 10 19
3267: 81 40 27
83: 17 5
156: 15 6
7290: 6 8 6 15
161011: 16 10 13
192: 17 8 14
21037: 9 7 18 13
292: 11 6 16 20
さてと、ええと。今日はもう疲れちゃったので頭が回んないですね ꉂꉂ( ᐛ )
問題を読むのも一苦労です ꉂꉂ( ᐛ )
各行が1つの方程式を表しています
(例えば、最初の 190: 10 19
で一つの方程式です)
テスト値は各行のコロンの前にあります。
(ここでは例えば 190
)
あなたの仕事は、残りの数字を演算子で組み合わせてテスト値を出せるかどうかを判断することです。
( 10
と 19
を何らかの演算子で演算すれば 190
になるか、を判断する)。
演算子は常に左から右に評価されます、優先順位のルールに従って評価されるわけではありません。さらに、方程式内の数字を並べ替えることはできません。
ジャングルの中をちらっと見ると、ゾウたちが2種類の演算子を持っているのが見えます:加算(+)と乗算(*)です。
例では、
190: 10 19
は 10 * 19 = 190
なのでOK
3267: 81 40 27
も 81 + 40 * 27 = 3267
もしくは 81 * 40 + 27 = 3267
となるのでOK
292: 11 6 16 20
も 11 + 6 * 16 + 20 = 292
でOK
3つがOKになり 190 + 3267 + 292 =
の 3749
が答えになる。
んー貪欲法かな?٩( ᐛ )و
解いたコード
function main(input) {
const args = input.split("\n");
const test = [];
const terms = [];
for (const arg of args) {
if (arg === "") continue;
const [left, right] = arg.split(": ");
test.push(Number(left));
terms.push(right.split(" ").map(Number));
}
let sum = 0;
for (let i = 0; i < test.length; i++) {
const currentTerms = terms[i];
const n = currentTerms.length;
let cancel = false;
(function recursion(index, total) {
if (cancel) return;
if (index === n) {
if (total === test[i]) {
sum += test[i];
cancel = true;
}
return;
}
recursion(index + 1, total + currentTerms[index]);
recursion(index + 1, total * currentTerms[index]);
})(0, 0);
}
console.log(sum);
}
main(require("fs").readFileSync("./input/puzzle.txt", "utf8"));
cd day7_1
node main.js
で実行できます。
2問目
ゾウ🐘が演算子を一つ隠していたようです。
演算子 ||
... 左右の入力から数字を結合して一つの数にする(例えば 12 || 345
は 12345
になるようです)
で、すべての演算子は、依然として左から右へ評価される、と。
ちなみにその場合の例での答えは 11387
になるようです。
今日は疲れていたので、2問目がそこまで難しくなくてよかったです٩( ᐛ )و
さて、やりましょう。
解いたコード
function main(input) {
const args = input.split("\n");
const test = [];
const terms = [];
for (const arg of args) {
if (arg === "") continue;
const [left, right] = arg.split(": ");
test.push(Number(left));
terms.push(right.split(" ").map(Number));
}
let sum = 0;
for (let i = 0; i < test.length; i++) {
const currentTerms = terms[i];
const n = currentTerms.length;
let cancel = false;
(function recursion(index, total) {
if (cancel) return;
if (index === n) {
if (total === test[i]) {
sum += test[i];
cancel = true;
}
return;
}
recursion(index + 1, total + currentTerms[index]);
recursion(index + 1, total * currentTerms[index]);
recursion(index + 1, Number(`${total}${currentTerms[index]}`));
})(0, 0);
}
console.log(sum);
}
main(require("fs").readFileSync("./input/puzzle.txt", "utf8"));
1行足しただけでいけました٩( ᐛ )و
今日は終わり!おつかれさまです٩( ᐛ )و
今日の海外の人
https://www.reddit.com/r/adventofcode/
なんか2問目の計算量について議論しているようですね...
自分はまだその域にいけないのでまだまだです ꉂꉂ( ᐛ )
では、また明日。