From 5820ac1c3b18e89774d7b1435f80b0daaf4f2628 Mon Sep 17 00:00:00 2001
From: sloane <1699281+sloanelybutsurely@users.noreply.github.com>
Date: Sat, 2 Dec 2023 09:37:03 -0500
Subject: [PATCH] solve 2023 2.1

---
 2023/README.md             |  3 +-
 2023/elixir/.formatter.exs |  1 +
 2023/elixir/lib/2023/2.ex  | 99 ++++++++++++++++++++++++++++++++++++++
 2023/elixir/mix.exs        |  3 +-
 2023/elixir/mix.lock       |  1 +
 README.md                  |  2 +-
 6 files changed, 106 insertions(+), 3 deletions(-)
 create mode 100644 2023/elixir/lib/2023/2.ex

diff --git a/2023/README.md b/2023/README.md
index 5fcd2ac..600f612 100644
--- a/2023/README.md
+++ b/2023/README.md
@@ -2,7 +2,7 @@
 
 |  S  |  M  |  T  |  W  |  T  |  F  |  S  |
 | :-: | :-: | :-: | :-: | :-: | :-: | :-: |
-|     |     |     |     |     | [1] |  2  |
+|     |     |     |     |     | [1] | [2] |
 |  3  |  4  |  5  |  6  |  7  |  8  |  9  |
 | 10  | 11  | 12  | 13  | 14  | 15  | 16  |
 | 17  | 18  | 19  | 20  | 21  | 22  | 23  |
@@ -10,3 +10,4 @@
 
 
 [1]: ./elixir/lib/2023/1.ex
+[2]: ./elixir/lib/2023/2.ex
diff --git a/2023/elixir/.formatter.exs b/2023/elixir/.formatter.exs
index d2cda26..42fbbb2 100644
--- a/2023/elixir/.formatter.exs
+++ b/2023/elixir/.formatter.exs
@@ -1,4 +1,5 @@
 # Used by "mix format"
 [
+  inport_deps: [:nimble_parsec],
   inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
 ]
diff --git a/2023/elixir/lib/2023/2.ex b/2023/elixir/lib/2023/2.ex
new file mode 100644
index 0000000..6819069
--- /dev/null
+++ b/2023/elixir/lib/2023/2.ex
@@ -0,0 +1,99 @@
+import AOC
+
+aoc 2023, 2 do
+  import NimbleParsec
+
+  dice =
+    integer(min: 1)
+    |> ignore(string(" "))
+    |> choice([
+      string("blue"),
+      string("green"),
+      string("red")
+    ])
+    |> label("die")
+    |> optional(ignore(string(", ")))
+    |> times(min: 1, max: 3)
+    |> label("dice")
+
+  game =
+    ignore(string("Game "))
+    |> integer(min: 1)
+    |> ignore(string(": "))
+    |> label("game")
+
+  defparsec(:game_p, game)
+  defparsec(:dice_p, dice)
+
+  def read_game(input) do
+    case game_p(input) do
+      {:ok, [id], rest, _, _, _} ->
+        dice_and_rest =
+          Stream.unfold(rest, fn
+            nil ->
+              nil
+
+            rest ->
+              case dice_p(rest) do
+                {:ok, dice, rest, _, _, _} ->
+                  dice =
+                    dice
+                    |> Enum.chunk_every(2)
+                    |> Enum.map(&Enum.reverse/1)
+                    |> Enum.map(&List.to_tuple/1)
+                    |> Enum.into(%{})
+
+                  {dice, String.replace_prefix(rest, "; ", "")}
+
+                {:error, _, rest, _, _, _} ->
+                  {rest, nil}
+              end
+          end)
+          |> Enum.to_list()
+
+        [rest | dice] = Enum.reverse(dice_and_rest)
+
+        {:ok, {id, dice, rest}}
+
+      _ ->
+        :halt
+    end
+  end
+
+  def read_games(input) do
+    Stream.unfold(input, fn rest ->
+      input =
+        rest
+        |> String.replace_prefix("\n", "")
+
+      case read_game(input) do
+        {:ok, {id, dice, rest}} ->
+          {{id, dice}, rest}
+
+        _ ->
+          nil
+      end
+    end)
+  end
+
+  def p1(input) do
+    red_max = 12
+    green_max = 13
+    blue_max = 14
+
+    input
+    |> read_games()
+    |> Stream.reject(fn {_id, dice} ->
+      dice
+      |> Enum.any?(fn d ->
+        Map.get(d, "red", 0) > red_max or Map.get(d, "green", 0) > green_max or
+          Map.get(d, "blue", 0) > blue_max
+      end)
+    end)
+    |> Stream.map(&elem(&1, 0))
+    |> Enum.sum()
+  end
+
+  def p2(_input) do
+  end
+end
diff --git a/2023/elixir/mix.exs b/2023/elixir/mix.exs
index dc60627..20c81ac 100644
--- a/2023/elixir/mix.exs
+++ b/2023/elixir/mix.exs
@@ -21,7 +21,8 @@ defmodule AdventOfCode.MixProject do
   # Run "mix help deps" to learn about dependencies.
   defp deps do
     [
-      {:advent_of_code_utils, "~> 4.0.0"}
+      {:advent_of_code_utils, "~> 4.0.0"},
+      {:nimble_parsec, "~> 1.4.0"}
     ]
   end
 end
diff --git a/2023/elixir/mix.lock b/2023/elixir/mix.lock
index 77df8e0..34e286f 100644
--- a/2023/elixir/mix.lock
+++ b/2023/elixir/mix.lock
@@ -1,5 +1,6 @@
 %{
   "advent_of_code_utils": {:hex, :advent_of_code_utils, "4.0.0", "28df8cde0d6cccf95b72880ab89b00e1cb7c0492164bbf537bdf229c0953f7aa", [:mix], [{:floki, "~> 0.34", [hex: :floki, repo: "hexpm", optional: false]}, {:tz, "~> 0.26", [hex: :tz, repo: "hexpm", optional: false]}], "hexpm", "6f44c1f5b901e6a5bd7561361f3441ee7fa4ee67ea28d7fc3b2df29303d80ff4"},
   "floki": {:hex, :floki, "0.35.2", "87f8c75ed8654b9635b311774308b2760b47e9a579dabf2e4d5f1e1d42c39e0b", [:mix], [], "hexpm", "6b05289a8e9eac475f644f09c2e4ba7e19201fd002b89c28c1293e7bd16773d9"},
+  "nimble_parsec": {:hex, :nimble_parsec, "1.4.0", "51f9b613ea62cfa97b25ccc2c1b4216e81df970acd8e16e8d1bdc58fef21370d", [:mix], [], "hexpm", "9c565862810fb383e9838c1dd2d7d2c437b3d13b267414ba6af33e50d2d1cf28"},
   "tz": {:hex, :tz, "0.26.2", "a40e4bb223344c6fc7b74dda25df1f26b88a30db23fa6e55de843bd79148ccdb", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:mint, "~> 1.5", [hex: :mint, repo: "hexpm", optional: true]}], "hexpm", "224b0618dd1e032778a094040bc710ef9aff6e2fa8fffc2716299486f27b9e68"},
 }
diff --git a/README.md b/README.md
index 4a4ab8b..45e8da4 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] **2/50** 🌟
+1. [2023] **3/50** 🌟
 
 [2015]: ./2015
 [2017]: ./2017