September 14, 2018
Just Juxt #31: Graph Tour (4clojure #89)
Starting with a graph you must write a function that returns true if it is possible to make a tour of the graph in which every edge is visited exactly once.
The graph is represented by a vector of tuples, where each tuple represents a single edge.
The rules are:
- You can start at any node.
- You must visit each edge exactly once.
- All edges are undirected.
(ns live.test
(:require [cljs.test :refer-macros [deftest is testing run-tests]]))
(defn eulerian [g]
(if (= (count g) (count (distinct g)))
(let [g (apply merge-with clojure.set/union
(mapcat (fn [[k v]] [{k #{v}} {v #{k}}]) g))
f (fn [[s k]]
(->> (g k)
(remove s)
(map #(vector (conj s %) %))))
p (map (juxt hash-set identity) (keys g))]
(not (empty? (nth (iterate (partial mapcat f) p) (dec (count g))))))
false))
(deftest eulerian-test
(is (= true (eulerian [[:a :b]])))
(is (= false (eulerian [[:a :a] [:b :b]])))
(is (= false (eulerian [[:a :b] [:a :b] [:a :c] [:c :a]
[:a :d] [:b :d] [:c :d]])))
(is (= true (eulerian [[1 2] [2 3] [3 4] [4 1]])))
(is (= true (eulerian [[:a :b] [:a :c] [:c :b] [:a :e]
[:b :e] [:a :d] [:b :d] [:c :e]
[:d :e] [:c :f] [:d :f]])))
(is (= false (eulerian [[1 2] [2 3] [2 4] [2 5]]))))
(run-tests)