Skip to content

Instantly share code, notes, and snippets.

@YannickFricke
Created December 5, 2023 22:15
Show Gist options
  • Save YannickFricke/bdbb1d0e0eb4cb6f82d811243e814b05 to your computer and use it in GitHub Desktop.
Save YannickFricke/bdbb1d0e0eb4cb6f82d811243e814b05 to your computer and use it in GitHub Desktop.
AoC 2023 Day 4
defmodule AdventOfCode2023.Day04 do
@moduledoc false
require IEx
require Logger
def run do
input =
"lib/advent_of_code2023/inputs/04/part1.txt"
|> File.read!()
|> String.trim()
|> String.split("\n", trim: true)
part1(input)
part2(input)
end
defp part1(input) do
sum_of_winning_numbers =
input
|> Enum.map(&parse_line/1)
|> Enum.map(&map_to_winning_numbers/1)
|> Enum.map(&map_to_points/1)
|> Enum.sum()
Logger.info("Sum of winning numbers: #{sum_of_winning_numbers}")
end
defp part2(input) do
parsed_lines =
Enum.map(input, &parse_line/1)
winning_numbers_per_card =
Map.new(parsed_lines, fn {card_id, _winning_numbers, _my_numbers} = entry ->
{card_id, length(map_to_winning_numbers(entry))}
end)
amount_of_cards =
Map.new(parsed_lines, fn {card_id, _winning_numbers, _my_numbers} -> {card_id, 1} end)
total_cards =
winning_numbers_per_card
|> Enum.reduce(amount_of_cards, fn {card_id, amount_of_winning_cards}, acc ->
if amount_of_winning_cards == 0 do
acc
else
start_index = card_id + 1
end_index = card_id + amount_of_winning_cards
cards_to_add = Map.get(acc, card_id, 1)
Enum.reduce(start_index..end_index, acc, fn index_to_update, acc ->
Map.update(acc, index_to_update, 0, &(&1 + cards_to_add))
end)
end
end)
|> dbg()
|> Map.values()
|> Enum.sum()
Logger.info("Total cards: #{total_cards}")
end
defp parse_line(line) do
["Card " <> raw_card_number, numbers] = String.split(line, ":", trim: true)
[winning_numbers_string, my_numbers_string] = String.split(numbers, "|")
parsed_card_number =
raw_card_number
|> String.trim()
|> String.to_integer()
winning_numbers =
winning_numbers_string
|> String.split(" ", trim: true)
|> Enum.map(&String.to_integer/1)
my_numbers =
my_numbers_string
|> String.split(" ", trim: true)
|> Enum.map(&String.to_integer/1)
{parsed_card_number, winning_numbers, my_numbers}
end
defp map_to_winning_numbers({_card_id, winning_numbers, my_numbers}) do
Enum.filter(my_numbers, &Enum.member?(winning_numbers, &1))
end
defp map_to_points([]), do: 0
defp map_to_points(numbers) do
numbers
|> Enum.drop(1)
|> Enum.reduce(1, fn _number, acc -> acc * 2 end)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment