はじめに
Advent of code 2024 Day 2 の Part 1 と Part 2 を解きます
問題文はこちら
実装したノートブックはこちら
セットアップ
Kino AOC をインストールします
Mix.install([
{:kino_aoc, "~> 0.1"}
])
Kino AOC の使い方はこちらを参照
入力の取得
"Advent of Code Helper" スマートセルを追加し、 Day 2 の入力を取得します
私の答え
私の答えです。
折りたたんでおきます。
▶を押して開いてください。
Part 1
回答
まず入力を読み込みます
reports =
puzzle_input
|> String.split("\n")
|> Enum.map(fn row ->
row
|> String.split(" ")
|> Enum.map(&String.to_integer(&1))
end)
第1段階として、単調減少または単調増加しているかをチェックします
ソートした結果とソートする前が一致していれば、必ず単調減少または単調増加しています
次に一つずらした配列を作り、次のレベルとの差が 1 〜 3 になっているかをチェックします
reports
|> Enum.filter(fn report ->
Enum.sort(report) == report or Enum.sort(report, :desc) == report
end)
|> Enum.filter(fn report ->
next_report = tl(report) ++ [nil]
Enum.zip([report, next_report])
|> Enum.all?(fn {current, next} ->
if is_nil(next) do
true
else
diff = abs(next - current)
diff > 0 and diff < 4
end
end)
end)
|> length()
Part 2
回答
ちょっと複雑ですが、各レポートにつき、1つレベルを削除したパターンを全て用意します
各パターンのうち、 Part 1 と同じ条件を満たすものが一つでもあれば、そのレポートは正常です
reports
|> Enum.filter(fn report ->
deleted =
1..length(report)
|> Enum.map(fn index ->
Enum.take(report, index - 1) ++ Enum.drop(report, index)
end)
[report | deleted]
|> Enum.filter(fn sub_report ->
Enum.sort(sub_report) == sub_report or Enum.sort(sub_report, :desc) == sub_report
end)
|> Enum.find(fn sub_report ->
next_report = tl(sub_report) ++ [nil]
Enum.zip([sub_report, next_report])
|> Enum.all?(fn {current, next} ->
if is_nil(next) do
true
else
diff = abs(next - current)
diff > 0 and diff < 4
end
end)
end)
|> then(&!is_nil(&1))
end)
|> length()
まとめ
問題文から ChatGPT に画像を生成してもらいました
Day 2 ですが、結構ややこしい問題でした
年々難しくなっていっているのかもしれません