diff --git a/greedy-algorithms/notes.md b/greedy-algorithms/notes.md
index 34ac568bd127ac3a3e7bb1e39af72fffa2cd02f9..35d62aceb93583ab247f7e4d5e1e090142657daf 100644
--- a/greedy-algorithms/notes.md
+++ b/greedy-algorithms/notes.md
@@ -64,7 +64,7 @@ Problem: Given a sequence of fueling sites, the distances between consecutive si
 *   Vertices (situations):
     *   Locations
 *   Edge weights (optional):
-    *   Distance to the next location
+    *   Distance to the next location (optional)
 *   Topological order:
     *   Order along the route: `a → b → … → i`
 *   Goal:
@@ -126,8 +126,8 @@ Problem: [same as above]
 ## Choosing a Forward Edge
 
 *   Exhaustive search:
-    *   Generate …
-    *   Check that …
+    *   Generate all edges that travel up to distance `range` along the route (generate these in forward order in order to keep a running distance total)
+    *   Check that the chosen edge travels farthest (but, that condition always favors the current candidate)
 
 ## Example
 
@@ -143,12 +143,15 @@ Problem: [same as above]
 
     Location  Next Location
     --------  -------------
-    a         …
-    …
+    a         c
+    c         d
+    d         e
+    e         h
+    h         i
 
     Path
     ----
-    a → …
+    a → c → d → e → h → i
 
 --------------------------------------------------------------------------------
 
@@ -214,22 +217,22 @@ Problem: Given frequencies for a set of symbols, create a lossless binary encodi
 ## DAG
 
 *   Edges (actions):
-    *   …
+    *   Combine two parts (sets of symbols) and record bits from what combination we did
 *   Vertices (situations):
-    *   …
+    *   Partitions of the symbols
 *   Edge weights:
-    *   …
+    *   Total frequency of the combined set
 *   Topological order:
-    *   …
+    *   By decreasing number of parts
 *   Goal:
-    *   …
+    *   Find the shortest path from having all sets separated to having all sets combined
 
 ## Choosing a Forward Edge
 
 *   Direct solution:
-    *   …
-    *   …
-    *   …
+    *   Choose the lowest-frequency part
+    *   Choose the second-lowest-frequency part
+    *   Follow the edge that combines those two parts
 
 ## Example
 
@@ -241,4 +244,6 @@ Problem: Given frequencies for a set of symbols, create a lossless binary encodi
              Symbol Partitioning (Frequency Order)           'a'  'b'  'c'  'd'
     -------------------------------------------------------  ---  ---  ---  ---
     {'a'} → 0.15, {'c'} → 0.25, {'b'} → 0.30, {'d'} → 0.30
-    …
+    {'a', 'c'} → 0.40, {'b'} → 0.30, {'d'} → 0.30              0         1
+    {'a', 'c'} → 0.40, {'b', 'd'} → 0.6                        0    0    1    1
+    {'a', 'c', 'b', 'd'} → 1.0                                00   10   01   11
diff --git a/greedy-algorithms/src/features/encoding/solver.js b/greedy-algorithms/src/features/encoding/solver.js
index 7c7344bb7c83a81a24a9cc163affa00b9802e719..0b84bd6b0b7ad91b8d517f3e2f005b6e199a8d6e 100644
--- a/greedy-algorithms/src/features/encoding/solver.js
+++ b/greedy-algorithms/src/features/encoding/solver.js
@@ -1,8 +1,25 @@
+import { PriorityQueue } from './collections.js';
+
 export function findEncoding(frequencies) {
   const results = new Map();
+  const partitioning = new PriorityQueue();
   for (const [meaning, frequency] of frequencies) {
     results.set(meaning, '');
+    partitioning.insert(new Set([meaning]), frequency);
+  }
+  while (partitioning.size > 1) {
+    const [firstMeanings, firstFrequency] = partitioning.remove();
+    const [secondMeanings, secondFrequency] = partitioning.remove();
+    for (const meaning of firstMeanings) {
+      results.set(meaning, `0${results.get(meaning)}`);
+    }
+    for (const meaning of secondMeanings) {
+      results.set(meaning, `1${results.get(meaning)}`);
+    }
+    partitioning.insert(
+      new Set([...firstMeanings, ...secondMeanings]),
+      firstFrequency + secondFrequency,
+    );
   }
-  // TODO: stub
   return results;
 }
diff --git a/greedy-algorithms/src/features/fueling/solver.js b/greedy-algorithms/src/features/fueling/solver.js
index 18326349a6727b0110a14ffee9f92a0950e54315..b97bec004a4201343edfd53cf9000fc8b480be30 100644
--- a/greedy-algorithms/src/features/fueling/solver.js
+++ b/greedy-algorithms/src/features/fueling/solver.js
@@ -7,7 +7,16 @@ export function planFuelings(gaps, range) {
     gaps.every((gap) => gap <= range),
     `Tried to find a fueling plan crossing a gap longer than the range ${range}.`,
   );
-  const results = [];
-  // TODO: stub
+  const results = [0];
+  const destination = gaps.length;
+  while (results[results.length - 1] < destination) {
+    let best = undefined;
+    for (let distance = 0, candidate = results[results.length - 1];
+      distance <= range && candidate <= destination;
+      distance += gaps[candidate], ++candidate) {
+      best = candidate;
+    }
+    results.push(best);
+  }
   return results;
 }