Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save flengyel/1434997 to your computer and use it in GitHub Desktop.
Save flengyel/1434997 to your computer and use it in GitHub Desktop.
My solution to Graph Tour https://4clojure.com/problem/89
;; flengyel's solution to Graph Tour
;; https://4clojure.com/problem/89
;; The edge vector is a vector of edges, each a vector with two vertices [e1 e2]
(fn [edgevec]
(letfn [(neighbors [edgevec] ;; map each vertex to its set of neighbors
(reduce
(fn [m e]
(letfn [(addmap [m a b] (assoc m a (if-let [nbdset (get m a)]
(conj nbdset b)
(set (list b)))))]
(let [a (e 0) b (e 1)]
(addmap (addmap m a b) b a)))) ;; reduce function
{} edgevec))
(connected? [edgevec]
(let [N (neighbors edgevec)
vertices (keys N)
q (atom clojure.lang.PersistentQueue/EMPTY)]
(letfn [(nq [v] (swap! q #(conj % v)))
(hq [] (peek @ q))
(dq [] (swap! q pop ))]
(nq (first vertices))
(loop [bag #{}]
(if-let [head (hq)]
(do (dq) (loop [v (vec (N head))]
(if (not (empty? v))
(do
(if (not (contains? bag (first v))) (nq (first v)))
(recur (rest v)))))
(recur (conj bag head)))
(= (set vertices) bag))))))
(degmod2 [edgevec]
(reduce
(fn [m e]
(letfn [(addmap [m a b] (assoc m a (if-let [bit (get m a)] (bit-xor bit 1) 1)))]
(let [a (e 0) b (e 1)]
(addmap (addmap m a b) b a))))
{} edgevec))]
(let [oddballs (reduce + (vals (degmod2 edgevec)))]
(and (connected? edgevec) (<= oddballs 2)))))
@flengyel
Copy link
Author

flengyel commented Dec 6, 2011

The addmap function, which appears twice, should be used once. The first use builds the set of neighborhoods of a vertex. The second variant counts degree of each vertex modulo 2. The number of odd degree vertices must be less than or equal to 2 for the tour to exist.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment