はじめに
Advent of code 2024 の準備として、過去回の Advent of code 2015 を Livebook で楽しみます
本記事では Day 19 の Part 2 を解きます
Part 1 と Part 2 の解き方が全く違ったので分けています
問題文はこちら
実装したノートブックはこちら
Part 1 はこちら
セットアップ
Kino AOC をインストールします
Mix.install([
{:kino_aoc, "~> 0.1"}
])
Kino AOC の使い方はこちらを参照
入力の取得
"Advent of Code Helper" スマートセルを追加し、 Day 19 の入力を取得します
私の答え
私の答えです。
折りたたんでおきます。
▶を押して開いてください。
回答
貪欲法などの探索を試してみましたがうまくいかず、 Reddit のスレッドを見てようやく解きました
https://www.reddit.com/r/adventofcode/comments/3xflz8/day_19_solutions/
置換のルールを見ると、実は規則的になっており、以下のように読み替えることができます
- Rn:
(
- Ar:
)
- Y:
,
例えば SiRnFYFAr
は Si(F,F)
を表しています
また、元素記号のように、 Si
などの大文字+小文字は一つの分子を表しています
CRnFYFYFArCaF
が入力とすると、前出の置換ルールを適用すれば C(F,F,F)CaF
となります
置換の数 = 全ての分子の数 - 1回の置換でついでに消すことができる分子の数なので、
全ての大文字の数 - (
の数 - )
の数 - ,
の数 * 2 - 1 が答えです
molecules =
puzzle_input
|> String.split("\n")
|> Enum.reverse()
|> hd()
count_str = fn molecules, str ->
Regex.scan(~r/#{str}/, molecules)
|> length()
end
Regex.scan(~r/[A-Z]/, molecules)
|> length()
|> Kernel.-(count_str.(molecules, "Rn"))
|> Kernel.-(count_str.(molecules, "Ar"))
|> Kernel.-(2 * count_str.(molecules, "Y"))
|> Kernel.-(1)
まとめ
Part 1 は単純でしたが、、、
Part 2 は入力を見て洞察しないと解けない問題でした