9
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 5

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

Last updated at Posted at 2024-12-04

はじめに

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

問題文はこちら

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

セットアップ

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

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

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

入力の取得

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

スクリーンショット 2024-12-04 19.17.43.png

私の答え

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

回答

まずは小さい入力例で解いてみます

input =
  """
  MMMSXXMASM
  MSAMXMSMSA
  AMXSXMAAMM
  MSAMASMSMX
  XMASAMXAMM
  XXAMMXXAMA
  SMSMSASXSS
  SAXAMASAAA
  MAMMMXMMMM
  MXMXAXMASX
  """

斜めに読んで MAS を探すため、入力をずらして回転します

turned_input =
  input
  |> String.trim()
  |> String.split("\n")
  |> Enum.with_index()
  |> Enum.map(fn {row, index} ->
    String.duplicate(".", index) <> row <> String.duplicate(".", String.length(row) - index - 1)
  end)
  |> Enum.map(&String.codepoints(&1))
  |> Enum.zip()
  |> Enum.map(fn col -> col |> Tuple.to_list() |> Enum.join() end)
  |> Enum.join("\n")

IO.puts(turned_input)

標準出力

M.........
MM........
MSA.......
SAMM......
XMXSX.....
XXSAMX....
MMXMAXS...
ASMASAMS..
SMASAMSAM.
MSAMMMMXAM
.AMSXXSAMX
..MMAXAMMM
...XMASAMX
....MMXSXA
.....ASAMX
......SAMM
.......AMA
........MS
.........X

斜めの中で MASM+SSAMS+M に変換します

turned_input
|> String.replace(~r/MAS/, "M+S")
|> String.replace(~r/SAM/, "S+M")
|> IO.puts()

標準出力

M.........
MM........
MSA.......
S+MM......
XMXSX.....
XXS+MX....
MMXMAXS...
ASM+S+MS..
SM+S+MS+M.
MS+MMMMXAM
.AMSXXS+MX
..MMAXAMMM
...XM+S+MX
....MMXSXA
.....AS+MX
......S+MM
.......AMA
........MS
.........X

元の角度に戻して + 以外を . に変換して見やすくします

output_a =
  turned_input
  |> String.replace(~r/MAS/, "M+S")
  |> String.replace(~r/SAM/, "S+M")
  |> String.split("\n")
  |> Enum.map(&String.codepoints(&1))
  |> Enum.zip()
  |> Enum.map(fn col ->
    col
    |> Tuple.to_list()
    |> Enum.join()
    |> String.trim(".")
    |> String.replace(~r/[A-Z]/, ".")
  end)

output_a
|> Enum.join("\n")
|> IO.puts()

標準出力

..........
..+.......
......++..
..+.+.....
....+.....
..+....+..
..........
.+.+.+.++.
..........
..........

逆方向の斜めで読んだとき、同じ位置に + があれば、交差したとみなすことができます

逆方向で試す前に、回転と置換を関数化しておきます

turn = fn input, direction ->
  input
  |> String.trim()
  |> String.split("\n")
  |> Enum.with_index()
  |> Enum.map(fn {row, index} ->
    case direction do
      :left ->
        String.duplicate(".", index) <> row <> String.duplicate(".", String.length(row) - index - 1)
      _ ->
        String.duplicate(".", String.length(row) - index - 1) <> row <> String.duplicate(".", index)
    end
  end)
  |> Enum.map(&String.codepoints(&1))
  |> Enum.zip()
  |> Enum.map(fn col -> col |> Tuple.to_list() |> Enum.join() end)
  |> Enum.join("\n")
end
replase_mas = fn turned_input ->
  turned_input
  |> String.replace(~r/MAS/, "M+S")
  |> String.replace(~r/SAM/, "S+M")
  |> String.split("\n")
  |> Enum.map(&String.codepoints(&1))
  |> Enum.zip()
  |> Enum.map(fn col ->
    col
    |> Tuple.to_list()
    |> Enum.join()
    |> String.trim(".")
    |> String.replace(~r/[A-Z]/, ".")
  end)
end

関数を使って回転と置換を実行します

output_b =
  input
  |> turn.(:right)
  |> replase_mas.()

output_b
|> Enum.join("\n")
|> IO.puts()

標準出力

..........
..+.......
......++..
..+.+.....
..+.......
..........
.....+....
.+.+.+.+..
.+........
..........

MAS が交差した点 = 左回転した方と右回転した方の両方で + になった点を数えます

Enum.zip(output_a, output_b)
|> Enum.map(fn {row_a, row_b} ->
  Enum.zip(
    String.codepoints(row_a),
    String.codepoints(row_b)
  )
  |> Enum.count(fn ab -> ab == {"+", "+"} end)
end)
|> Enum.sum()

実行結果

9

同じことを実際の入力に対して実行します

output_a =
  puzzle_input
  |> turn.(:left)
  |> replase_mas.()

output_b =
  puzzle_input
  |> turn.(:right)
  |> replase_mas.()

Enum.zip(output_a, output_b)
|> Enum.map(fn {row_a, row_b} ->
  Enum.zip(
    String.codepoints(row_a),
    String.codepoints(row_b)
  )
  |> Enum.count(fn ab -> ab == {"+", "+"} end)
end)
|> Enum.sum()

まとめ

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

aoc2024_day4_2.png

「交差する点」をどう探すかが面白い問題でした

Part 1 もそうですが、出力がアートのようになってキレイですね

9
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
9
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?