Skip to content

Instantly share code, notes, and snippets.

@johngian
Created December 5, 2021 19:11
Show Gist options
  • Save johngian/ccde4cb106d3c9232743c371cb0ec4d6 to your computer and use it in GitHub Desktop.
Save johngian/ccde4cb106d3c9232743c371cb0ec4d6 to your computer and use it in GitHub Desktop.
Advent of code 2021 - day 4 - part 1 - solution
defmodule Bingo do
def parseline(line) do
line
|> String.split(" ", trim: true)
|> Enum.map(&String.to_integer/1)
end
def parseboard(board) do
Enum.map(board, &parseline/1)
end
def read(path) do
input = File.read!(path)
input = String.split(input, "\n")
[numbers | boards] = input
numbers = numbers |> String.split(",") |> Enum.map(&String.to_integer/1)
boards =
boards
|> Enum.chunk_by(fn x -> x != "" end)
|> Enum.reject(fn x -> x == [""] end)
|> Enum.map(&parseboard/1)
%{boards: boards, numbers: numbers}
end
def checkboard(board, history) do
vertical = board
horizontal =
board
|> Enum.map(fn line -> MapSet.subset?(MapSet.new(line), history) end)
|> Enum.find_index(fn line -> line == true end)
vertical =
vertical
|> Enum.zip()
|> Enum.map(&Tuple.to_list(&1))
|> Enum.map(fn line -> MapSet.subset?(MapSet.new(line), history) end)
|> Enum.find_index(fn line -> line == true end)
{horizontal, vertical}
end
def checkboards(history, boards) do
history = MapSet.new(history)
boards
|> Enum.map(fn board -> checkboard(board, history) end)
|> Enum.find_index(fn result -> result != {nil, nil} end)
end
def count(boards, winner, history) do
board = boards |> Enum.at(winner)
latest = history |> Enum.at(-1)
history = MapSet.new(history)
s =
board
|> Enum.map(fn line -> Enum.filter(line, fn x -> !MapSet.member?(history, x) end) end)
|> Enum.map(&Enum.sum/1)
|> Enum.sum()
result = s * latest
{board, result, latest, history}
end
def play(history, future, boards, winner) when future == [] or winner != nil do
if winner != nil do
count(boards, winner, history)
else
"No winner"
end
end
def play(history, future, boards, _winner) do
[next | future] = future
curr = history ++ [next]
play(curr, future, boards, checkboards(curr, boards))
end
def run() do
input = read("./input/day4.txt")
{history, future} = Enum.split(input[:numbers], 4)
play(history, future, input[:boards], nil)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment