68 lines
1.3 KiB
Elixir
68 lines
1.3 KiB
Elixir
defmodule Day13 do
|
|
@example """
|
|
939
|
|
7,13,x,x,59,x,31,19
|
|
"""
|
|
|
|
def part1(example \\ false) do
|
|
{earliest_time, busses} = parse_input(example)
|
|
|
|
bus_id =
|
|
busses
|
|
|> Enum.reject(&(&1 == "x"))
|
|
|> Enum.min_by(fn bus ->
|
|
bus - rem(earliest_time, bus)
|
|
end)
|
|
|
|
bus_id * (bus_id - rem(earliest_time, bus_id))
|
|
end
|
|
|
|
def part2(example \\ false) do
|
|
{_, busses} = parse_input(example)
|
|
|
|
busses =
|
|
busses
|
|
|> Enum.with_index()
|
|
|> Enum.reject(&(elem(&1, 0) == "x"))
|
|
|
|
find_time(0, busses)
|
|
end
|
|
|
|
def parse_input(example) do
|
|
[l1, l2] =
|
|
if(example, do: @example, else: File.read!("lib/day13/input.txt"))
|
|
|> String.trim()
|
|
|> String.split()
|
|
|
|
busses =
|
|
l2
|
|
|> String.split(",")
|
|
|> Enum.map(fn
|
|
"x" -> "x"
|
|
s -> String.to_integer(s)
|
|
end)
|
|
|
|
{String.to_integer(l1), busses}
|
|
end
|
|
|
|
def find_time(time, busses) do
|
|
{valid, rest} =
|
|
Enum.split_while(busses, fn {id, index} ->
|
|
rem(time + index, id) == 0
|
|
end)
|
|
|
|
case rest do
|
|
[] ->
|
|
time
|
|
|
|
_ ->
|
|
if valid == [] do
|
|
raise "uh oh"
|
|
end
|
|
|
|
step = Enum.reduce(valid, 1, &(elem(&1, 0) * &2))
|
|
find_time(time + step, busses)
|
|
end
|
|
end
|
|
end
|