          (case code
            (\p \m)  (recur (next xs) ys result)
            (\P \M)  (recur xs (next ys) result)
-           \S (recur (cons (derive-interval (second y) (second x) x)
+           \S (recur (cons (update-interval x (second y) (second x))
                            (next xs))
                      (next ys)
-                     (clojure.core/conj result (augment-interval y x)))
+                     (clojure.core/conj result (update-interval x y)))
            \F (recur (next xs) (next ys) (clojure.core/conj result y))
-           \o (recur (cons (derive-interval (first y) (second x) x)
+           \o (recur (cons (update-interval x (first y) (second x))
                            (next xs))
-                     (cons (derive-interval (second x) (second y) x) (next ys))
+                     (cons (update-interval x (second x) (second y)) (next ys))
                      (clojure.core/conj
                       result
-                      (derive-interval (first y) (second x) x)))
+                      (update-interval x (first y) (second x))))
            \O (recur (cons
-                      (derive-interval (second y) (second x) x)
+                      (update-interval x (second y) (second x))
                       (next xs))
                      (next ys)
                      (clojure.core/conj
                       result
-                      (derive-interval (first x) (second y) x)))
+                      (update-interval x (first x) (second y))))
            \D (recur (cons
-                      (derive-interval (second y) (second x) x)
+                      (update-interval x (second y) (second x))
                       (next xs))
                      (next ys)
-                     (clojure.core/conj result (augment-interval y x)))
-           \d (recur (next xs) (cons (derive-interval (second x) (second y) x)
+                     (clojure.core/conj result (update-interval x y)))
+           \d (recur (next xs) (cons (update-interval x (second x) (second y))
                                      (next ys))
                      (clojure.core/conj result x))
            \e (recur (next xs) (next ys) (clojure.core/conj result x))
            \f (recur (next xs) (next ys) (clojure.core/conj result x))
            \s (recur (next xs)
-                     (cons (derive-interval (second x) (second y) x)
+                     (cons (update-interval x (second x) (second y))
                            (next ys))
                      (clojure.core/conj result x))))
        result)))

  (->> (f ival)
       (map interval)
       (map (partial concur ival))
       (map #(augment-interval % ival))
       (remove nil?)))

(defn group-segments-by

             (\f \d \e) (recur (next xs) (next ys) result)
             \s (recur (next xs) ys result)
             (\S \O) (recur (cons (interval (second y) (second x)) (next xs)) (next ys) result)
             \F (recur (next xs) (next ys) (clojure.core/conj result (update-interval x (first x) (first y))))
             \o (recur (next xs) ys (clojure.core/conj result (update-interval x (first x) (first y))))
             \D (recur (cons (interval (second y) (second x)) (next xs))
                       (next ys)
                       (clojure.core/conj result (update-interval x (first x) (first y))))))
         (apply clojure.core/conj result xs))
       result)))
  ([s1 s2 & sets]
