はじめに
Advent of code 2024 の準備として、過去回の Advent of code 2015 を Livebook で楽しみます
本記事では Day 16 の Part 1 と Part 2 を解きます
問題文はこちら
実装したノートブックはこちら
セットアップ
Kino AOC をインストールします
Mix.install([
{:kino_aoc, "~> 0.1"}
])
Kino AOC の使い方はこちらを参照
入力の取得
"Advent of Code Helper" スマートセルを追加し、 Day 16 の入力を取得します
私の答え
私の答えです。
折りたたんでおきます。
▶を押して開いてください。
Part 1
回答
入力を正規表現でパースします
sue_list =
puzzle_input
|> String.split("\n")
|> Enum.with_index(1)
|> Enum.map(fn {row, index} ->
Regex.scan(~r/[a-z]+: [0-9]+/, row)
|> Enum.into(%{}, fn [item] ->
Regex.named_captures(~r/(?<name>[a-z]+): (?<number>[0-9]+)/, item)
|> then(fn %{"name" => name, "number" => number} ->
{String.to_atom(name), String.to_integer(number)}
end)
end)
|> Map.put(:index, index)
end)
実行結果
[
%{index: 1, children: 1, vizslas: 7, cars: 8},
%{index: 2, children: 5, akitas: 10, perfumes: 10},
%{index: 3, pomeranians: 4, vizslas: 1, cars: 5},
...
]
問題文内の MFCSAM の出力を定義します
mfscam =
%{
children: 3,
cats: 7,
samoyeds: 2,
pomeranians: 3,
akitas: 0,
vizslas: 0,
goldfish: 5,
trees: 3,
cars: 2,
perfumes: 1
}
各スーおばさんについて、 MFCSAM と同じ項目のものは全て同じ値になっているか、をチェックし、該当するスーおばさんの番号を取得します
sue_list
|> Enum.find(fn sue ->
sue
|> Map.delete(:index)
|> Enum.filter(fn {key, _} ->
mfscam
|> Map.keys()
|> Enum.member?(key)
end)
|> Enum.all?(fn {key, value} ->
Map.get(mfscam, key) == value
end)
end)
|> Map.get(:index)
Part 2
回答
項目によって値の比較条件が変わっただけです
sue_list
|> Enum.find(fn sue ->
sue
|> Map.delete(:index)
|> Enum.filter(fn {key, _} ->
mfscam
|> Map.keys()
|> Enum.member?(key)
end)
|> Enum.all?(fn {key, value} ->
scam_value = Map.get(mfscam, key)
cond do
Enum.member?([:cats, :trees], key) ->
scam_value < value
Enum.member?([:pomeranians, :goldfish], key) ->
scam_value > value
true ->
scam_value == value
end
end)
end)
|> Map.get(:index)
まとめ
問題文から ChatGPT に画像を生成してもらいました
問題文が無駄にややこしいだけで、問題としては素直に解くだけでした