diff --git a/src/wolfgoatcabbage/Problem.java b/src/wolfgoatcabbage/Problem.java
index 914ef96fb0e79382841c5e3574b119f063609315..bf704b29e75ce00b811f9afe995036b3d11d7101 100644
--- a/src/wolfgoatcabbage/Problem.java
+++ b/src/wolfgoatcabbage/Problem.java
@@ -56,17 +56,55 @@ public final class Problem {
     int nTrips = (int) Math.round(obj);
     // Add each trip to the report.
     for (int t = 1; t <= nTrips; t++) {
+      sb.append("Time ").append(t).append(":\t");
       if (t % 2 == 0) {
         // Even numbered trips are right to left.
-        sb.append("Time ").append(t).append(":\t")
-          .append(format(what(near[t - 1]), what(transit[t]), what(far[t]), false))
-          .append("\n");
+          sb.append(format(what(near[t - 1]), what(transit[t]),
+                           what(far[t]), false));
       } else {
         // Odd numbered trips are left to right.
-        sb.append("Time ").append(t).append(":\t")
-          .append(format(what(near[t]), what(transit[t]), what(far[t - 1]), true))
-          .append("\n");
+        sb.append(format(what(near[t]), what(transit[t]),
+                         what(far[t - 1]), true));
       }
+      sb.append("\n");
+    }
+    return sb.toString();
+  }
+
+  /**
+   * Generates a string summary of a solution.
+   *
+   * The first index in the matrix argument is time, the second is item.
+   *
+   * @param nTrips
+   * @param far
+   * @param carried
+   * @return 
+   */
+  public static String report(final int nTrips, final double[][] far,
+                              final double[] carried) {
+    StringBuilder sb = new StringBuilder();
+    sb.append("""
+              The farmer arrives at the left bank at time 0.
+              """);
+    // Add each trip to the report.
+    for (int t = 1; t <= nTrips; t++) {
+      sb.append("Time ").append(t).append(":\t");
+      String boat;
+      int c = (int) Math.round(carried[t]);
+      if (c < ITEMCOUNT) {
+        boat = ITEMS[c];
+      } else {
+        boat = "nothing";
+      }
+      if (t % 2 == 0) {
+        // Trip is far to near.
+        sb.append(format(what(flip(far[t - 1])), boat, what(far[t]), false));
+      } else {
+        // Trip is near to far.
+        sb.append(format(what(flip(far[t])), boat, what(far[t - 1]), true));
+      }
+      sb.append("\n");
     }
     return sb.toString();
   }
@@ -121,4 +159,17 @@ public final class Problem {
     sb.append(String.format("%-" + WIDTH + "s", right));
     return sb.toString();
   }
+
+  /**
+   * Reverses the 0-1 values in a vector.
+   * @param x a vector of 0-1 values
+   * @return the logical negation of x
+   */
+  private static double[] flip(final double[] x) {
+    double[] y = new double[x.length];
+    for (int i = 0; i < x.length; i++) {
+      y[i] = 1 - x[i];
+    }
+    return y;
+  }
 }