Powered by AppSignal & Oban Pro

Advent of Code 2024 Day 6 Part 1

2024_day6_part1.livemd

Advent of Code 2024 Day 6 Part 1

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

Get Inputs

{:ok, puzzle_input} =
  KinoAOC.download_puzzle("2024", "6", System.fetch_env!("LB_SESSION"))

My answer

sample_input =
  """
  ....#.....
  .........#
  ..........
  ..#.......
  .......#..
  ..........
  .#..^.....
  ........#.
  #.........
  ......#...
  """
  |> String.trim()

Kino.Text.new(sample_input, terminal: true)
turn = fn input ->
  input
  |> String.replace("^", "<")
  |> String.split("\n")
  |> Enum.map(&String.codepoints(&1))
  |> Enum.zip()
  |> Enum.map(fn col -> col |> Tuple.to_list() |> Enum.join() end)
  |> Enum.reverse()
  |> Enum.join("\n")
end
[
  sample_input
  |> Kino.Text.new(terminal: true),
  sample_input
  |> turn.()
  |> Kino.Text.new(terminal: true),
  sample_input
  |> turn.()
  |> turn.()
  |> Kino.Text.new(terminal: true),
  sample_input
  |> turn.()
  |> turn.()
  |> turn.()
  |> Kino.Text.new(terminal: true),
]
|> Kino.Layout.grid(columns: 4)
Regex.scan(~r/#[^\n#]*</, ".#.X.#.#.X..<..")
Regex.scan(~r/#[^\n#]*</, "..X..<..")
turned_input = turn.(sample_input)

route =
  Regex.scan(~r/#[^\n#]*</, turned_input)
  |> hd()
  |> hd()
String.replace(
  turned_input,
  route,
  "#^" <> String.duplicate("X", String.length(route) - 2)
)
|> Kino.Text.new(terminal: true)
round = fn input ->
  Enum.reduce_while(1..1000, input, fn _, acc_input ->
    turned_input = turn.(acc_input)

    case Regex.scan(~r/#[^\n#]*</, turned_input) do
      [[route]] ->
        {
          :cont,
          String.replace(
            turned_input,
            route,
            "#^" <> String.duplicate("X", String.length(route) - 2)
          )
        }

      _ ->
        route =
          Regex.scan(~r/\.[^\n]*</, turned_input)
          |> hd()
          |> hd()

        {
          :halt,
          String.replace(
            turned_input,
            route,
            String.duplicate("X", String.length(route))
          )
        }
    end
  end)
end
rounded = round.(sample_input)

Kino.Text.new(rounded, terminal: true)
Regex.scan(~r/X/, rounded)
|> length()
Regex.scan(~r/X/, round.(puzzle_input))
|> length()