Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Advent of Code 2023 - Day 13

2023/13.livemd

Advent of Code 2023 - Day 13

Mix.install([
  {:kino, "~> 0.11.0"},
  {:kino_aoc, github: "ljgago/kino_aoc"}
])

Input

{:ok, puzzle_input} =
  KinoAOC.download_puzzle("2023", "13", System.fetch_env!("LB_AOC_SESSION"))
input =
  puzzle_input
  |> String.split("\n\n", trim: true)
  |> Enum.map(fn row ->
    row
    |> String.split("\n", trim: true)
    |> Enum.map(&String.graphemes/1)
  end)

Part 1

find_reflection = fn pattern, compare_fun ->
  count = Enum.count(pattern)

  Enum.find_index(0..(count - 2), fn i ->
    upper = Enum.slice(pattern, 0..i)
    lower = Enum.slice(pattern, (i + 1)..count)
    min = min(length(upper), length(lower))
    upper_cut = Enum.slice(upper, -min..-1)
    lower_cut = Enum.slice(lower, 0..(min - 1))

    compare_fun.(lower_cut, Enum.reverse(upper_cut))
  end)
end

summarize = fn pattern, compare_fun ->
  for pattern <- pattern, reduce: 0 do
    sum ->
      flipped = Enum.zip_with(pattern, &amp;Function.identity/1)

      ih = find_reflection.(pattern, compare_fun)
      iv = find_reflection.(flipped, compare_fun)

      case {ih, iv} do
        {i, nil} -> sum + (i + 1) * 100
        {nil, i} -> sum + i + 1
      end
  end
end

input
|> summarize.(&amp;(&amp;1 == &amp;2))

Part 2

defmodule Part2 do
  def diff([], [], d), do: d
  def diff([a1 | ar], [b1 | br], d) when a1 != b1, do: diff(ar, br, d + 1)
  def diff([_ | ar], [_ | br], d), do: diff(ar, br, d)
end

input
|> summarize.(fn a, b ->
  a = List.flatten(a)
  b = List.flatten(b)

  Part2.diff(a, b, 0) == 1
end)

Run in Livebook