はじめに
Advent of code 2024 Day 5 の Part 1 を解きます
Part 2 の変更点が多いので別記事に分割しました
問題文はこちら
実装したノートブックはこちら
セットアップ
Kino AOC をインストールします
Mix.install([
{:kino_aoc, "~> 0.1"}
])
Kino AOC の使い方はこちらを参照
入力の取得
"Advent of Code Helper" スマートセルを追加し、 Day 5 の入力を取得します
私の答え
私の答えです。
折りたたんでおきます。
▶を押して開いてください。
回答
入力を読み込むための関数を用意します
parse_input = fn input ->
[rules, updates] =
input
|> String.split("\n\n")
|> Enum.map(&String.split(&1, "\n"))
rules =
rules
|> Enum.map(fn rule ->
rule
|> String.split("|")
|> Enum.map(&String.to_integer(&1))
|> List.to_tuple()
end)
updates =
updates
|> Enum.map(fn update ->
update
|> String.split(",")
|> Enum.map(&String.to_integer(&1))
end)
{rules, updates}
end
入力例で試してみます
{rules, updates} =
"""
47|53
97|13
97|61
97|47
75|29
61|13
75|53
29|13
97|29
53|29
61|53
97|53
61|29
47|13
75|47
97|75
47|61
75|61
47|29
75|13
53|13
75,47,61,53,29
97,61,53,29,13
75,29,13
75,97,47,61,53
61,13,29
97,13,75,29,47
"""
|> String.trim()
|> parse_input.()
実行結果
{[
{47, 53},
{97, 13},
{97, 61},
...
],
[
[75, 47, 61, 53, 29],
[97, 61, 53, 29, 13],
[75, 29, 13],
...
]}
正しい更新だけを抽出する関数を用意します
各ルールについて、前後の文字両方が存在していて、前後関係が誤っているものがあれば正しくない更新です
get_right_updates = fn updates, rules ->
updates
|> Enum.filter(fn update ->
rules
|> Enum.reduce_while(nil, fn {a, b}, _ ->
a_index = Enum.find_index(update, &(&1 ==a))
b_index = Enum.find_index(update, &(&1 ==b))
if is_nil(a_index) or is_nil(b_index) do
{:cont, true}
else
if a_index < b_index do
{:cont, true}
else
{:halt, false}
end
end
end)
end)
end
入力例で実行します
updates
|> get_right_updates.(rules)
|> Enum.map(fn update ->
Enum.at(update, div(length(update), 2))
end)
|> Enum.sum()
実行結果
143
問題文と同じ結果になりました
実際の入力で実行れば答えが出ます
{rules, updates} = parse_input.(puzzle_input)
updates
|> get_right_updates.(rules)
|> Enum.map(fn update ->
Enum.at(update, div(length(update), 2))
end)
|> Enum.sum()
まとめ
問題文から ChatGPT に画像を生成してもらいました
単純なチェックだけなので簡単ですね
Part 2 はこちら