defmodule Day14 do defmodule Board do @derive Inspect defstruct [:w, :h, :robots] def from_data(data, w, h) do robots = data |> String.split("\n", trim: true) |> Enum.map(fn line -> Regex.scan(~r/-?\d+/, line) |> List.flatten() |> Enum.map(&String.to_integer/1) |> List.to_tuple() end) %Board{w: w, h: h, robots: robots} end def move(board, moves) do board.robots |> Enum.map(fn {x, y, vx, vy} -> { posrem(x+moves*vx, board.w), posrem(y+moves*vy, board.h) } end) end defp posrem(n, m) do rem(rem(n, m)+m, m) end def print(board, pos) do pos = MapSet.new(pos) for i <- 0..board.w-1 do for j <- 0..board.h-1 do if MapSet.member?(pos, {j, i}) do "X" else "." end end end |> Enum.map(&List.to_string/1) |> Enum.join("\n") |> IO.puts() end end def part1(data) do board = Board.from_data(data, 101, 103) Board.move(board, 100) |> Enum.map(fn {x, y} -> cond do x < div(board.w, 2) and y < div(board.h, 2) -> {1, 0, 0, 0} x < div(board.w, 2) and y > div(board.h, 2) -> {0, 1, 0, 0} x > div(board.w, 2) and y < div(board.h, 2) -> {0, 0, 1, 0} x > div(board.w, 2) and y > div(board.h, 2) -> {0, 0, 0, 1} true -> {0, 0, 0, 0} end end) |> Enum.reduce({0, 0, 0, 0}, fn {i1, i2, i3, i4}, {q1, q2, q3, q4} -> {q1+i1, q2+i2, q3+i3, q4+i4} end) |> then(fn {q1, q2, q3, q4} -> q1*q2*q3*q4 end) end def part2(data) do board = Board.from_data(data, 101, 103) Stream.map(0..10000, fn i -> pos = Board.move(board, i) most = pos |> Enum.group_by(&elem(&1, 0), &(elem(&1, 1))) |> Enum.map(&Enum.sort(elem(&1, 1))) |> Enum.map(fn ys -> Enum.zip(ys, tl(ys)) |> Enum.map(fn {a, b} -> b-a end) end) |> List.flatten() |> Enum.frequencies() |> Enum.max_by(&elem(&1, 1)) if elem(most, 0) == 1 and elem(most, 1) > 100 do dbg({i, most}) Board.print(board, pos) i end end) |> Stream.filter(& &1 != nil) |> Enum.take(1) |> hd() end end data = IO.read(:stdio, :eof) {time1, ans1} = :timer.tc(fn -> Day14.part1(data) end) IO.puts("Time : #{time1 / 1000000}") IO.puts("Answer: #{ans1}") {time2, ans2} = :timer.tc(fn -> Day14.part2(data) end) IO.puts("Time : #{time2 / 1000000}") IO.puts("Answer: #{ans2}")