From 6bc67ec21fe31f3cd1cd38798667d792615b9536 Mon Sep 17 00:00:00 2001
From: sloane <1699281+sloanelybutsurely@users.noreply.github.com>
Date: Thu, 7 Dec 2023 10:39:05 -0500
Subject: [PATCH] solve 2023 7.1

---
 2023/README.md         |  4 +++-
 2023/lib/2023/7.ex     | 52 ++++++++++++++++++++++++++++++++++++++++++
 2023/lib/AOCHelpers.ex | 30 ++++++++++++++++++++++++
 README.md              |  2 +-
 4 files changed, 86 insertions(+), 2 deletions(-)
 create mode 100644 2023/lib/2023/7.ex
 create mode 100644 2023/lib/AOCHelpers.ex

diff --git a/2023/README.md b/2023/README.md
index c988051..f919199 100644
--- a/2023/README.md
+++ b/2023/README.md
@@ -3,7 +3,7 @@
 |  S  |  M  |  T  |  W  |  T  |  F  |  S  |
 | :-: | :-: | :-: | :-: | :-: | :-: | :-: |
 |     |     |     |     |     | [1] | [2] |
-| [3] | [4] | [5] |  6  |  7  |  8  |  9  |
+| [3] | [4] | [5] |  6  | [7] |  8  |  9  |
 | 10  | 11  | 12  | 13  | 14  | 15  | 16  |
 | 17  | 18  | 19  | 20  | 21  | 22  | 23  |
 | 24  | 25  |     |     |     |     |     |
@@ -14,3 +14,5 @@
 [3]: ./lib/2023/3.ex
 [4]: ./lib/2023/4.ex
 [5]: ./lib/2023/5.ex
+<!-- [6]: ./lib/2023/6.ex -->
+[7]: ./lib/2023/7.ex
diff --git a/2023/lib/2023/7.ex b/2023/lib/2023/7.ex
new file mode 100644
index 0000000..d87ef7d
--- /dev/null
+++ b/2023/lib/2023/7.ex
@@ -0,0 +1,52 @@
+import AOC
+import AOCHelpers
+
+aoc 2023, 7 do
+  def p1(input) do
+    input
+    |> read_input()
+    |> Enum.map(fn [hand, bet] ->
+      counts =
+        hand
+        |> Enum.frequencies()
+        |> Map.values()
+        |> Enum.sort(:desc)
+
+      [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 p2(_input) do
+  end
+
+  def read_input(input) do
+    input
+    |> lines()
+    |> Enum.map(fn line ->
+      line
+      |> words()
+      |> map_list([&to_numeric_hand/1, &String.to_integer/1])
+    end)
+  end
+
+  def to_numeric_hand(str) do
+    str
+    |> letters()
+    |> Enum.map(fn
+      "A" -> 14
+      "K" -> 13
+      "Q" -> 12
+      "J" -> 11
+      "T" -> 10
+      n -> String.to_integer(n)
+    end)
+  end
+
+  def compare_hands_1([counts, hand_a, _], [counts, hand_b, _]), do: hand_a <= hand_b
+  def compare_hands_1([counts_a, _, _], [counts_b, _, _]), do: counts_a <= counts_b
+end
diff --git a/2023/lib/AOCHelpers.ex b/2023/lib/AOCHelpers.ex
new file mode 100644
index 0000000..b96f17e
--- /dev/null
+++ b/2023/lib/AOCHelpers.ex
@@ -0,0 +1,30 @@
+defmodule AOCHelpers do
+  def lines(string) when is_binary(string) do
+    String.split(string, "\n")
+  end
+
+  def words(str) when is_binary(str) do
+    String.split(str)
+  end
+
+  def letters(str) when is_binary(str) do
+    String.split(str, "", trim: true)
+  end
+
+  @doc """
+  Take a list of terms and a list of 1-arity functions and apply each function
+  to the coresponding term in the list of terms.
+
+  ## Example
+
+      iex> map_list([1, 2, 3], [&(&1 + 1), &(&1 * 100), &to_string/1])
+      [2, 200, "3"]
+
+  """
+  def map_list(args, funs) do
+    Enum.zip_with(args, funs, fn arg, fun -> fun.(arg) end)
+  end
+
+  def id(x), do: x
+  def always(x), do: fn -> x end
+end
diff --git a/README.md b/README.md
index e770f5f..21d004d 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] **9/50** 🌟
+1. [2023] **10/50** 🌟
 
 [2015]: ./2015
 [2017]: ./2017