            :block-succs block-preds
            :block-preds block-succs
            :sources sinks
-           :sinks sources)))
-
-(defrecord YPlottedClassGraph [classes ys char-sep]
-  YPlotted
-  (min-y [_]
-    (apply min (map #(ys (ffirst %)) classes)))
-  (max-y [_]
+           :sinks sources))
+
+  YPlottable
+  (ys [this node-sep char-sep]
+    (memo-ys this node-sep char-sep))
+
+  (min-y [this node-sep char-sep]
+    (apply min (map #(get (ys this node-sep char-sep) (ffirst %)) classes)))
+
+  (max-y [this node-sep char-sep]
     (->> classes
          (mapcat peek)
-         (map #(+ (ys %) (* char-sep (dec (:weight %)))))
+         (map #(+ (get (ys this node-sep char-sep) %)
+                  (* char-sep (dec (:weight %)))))
          (apply max)))
-  (width [this]
-    (- (max-y this) (min-y this)))
-  (shift-y [this delta]
-    (assoc this :ys (into {}
-                          (map (fn [[node y]]
-                                 [node (+ y delta)])
-                               ys)))))
+
+  (width [this node-sep char-sep]
+    (- (max-y this node-sep char-sep) (min-y this node-sep char-sep)))
+
+  (shift-ys [this node-sep char-sep delta]
+    (->> (ys this node-sep char-sep)
+         (map (fn [[node y]]
+                [node (+ y delta)]))
+         (into {}))))
 
 
 (defn check-alignment

  "Generates coordinates for all paths in a FlatGraph"
  [flat-graph max-slope min-arc-radius layer-sep node-sep char-sep]
  (let [{:keys [layers characters]} flat-graph
        node-ys (FlatGraph->node-ys flat-graph node-sep char-sep)
        paths-y (->> (nodes flat-graph)
                     (mapcat (fn [node]
                               (map-indexed (fn [i c]

  block graph. If you reflect the graph though, you'll see that we're working
  from the same block and getting the same result."
  [flat-graph node-sep char-sep]
  (let [class-graphs (FlatGraph->ClassGraphs flat-graph)
        narrowest (apply min-key #(width % node-sep char-sep) class-graphs)
        narrow-min-y (min-y narrowest node-sep char-sep)
        narrow-max-y (max-y narrowest node-sep char-sep)]
    (->> class-graphs
         (map #(let [delta (if (:aligned-down (meta %))
                             (- narrow-max-y (max-y % node-sep char-sep))
                             (- narrow-min-y (min-y % node-sep char-sep)))]
                 (shift-ys % node-sep char-sep delta)))
         (apply merge-with #(if (vector? %1) (conj %1 %2) [%1 %2]))
         (map (fn [[node ys]]
                (let [sort-ys (sort ys)]
                  [node (/ (+ (nth sort-ys 1) (nth sort-ys 2)) 2)])))
         (into {}))))


(defn arc-distance
