defmodule AOC.Day13 do def parse_input do [depart, buses] = AOC.Util.input_lines(13, 1) depart = String.to_integer(depart) buses = buses |> String.split(",") |> Enum.map(fn bus when bus == "x" -> :x bus -> String.to_integer(bus) end) {depart, buses} end def find_earliest_bus(depart, buses), do: find_earliest_bus(depart, buses, {nil, :infinity}) def find_earliest_bus(_, [], earliest), do: earliest def find_earliest_bus(depart, [bus | tl], {_, earliest} = acc) do rounds = div(depart, bus) rounds = if rounds * bus < depart, do: rounds + 1, else: rounds wait = rounds * bus - depart acc = if wait < earliest, do: {bus, wait}, else: acc find_earliest_bus(depart, tl, acc) end def find_offsets(buses) do buses |> Enum.with_index() |> Enum.reject(&(elem(&1, 0) |> is_atom())) end def parts do {depart, buses} = parse_input() {bus, earliest} = find_earliest_bus(depart, Enum.reject(buses, &is_atom/1)) part1 = bus * earliest offsets = find_offsets(buses) {part1, offsets} end end