aoc/20/lib/days/day13.ex
2023-12-04 10:25:33 +01:00

45 lines
1.1 KiB
Elixir

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