From 4734c0673888c3558e0e43c7b7c549cd109447b8 Mon Sep 17 00:00:00 2001
From: "Brady J. Garvin" <bgarvin@cse.unl.edu>
Date: Thu, 28 Sep 2023 12:28:14 -0500
Subject: [PATCH] Recorded work from Thursday.

---
 dynamic-programming/notes.md                  | 36 +++++++++----------
 .../src/features/wrapping/solver.js           | 12 ++++++-
 2 files changed, 29 insertions(+), 19 deletions(-)

diff --git a/dynamic-programming/notes.md b/dynamic-programming/notes.md
index c2821f3..e70b77e 100644
--- a/dynamic-programming/notes.md
+++ b/dynamic-programming/notes.md
@@ -115,34 +115,34 @@ Problem: Wrap a paragraph to a line length, minimizing the sum of the squares of
 ## DAG
 
 *   Edges (actions):
-    *   …
+    *   Place an entire line
 *   Vertices (situations):
-    *   …
+    *   The number of words placed so far
 *   Edge weights:
-    *   …
+    *   The penalty for the line just placed
 *   Topological order:
-    *   …
+    *   0 → 1 → … → `wordCount`
 *   Goal:
-    *   …
+    *   Find a shortest path from 0 to `wordCount`
 
 ## Backpointer Class
 
 *   Information for the final result:
-    *   …
+    *   What was the position of the previous line break?
 *   Information to go back:
-    *   …
+    *   What was the position of the previous line break? (redundant)
 *   Information to compare quality:
-    *   …
+    *   What was the *total* penalty for the lines placed so far?
 
 ## Choosing a Backpointer
 
 *   Exhaustive search:
-    *   Generate ….
-    *   Check that ….
+    *   Generate start-of-line positions (in reverse order) as long as the character count (a running total) does not exceed the line length and the start-of-line position does not go negative.
+    *   Check that the backpointer minimizes the *total* penalty (the total penalty of all prior lines plus the penalty of the newly added line).
 
 ## Example
 
->  x x x x xxxx xxxx
+>  x x x|x xxxx|xxxx
 > 0 1 2 3 4    5    6
 
     Vertex          Backpointer
@@ -150,13 +150,13 @@ Problem: Wrap a paragraph to a line length, minimizing the sum of the squares of
      Index  Previous Index  Total Penalty
     ------  --------------  -------------
          0               ⊥              0
-         1               …              …
-         2               …              …
-         3               …              …
-         4               …              …
-         5               …              …
-         6               …              …
+         1               0             36
+         2               0             16
+         3               0              4
+         4               0              0
+         5               3              5
+         6               5             14
 
     Reversed Path
     ----
-    6 ← …
+    6 ← 5 ← 3 ← 0
diff --git a/dynamic-programming/src/features/wrapping/solver.js b/dynamic-programming/src/features/wrapping/solver.js
index 062a7fa..380f102 100644
--- a/dynamic-programming/src/features/wrapping/solver.js
+++ b/dynamic-programming/src/features/wrapping/solver.js
@@ -12,7 +12,17 @@ class Backpointer {
 function chooseBackpointer(wordLengths, lineLength, backpointers) {
   const index = backpointers.length;
   let best = new Backpointer(undefined, Infinity);
-  // TODO: stub
+  for (let start = index - 1, characterCount = wordLengths[start];
+    start >= 0 && characterCount <= lineLength;
+    --start, characterCount += wordLengths[start] + 1) {
+    const candidate = new Backpointer(
+      start,
+      backpointers[start].totalPenalty + penalty(characterCount, lineLength),
+    );
+    if (candidate.totalPenalty < best.totalPenalty) {
+      best = candidate;
+    }
+  }
   console.assert(
     best.previousIndex !== undefined,
     `One of the word lengths ${wordLengths} is too long to fit in a line of length ${lineLength}.`,
-- 
GitLab