From 20ae3c56c07d73adf138072e813b07b5b44312e3 Mon Sep 17 00:00:00 2001 From: "Brady J. Garvin" <bgarvin@cse.unl.edu> Date: Fri, 6 Oct 2023 15:15:54 -0500 Subject: [PATCH] Recorded work from Friday. --- dynamic-programming/notes.md | 28 +++++++++++-------- .../src/features/wrapping/solver.js | 12 +++++++- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/dynamic-programming/notes.md b/dynamic-programming/notes.md index 33d0f7d..dc920f3 100644 --- a/dynamic-programming/notes.md +++ b/dynamic-programming/notes.md @@ -124,17 +124,17 @@ Problem: Wrap a paragraph to a line length, minimizing the sum of the squares of ## Backpointer Class * Information for the final result: - * … + * What was the position of the previous linebreak? * Information to go back: - * … + * What was the position of the previous linebreak? (redundant with the info above) (alternatively, we could track the number of words on the chosen line) * 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 does not exceed the line length and the start-of-line position does not go negative. + * Check that the backpointer minimizes total penalty. ## Example @@ -146,13 +146,17 @@ 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 + +> x x x +> x xxxx +> xxxx diff --git a/dynamic-programming/src/features/wrapping/solver.js b/dynamic-programming/src/features/wrapping/solver.js index 062a7fa..2288104 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 += 1 + wordLengths[start]) { + const candidate = new Backpointer( + start, + backpointers[…].totalPenalty + penalty(…, …), + ); + 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