diff --git a/2022/README.md b/2022/README.md
index 6092a836498b91683184f07912edfca397d392c1..b0c0ae510fcdb07dd2c409d0ffc6b297f8a23ade 100644
--- a/2022/README.md
+++ b/2022/README.md
@@ -252,5 +252,23 @@ Well... I'm going to take the part 2 code in a (very) slightly different directi
 
 ## Day 9
 
+- [The problem](https://adventofcode.com/2022/day/9)
+- [The solution](src/main/java/edu/unl/cse/bohn/year2022/Day9.java)
+
+### Part 1
+
+The subproblems are
+- ...
+
+### Part 2
+
+...
+
+### Refactoring
+
+...
+
+## Day 10
+
 (coming soon)
 
diff --git a/2022/src/main/java/edu/unl/cse/bohn/year2022/Day8.java b/2022/src/main/java/edu/unl/cse/bohn/year2022/Day8.java
index 35daf5241661fc7b10e39ba972654f13f05d1c0a..da581f80200e699b7dc469389114958aeb7c5f5f 100644
--- a/2022/src/main/java/edu/unl/cse/bohn/year2022/Day8.java
+++ b/2022/src/main/java/edu/unl/cse/bohn/year2022/Day8.java
@@ -39,11 +39,7 @@ public class Day8 extends Puzzle {
     }
 
     private static int[][] getTreeHeights(List<String> data) {
-        int[][] treeHeights = new int[data.size()][data.get(0).length()];
-        for (int i = 0; i < treeHeights.length; i++) {
-            treeHeights[i] = data.get(i).chars().map(c -> c - '0').toArray();
-        }
-        return treeHeights;
+        return toIntMatrix(data);
     }
 
     private boolean[][] computeTreeVisibility(List<String> data) {
diff --git a/scaffolding/Puzzle.java b/scaffolding/Puzzle.java
index 100704cec7d51d3b557a350d2d62254e850e14e4..f4ca424bcc665ac01fdc671ab5a24e655a632475 100644
--- a/scaffolding/Puzzle.java
+++ b/scaffolding/Puzzle.java
@@ -1,6 +1,8 @@
 package edu.unl.cse.bohn;
 
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
 public abstract class Puzzle {
@@ -25,4 +27,19 @@ public abstract class Puzzle {
         System.out.println("Part 1: " + computePart1(data));
         System.out.println("Part 2: " + computePart2(data));
     }
+
+    protected static List<Integer> toIntegerList(List<String> data) {
+        return data.stream().mapToInt(Integer::valueOf).boxed().toList();
+    }
+
+    protected static char[][] toCharMatrix(List<String> data) {
+        // I suspect this cast won't work
+        return (char[][]) data.stream().map(String::toCharArray).toArray();
+    }
+
+    protected static int[][] toIntMatrix(List<String> data) {
+        int[][] matrix = new int[data.size()][data.get(0).length()];
+        Arrays.setAll(matrix, i -> data.get(i).chars().map(c -> c - '0').toArray());
+        return matrix;
+    }
 }