defmodule Aoc2023.Day18 do require Integer use Aoc2023 def parse(input) do input |> lines |> Enum.map(fn line -> [dir, n, color] = Regex.run(~r/^([RDLU]) (\d+) \(#([0-9a-f]{6})\)$/, line, capture: :all_but_first) { dir |> String.to_charlist() |> head, n |> String.to_integer(), color } end) end defp simulate({pos, dist, points}, {dir, n}) do p = case dir do :u -> {-n, 0} :d -> {n, 0} :r -> {0, n} :l -> {0, -n} end |> add_vec(pos) {p, dist + n, [p | points]} end defp area(perim, points), # Shoelace formula do: Stream.zip(points, points |> Stream.cycle() |> Stream.drop(1)) |> Stream.map(fn {{y, x}, {y1, x1}} -> x * y1 - x1 * y end) |> Enum.sum() |> abs |> then(&((&1 + perim) / 2)) |> trunc defp run(instrs) do {_, dist, points} = instrs |> Enum.reduce({{0, 0}, 2, [{0, 0}]}, &simulate(&2, &1)) area(dist, points) end def part1(input) do run(for {dir, n, _} <- input, do: {case dir do ?U -> :u ?D -> :d ?L -> :l ?R -> :r end, n}) end def part2(input) do run(for {_, _, <>} <- input do {case dir do ?0 -> :r ?1 -> :d ?2 -> :l ?3 -> :u end, String.to_integer(len, 16)} end) end end