7
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ElixirAdvent Calendar 2024

Day 7

Advent of code 2024 Day 5 Part 2 を Livebook で楽しむ

Last updated at Posted at 2024-12-05

はじめに

Advent of code 2024 Day 5 の Part 2 を解きます

問題文はこちら

実装したノートブックはこちら

Part 1 はこちら

セットアップ

Kino AOC をインストールします

Mix.install([
  {:kino_aoc, "~> 0.1"}
])

Kino AOC の使い方はこちらを参照

入力の取得

"Advent of Code Helper" スマートセルを追加し、 Day 5 の入力を取得します

スクリーンショット 2024-12-06 0.57.41.png

私の答え

私の答えです。
折りたたんでおきます。
▶を押して開いてください。

回答

入力の読込処理は Part 1 と同じです

Part 2 では誤っている更新について修正する必要があります

誤った更新の探索は Part 1 の逆を実行すればよいだけなので、末尾に |> then(&(not &1)) をつけるだけです

修正処理では、前後関係が誤っている箇所について、位置を入れ替えます

入れ替えた結果、以前は正しかった前後関係が誤った状態になる可能性があるため、修正した場合は改めて先頭のルールからチェックし直す必要があります

再帰処理が必要なため、モジュール化しました

defmodule Fixer do
  def get_wrong_updates(updates, rules) do
    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)
      |> then(&(not &1))
    end)
  end

  def fix_update(update, rules) do
    rules
    |> Enum.reduce(update, fn {a, b}, acc_update ->
      a_index = Enum.find_index(acc_update, &(&1 ==a))
      b_index = Enum.find_index(acc_update, &(&1 ==b))

      if is_nil(a_index) or is_nil(b_index) do
        acc_update
      else
        if a_index < b_index do
          acc_update
        else
          acc_update
          |> List.update_at(a_index, fn _ -> b end)
          |> List.update_at(b_index, fn _ -> a end)
          |> fix_update(rules)
        end
      end
    end)
  end
end

入力例に対して実行してみます

updates
|> Fixer.get_wrong_updates(rules)
|> Enum.map(fn update ->
  Fixer.fix_update(update, rules)
end)
|> Enum.map(fn update ->
  Enum.at(update, div(length(update), 2))
end)
|> Enum.sum()

実行結果

123

問題文と同じ値になりました

実際の入力に対して実行します

{rules, updates} = parse_input.(puzzle_input)

updates
|> Fixer.get_wrong_updates(rules)
|> Enum.map(fn update ->
  Fixer.fix_update(update, rules)
end)
|> Enum.map(fn update ->
  Enum.at(update, div(length(update), 2))
end)
|> Enum.sum()

まとめ

問題文から ChatGPT に画像を生成してもらいました

aoc2024_day5_2.png

修正処理で再帰的なチェックが必要で、そこで少し躓きました

7
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?