From dcbdbcf128f385e458c3c2486c5c26846f634475 Mon Sep 17 00:00:00 2001
From: sloane <1699281+sloanelybutsurely@users.noreply.github.com>
Date: Thu, 7 Dec 2023 10:49:26 -0500
Subject: [PATCH] solve 2023 7.2

---
 2023/lib/2023/7.ex | 58 +++++++++++++++++++++++++++++++++++-----------
 README.md          |  2 +-
 2 files changed, 46 insertions(+), 14 deletions(-)

diff --git a/2023/lib/2023/7.ex b/2023/lib/2023/7.ex
index d87ef7d..b4e8c0b 100644
--- a/2023/lib/2023/7.ex
+++ b/2023/lib/2023/7.ex
@@ -4,7 +4,14 @@ import AOCHelpers
 aoc 2023, 7 do
   def p1(input) do
     input
-    |> read_input()
+    |> read_input(fn
+      "A" -> 14
+      "K" -> 13
+      "Q" -> 12
+      "J" -> 11
+      "T" -> 10
+      n -> String.to_integer(n)
+    end)
     |> Enum.map(fn [hand, bet] ->
       counts =
         hand
@@ -21,30 +28,55 @@ aoc 2023, 7 do
     |> Enum.sum()
   end
 
-  def p2(_input) do
+  def p2(input) do
+    input
+    |> read_input(fn
+      "J" -> -1
+      "A" -> 14
+      "K" -> 13
+      "Q" -> 12
+      "T" -> 10
+      n -> String.to_integer(n)
+    end)
+    |> Enum.map(fn [hand, bet] ->
+      {jokers, hand_without_jokers} = Enum.split_with(hand, &(&1 === -1))
+
+      number_of_jokers = Enum.count(jokers)
+
+      counts_without_jokers =
+        hand_without_jokers
+        |> Enum.frequencies()
+        |> Map.values()
+        |> Enum.sort(:desc)
+
+      counts = [
+        List.first(counts_without_jokers, 0) + number_of_jokers
+        | Enum.drop(counts_without_jokers, 1)
+      ]
+
+      [counts, hand, bet]
+    end)
+    |> Enum.sort(&compare_hands_1/2)
+    |> Enum.map(&Enum.at(&1, 2))
+    |> Enum.with_index(1)
+    |> Enum.map(fn {bet, rank} -> bet * rank end)
+    |> Enum.sum()
   end
 
-  def read_input(input) do
+  def read_input(input, card_to_number) do
     input
     |> lines()
     |> Enum.map(fn line ->
       line
       |> words()
-      |> map_list([&to_numeric_hand/1, &String.to_integer/1])
+      |> map_list([&to_numeric_hand(&1, card_to_number), &String.to_integer/1])
     end)
   end
 
-  def to_numeric_hand(str) do
+  def to_numeric_hand(str, card_to_number) do
     str
     |> letters()
-    |> Enum.map(fn
-      "A" -> 14
-      "K" -> 13
-      "Q" -> 12
-      "J" -> 11
-      "T" -> 10
-      n -> String.to_integer(n)
-    end)
+    |> Enum.map(card_to_number)
   end
 
   def compare_hands_1([counts, hand_a, _], [counts, hand_b, _]), do: hand_a <= hand_b
diff --git a/README.md b/README.md
index 21d004d..a4256b4 100644
--- a/README.md
+++ b/README.md
@@ -14,7 +14,7 @@
 1. [2020] **17/50** 🌟
 1. [2021] **43/50** 🌟
 1. [2022] **14/50** 🌟
-1. [2023] **10/50** 🌟
+1. [2023] **11/50** 🌟
 
 [2015]: ./2015
 [2017]: ./2017