Advent of Code 2023 - Day 06
Mix.install([
{:kino, "~> 0.11.0"},
{:kino_aoc, github: "ljgago/kino_aoc"},
{:bisect, "~> 0.4.0"}
])
Input
{:ok, puzzle_input} =
KinoAOC.download_puzzle("2023", "6", System.fetch_env!("LB_AOC_SESSION"))
races =
puzzle_input
|> String.split("\n")
|> Enum.map(fn input ->
Regex.scan(~r/\d+/, input)
|> List.flatten()
|> Enum.map(&String.to_integer/1)
end)
|> Enum.zip()
Part 1
is_win? = fn time, record, wait ->
(time - wait) * wait > record
end
count_wins = fn {time, record} ->
Enum.reduce(0..time, 0, fn wait, wins ->
if is_win?.(time, record, wait), do: wins + 1, else: wins
end)
end
races
|> Stream.map(count_wins)
|> Enum.product()
Part 2
[time, record] =
races
|> Enum.unzip()
|> Tuple.to_list()
|> Enum.map(&Enum.join/1)
|> Enum.map(&String.to_integer/1)
left = Range.to_list(0..ceil(time / 2))
first_win = Bisect.search(left, fn wait -> is_win?.(time, record, wait) end)
time - first_win * 2 + 1