defmodule Aoc2023.Day11 do use Aoc2023 def parse(input) do coords = input |> lines |> Enum.map(pipe(String.to_charlist() |> Enum.map(&(&1 == ?#)))) |> Enum.with_index() |> Enum.flat_map(fn {row, y} -> row |> Enum.with_index() |> Enum.filter(pipe(elem(0))) |> Enum.map(fn {_, x} -> {y, x} end) end) ys = coords |> Enum.map(pipe(elem(0))) |> MapSet.new() empty_rows = MapSet.difference(MapSet.new(0..(ys |> Enum.max())), ys) xs = coords |> Enum.map(pipe(elem(1))) |> MapSet.new() empty_cols = MapSet.difference(MapSet.new(0..(xs |> Enum.max())), xs) fn expansion -> coords_ = coords |> Enum.map(fn {y, x} -> {y + Enum.count(empty_rows, &(&1 < y)) * (expansion - 1), x + Enum.count(empty_cols, &(&1 < x)) * (expansion - 1)} end) coords_ |> Enum.with_index() |> Enum.flat_map(fn {c, i} -> coords_ |> Enum.drop(i + 1) |> Enum.map(&{c, &1}) end) |> Enum.map(&dist/1) |> Enum.sum() end end defp dist({{y1, x1}, {y2, x2}}) do abs(x1 - x2) + abs(y1 - y2) end def part1(input) do input.(2) end def part2(input) do input.(1_000_000) end end