Browse Source

Solve 2021 Day 4 Part 2 in elixir

master
Garrit Franke 2 years ago
parent
commit
336209d19c
Signed by: garrit
GPG Key ID: 65586C4DDA55EA2C
  1. 90
      2021/Day4/Elixir/giant_squid.ex
  2. 19
      2021/Day4/test.txt

90
2021/Day4/Elixir/giant_squid.ex

@ -10,32 +10,53 @@ defmodule GiantSquid do
Enum.at(input, 0)
|> String.split(",", trim: true)
|> Enum.map(&Integer.parse/1)
|> Enum.map(fn (t) -> elem(t, 0) end)
|> Enum.map(fn t -> elem(t, 0) end)
end
def parse_board(board) do
String.split(board, "\n")
|> Enum.map(fn(board) ->
|> Enum.map(fn board ->
String.replace(board, " ", " ")
|> String.split(" ", trim: true)
|> Enum.map(&Integer.parse/1)
|> Enum.map(fn (t) -> elem(t, 0) end)
|> Enum.map(fn (col) -> {col, false} end)
|> Enum.map(fn t -> elem(t, 0) end)
|> Enum.map(fn col -> {col, false} end)
end)
end
def play_bingo(boards, [drawn | tail]) do
boards_after_game = Enum.map(boards, &(apply_drawn_number(&1, drawn)))
boards_after_game = Enum.map(boards, &apply_drawn_number(&1, drawn))
winner = Enum.find(boards_after_game, false, &has_bingo/1)
if winner, do: {winner, drawn}, else: play_bingo(boards_after_game, tail)
end
def play_bingo(board, [drawn]), do: apply_drawn_number(board, drawn)
def play_bingo(board, []), do: board
def play_all_drawn_numbers(boards, [drawn | tail]) do
boards_after_game =
Enum.map(boards, fn {data, elements_left, won_with} = board ->
{apply_drawn_number(elem(board, 0), drawn), elements_left, won_with}
end)
|> Enum.map(fn {data, elements_left, won_with} = board ->
if has_bingo(data) and !won_with do
{data, Enum.count(tail) + 1, drawn}
else
board
end
end)
if Enum.all?(Enum.map(boards, &(elem(&1, 2)))) do
boards
else
play_all_drawn_numbers(boards_after_game, tail)
end
end
def play_all_drawn_numbers(boards, []), do: boards
def apply_drawn_number(board, num) do
Enum.map(board, fn (row) ->
Enum.map(row, fn ({value, matched}) ->
Enum.map(board, fn row ->
Enum.map(row, fn {value, matched} ->
if value == num, do: {value, true}, else: {value, matched}
end)
end)
@ -44,14 +65,17 @@ defmodule GiantSquid do
def row_has_bingo(row), do: Enum.all?(row)
def has_bingo(board) do
matched_matrix = Enum.map(board, fn (row) ->
Enum.map(row, fn ({value, matched}) -> matched end)
end)
matched_matrix =
Enum.map(board, fn row ->
Enum.map(row, fn {value, matched} -> matched end)
end)
row_bingo = Enum.any?(matched_matrix, &row_has_bingo/1)
col_bingo = Enum.zip(matched_matrix)
|> Enum.map(&Tuple.to_list/1)
|> Enum.any?(&row_has_bingo/1)
col_bingo =
Enum.zip(matched_matrix)
|> Enum.map(&Tuple.to_list/1)
|> Enum.any?(&row_has_bingo/1)
row_bingo or col_bingo
end
@ -63,20 +87,42 @@ defmodule GiantSquid do
@spec first() :: Integer
def first() do
drawn = load_file |> drawn_numbers
boards = load_file |> parse_boards
drawn = load_file() |> drawn_numbers
boards = load_file() |> parse_boards
{winner, last_drawn} = play_bingo(boards, drawn)
undrawn_sum = List.flatten(winner)
|> Enum.filter(fn ({_, was_drawn}) -> !was_drawn end)
|> Enum.map(&(elem(&1, 0)))
|> Enum.sum()
undrawn_sum * last_drawn
undrawn_sum =
List.flatten(winner)
|> Enum.filter(fn {_, was_drawn} -> !was_drawn end)
|> Enum.map(&elem(&1, 0))
|> Enum.sum()
undrawn_sum * last_drawn
end
@spec second() :: Integer
def second() do
drawn = load_file |> drawn_numbers
boards =
load_file()
|> parse_boards
|> Enum.map(fn board -> {board, nil, nil} end)
boards_after_games =
play_all_drawn_numbers(boards, drawn)
|> Enum.sort_by(&elem(&1, 1))
{data, _, last_drawn} = board = Enum.at(boards_after_games, 0)
undrawn_sum =
List.flatten(data)
|> Enum.filter(fn {_, was_drawn} -> !was_drawn end)
|> Enum.map(&elem(&1, 0))
|> Enum.sum()
undrawn_sum * last_drawn
end
end

19
2021/Day4/test.txt

@ -0,0 +1,19 @@
7,4,9,5,11,17,23,2,0,14,21,24,10,16,13,6,15,25,12,22,18,20,8,19,3,26,1
22 13 17 11 0
8 2 23 4 24
21 9 14 16 7
6 10 3 18 5
1 12 20 15 19
3 15 0 2 22
9 18 13 17 5
19 8 7 25 23
20 11 10 24 4
14 21 16 12 6
14 21 17 24 4
10 16 15 9 19
18 8 23 26 20
22 11 13 6 5
2 0 12 3 7
Loading…
Cancel
Save