My (attempted) solutions to the 2022 Advent of Code
Log | Files | Refs | README

```commit 20a95877507a9e68fc153089234ca852f3db2095
parent fe93b248b09c82fcbe1c2a3a58b0f04f86be6115
Date:   Fri,  2 Dec 2022 13:45:38 -0800

Solution to day 2, part 2.

Diffstat:
Msrc/day_2.jl | 40++++++++++++++++++++++++++++++++++------
```
```1 file changed, 34 insertions(+), 6 deletions(-)
diff --git a/src/day_2.jl b/src/day_2.jl
@@ -9,6 +9,10 @@ example = split("""
C Z""", "\n")

+function mod_pos(a, b)
+    a >= 0 ? a % b : (a % b) + b
+end
+
# Note that this rearranges the input rows. Not sure if that will be a problem.
# Maybe leftjoin needs to be told not to do that? IDK. Also Julia has the whack
# negative modulus behavior. Finally, I don't know if this is idiomatic Julia
@@ -27,11 +31,7 @@ function parse_input(input)
on = :b) |>
x->transform(x,
[:score_a, :score_b] =>
-                       ByRow((a, b) -> (b-a+1) % 3) =>
-                       :win_score) |>
-        x->transform(x,
-                     :win_score =>
-                       ByRow(a -> a < 0 ? a + 3 : a) =>
+                       ByRow((a, b) -> mod_pos(b-a+1, 3)) =>
:win_score) |>
x->transform(x,
[:score_b, :win_score] =>
@@ -45,7 +45,35 @@ end
@assert part_1(example) == 15
@info part_1(input)

+# Now that I know what part 2 wants, I'm going to do what I should've done for
+# part 1 and approach this more efficiently. I'm still going to (over)use data
+# frames as I get a handle on DataFrames.jl
+function parse_input_2(input)
+    scores = DataFrame(
+        a = ['A', 'B', 'C'],
+        b = ['X', 'Y', 'Z'],
+        score = 0:2
+    )
+    input |>
+        x->DataFrame(a = first.(x), b = last.(x)) |>
+        x->groupby(x, [:a, :b]) |>
+        x->combine(x, nrow) |>
+        x->leftjoin(x, select(scores, "a", "score" => "score_a"),
+                    on = :a) |>
+        x->leftjoin(x, select(scores, "b", "score" => "score_b"),
+                    on = :b) |>
+        x->transform(x,
+                     [:score_a, :score_b] =>
+                        ByRow((a,b)->mod_pos(a+b-1, 3)) =>
+                        :shape_score) |>
+        x->transform(x,
+                     [:nrow, :shape_score, :score_b] =>
+                       ByRow((a, b, c) -> a * ((b + 1) + 3 * c)) =>
+                       :round_score)
+end
+
function part_2(input)
-    nothing
+    sum(parse_input_2(input)[:, :round_score])
end
+@assert part_2(example) == 12
@info part_2(input)
```