     treeify
     bracket))
 
-(defn- compute-round-dispatch [_ node]
-  (when (and (map? node) (contains? node :upper) (contains? node :lower))
-    (if (get-in node [:data :round])
-      :branch
-      :root)))
-
-(defmulti #^{:private true} compute-round
-          compute-round-dispatch)
-(defmethod compute-round :default [_ node]
-  node)
-(defmethod compute-round :branch [_ node]
-  (let [current-round (get-in node [:data :round])]
-    (-> (assoc-in node [:upper :data :round] (dec current-round))
-        (assoc-in [:lower :data :round] (dec current-round)))))
-(defmethod compute-round :root [max-rounds node]
-  (compute-round max-rounds (assoc-in node [:data :round] max-rounds)))
+(defn- branch? [node]
+  (and (map? node) (contains? node :upper) (contains? node :lower)))
+
+(defn children [node]
+  ((juxt :upper :lower) node))
+
+(defn make-node [existing [upper lower]]
+  (-> (assoc-in existing [:upper] upper)
+      (assoc-in [:lower] lower)))
+
+(defn- update-round [rnd node]
+  (assoc-in node [:data :round] rnd))
+
+(defn- compute-round [loc]
+  (if (zip/end? loc)
+    loc
+    (if-let [parent-round (some-> (zip/up loc)
+                                  zip/node
+                                  (get-in [:data :round]))]
+      (recur (zip/next (zip/edit loc (partial update-round (dec parent-round)))))
+      (recur (zip/next loc)))))
 
 (defn round-info [max-rounds tree]
-  (walk/prewalk
-    (partial compute-round max-rounds)
-    tree))
+  (->> (update-round max-rounds tree)
+       (zip/zipper
+         branch?
+         children
+         make-node)
+       compute-round
+       zip/root))
 
 (defn weighted-pairing-log5
   "Compute and update the chance that Team a and Team b will advance when playing against each other,

  (let [parent-team-map (->> (get-in node [:data :teams])
                             (map #((juxt :name identity) %))
                             (into {}))]
    (if (and (get node :upper) (get node :lower))
      (-> (update-in node [:upper] (partial update-child-expected-value parent-team-map))
          (update-in [:lower] (partial update-child-expected-value parent-team-map)))
      node)))

  (if (zip/end? loc)
    loc
    (recur (zip/next (zip/edit loc update-expected-value)))))

(defn compute-expected-value
  "Compute the expected value for each node in the tournament probabilites tree."
