From b7744eb2a3f8c37daadbd4525629ece3d98ed0ab Mon Sep 17 00:00:00 2001 From: Caleb Webber Date: Mon, 4 Dec 2023 01:02:52 -0500 Subject: [PATCH] 2023 day 4 --- lib/2023_day4.ex | 67 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 lib/2023_day4.ex diff --git a/lib/2023_day4.ex b/lib/2023_day4.ex new file mode 100644 index 0000000..5bcbe15 --- /dev/null +++ b/lib/2023_day4.ex @@ -0,0 +1,67 @@ +defmodule Card do + defp to_list_numbers(str) do + str + |> String.split(" ") + |> Enum.filter(fn s -> String.length(s) !== 0 end) + |> Enum.map(fn u -> + {i, _} = Integer.parse(u) + i + end) + end + + defp count_winning_cards(player_card, winning_numbers) do + player_card |> Enum.filter(fn n -> Enum.any?(winning_numbers, &(&1 == n)) end) |> Enum.count() + end + + defp parse_card("Card " <> rest) do + [_, numbers] = rest |> String.split(":") + [winning, player] = numbers |> String.split("|") + + [winning |> String.trim() |> to_list_numbers(), player |> String.trim() |> to_list_numbers()] + end + + def parse(input) do + for card <- input |> String.split("\n"), + [winning_numbers, our_numbers] = parse_card(card) do + [winning_numbers, our_numbers] + end + end + + def part1(cards) do + for [winning_numbers, our_numbers] <- cards do + case count_winning_cards(our_numbers, winning_numbers) do + n when n > 0 -> 2 ** (n - 1) + 0 -> 0 + end + end + |> Enum.sum() + end + + def part2(cards) do + copies_of_each_card = + cards + |> Enum.with_index() + |> Enum.map(fn {_, _} -> + 1 + end) + |> Enum.into([]) + + cards + |> Enum.with_index() + |> Enum.reduce( + copies_of_each_card, + fn {[winning, player], idx}, copies -> + self_copies = Enum.at(copies, idx) + won = count_winning_cards(player, winning) + slice = if won > 0, do: (idx + 1)..(idx + won), else: (..) + + copies + |> Enum.with_index() + |> Enum.map(fn {count, idx} -> + if idx in slice, do: count + self_copies, else: count + end) + end + ) + |> Enum.sum() + end +end