diff --git a/lib/common.ex b/lib/common.ex index 1fab35c..1de2d69 100644 --- a/lib/common.ex +++ b/lib/common.ex @@ -37,7 +37,9 @@ defmodule Aoc2023.Common do def lines(x), do: String.split(x, "\n") def head([head | _]), do: head + def head([]), do: nil def tail([_ | tail]), do: tail + def tail([]), do: nil def lcm(a, b), do: div(abs(a*b), Integer.gcd(a,b)) def lcm(ls), do: ls |> Enum.reduce(&lcm/2) @@ -55,6 +57,6 @@ defmodule Aoc2023.Common do |> Stream.map(pipe(elem(0))) end - def repeat(lst, 0), do: [] + def repeat(_, 0), do: [] def repeat(lst, n), do: Enum.concat(lst, repeat(lst, n - 1)) end diff --git a/lib/day13.ex b/lib/day13.ex new file mode 100644 index 0000000..965169b --- /dev/null +++ b/lib/day13.ex @@ -0,0 +1,46 @@ +defmodule Aoc2023.Day13 do + use Aoc2023 + + def parse(input) do + input + |> String.split("\n\n") + |> Enum.map(pipe(lines |> Enum.map(&String.to_charlist/1))) + end + + defp reflected_row(block, smudges) do + 0..(length(block) - 2) + |> Enum.filter(fn i -> + Enum.zip_with( + Enum.take(block, i + 1) |> Enum.reverse() |> Enum.concat(), + Enum.drop(block, i + 1) |> Enum.concat(), + &Kernel.==/2 + ) + |> Enum.count(&(not &1)) + |> Kernel.==(smudges) + end) + |> head + end + + defp reflected_column(block, smudges) do + block |> transpose() |> reflected_row(smudges) + end + + defp reflection(block, smudges \\ 0) do + row = reflected_row(block, smudges) + if row != nil, do: {:h, row + 1}, else: {:v, reflected_column(block, smudges) + 1} + end + + def part1(input) do + reflections = input |> Enum.map(&reflection/1) + + (Keyword.get_values(reflections, :h) |> Enum.sum()) * 100 + + (Keyword.get_values(reflections, :v) |> Enum.sum()) + end + + def part2(input) do + reflections = input |> Enum.map(pipe(reflection(1))) + + (Keyword.get_values(reflections, :h) |> Enum.sum()) * 100 + + (Keyword.get_values(reflections, :v) |> Enum.sum()) + end +end diff --git a/lib/mix_tasks.ex b/lib/mix_tasks.ex index 133e15e..4029411 100644 --- a/lib/mix_tasks.ex +++ b/lib/mix_tasks.ex @@ -14,6 +14,7 @@ defmodule Mix.Tasks.Aoc do defp module(10), do: Aoc2023.Day10 defp module(11), do: Aoc2023.Day11 defp module(12), do: Aoc2023.Day12 + defp module(13), do: Aoc2023.Day13 # [MODULE INSERTION POINT] defp base_dir(), do: System.get_env("AOC_BASE") diff --git a/tests/day13/1 b/tests/day13/1 new file mode 100644 index 0000000..3b6b5cc --- /dev/null +++ b/tests/day13/1 @@ -0,0 +1,15 @@ +#.##..##. +..#.##.#. +##......# +##......# +..#.##.#. +..##..##. +#.#.##.#. + +#...##..# +#....#..# +..##..### +#####.##. +#####.##. +..##..### +#....#..# diff --git a/tests/day13/1.1 b/tests/day13/1.1 new file mode 100644 index 0000000..ec8785e --- /dev/null +++ b/tests/day13/1.1 @@ -0,0 +1 @@ +405 diff --git a/tests/day13/1.2 b/tests/day13/1.2 new file mode 100644 index 0000000..d411bb7 --- /dev/null +++ b/tests/day13/1.2 @@ -0,0 +1 @@ +400