AoC 2023 - Day 04
Mix.install([
{:kino, "~> 0.11.3"}
])
Section
input_e1 =
"day04-e1.txt"
|> Kino.FS.file_path()
|> File.read!()
|> String.trim()
input =
"day04.txt"
|> Kino.FS.file_path()
|> File.read!()
|> String.trim()
[input_e1, input]
defmodule Solution do
def part_1(input) do
input
|> String.split("\n")
|> Enum.map(fn card ->
[numbers, winning_numbers] = split(card)
matches =
numbers
|> MapSet.intersection(winning_numbers)
|> MapSet.size()
if matches > 0 do
round(:math.pow(2, matches - 1))
else
0
end
end)
|> Enum.sum()
end
def part_2(input) do
lines = String.split(input, "\n")
cards = List.duplicate(1, length(lines))
lines
|> Enum.with_index()
|> Enum.reduce(cards, fn {card, n}, acc ->
[numbers, winning_numbers] = split(card)
cards_won =
numbers
|> MapSet.intersection(winning_numbers)
|> MapSet.size()
range = (n + 1)..(cards_won + n)//1
Enum.reduce(range, acc, fn i, acc ->
List.update_at(acc, i, &(&1 + Enum.at(acc, n)))
end)
end)
|> Enum.sum()
end
defp split(line) do
[_card, card] = String.split(line, ":", trim: true)
card
|> String.split("|", trim: true)
|> Enum.map(&String.split(&1, " ", trim: true))
|> Enum.map(&MapSet.new/1)
end
end
Solution.part_1(input)
Solution.part_2(input)