Day 4
Input
# Livebook Input (atleast the default one) doesn't support multiline
[winning_nums | boards] = IO.gets(:input) |> String.split(~r{\s}, trim: true)
winning_nums =
winning_nums
|> String.split(",")
|> Enum.map(&String.to_integer/1)
boards =
boards
|> Enum.map(&String.to_integer/1)
|> Enum.chunk_every(5)
|> Enum.chunk_every(5)
Part 1
calculate_card = fn bingo_card, last_number ->
List.flatten(bingo_card)
|> Enum.reject(&(&1 == -1))
|> Enum.sum()
|> Kernel.*(last_number)
|> IO.inspect()
# exit after first find
Kernel.exit(:ok)
end
# mark all matching numbers inside boards
mark_boards = fn boards, n ->
List.flatten(boards)
|> Enum.map(&if(&1 == n, do: -1, else: &1))
# convert back to 5x5 boards
|> Enum.chunk_every(5)
|> Enum.chunk_every(5)
end
check_boards = fn boards, last_n ->
Enum.each(boards, fn b ->
for i <- 0..4 do
# horizontal || vertical
if Enum.sum(Enum.at(b, i)) == -5 || Enum.sum(Enum.map(b, &Enum.at(&1, i))) == -5 do
calculate_card.(b, last_n)
end
end
end)
boards
end
Enum.reduce(winning_nums, boards, fn n, b -> mark_boards.(b, n) |> check_boards.(n) end)
Part 2
# So ugly I had to hide it