0

I'm currently working on a route planning program in clojure. I'm using ubergraph to create my data structure and then using ubergraphs built in shortest-path algorithm. I have it working with 2 arguments being passed in and also have it working with passing 3 arguments in.

However, instead of writing a new function each time I want to pass in more arguments is there a way to write a recursive version that can take in any number of arguments?

(defn journey [start end]
  (alg/pprint-path (alg/shortest-path all-edges {:start-node start, :end-node end, :cost-attr :weight})))



(journey :main-office :r131)

(defn fullpath [start delivery end]
  (journey start delivery)
  (journey delivery end))


(fullpath :main-office :r131 :main-office)
(fullpath :main-office :r119 :main-office)

Above is the code I currently have which is working fine.

Would it be possible to write a function that could accept the arguments below for example and still print out the path taken.

(fullpath :main-office :r113 :r115 :main-office)

Any help greatly appreciated.

benjano
  • 369
  • 1
  • 5
  • 17
  • Have you checked this [page](http://stackoverflow.com/questions/9242440/how-to-make-a-clojure-function-take-a-variable-number-of-parameters)? Have you tried `apply`? – jmargolisvt Mar 15 '17 at 18:36
  • Hi, if my understanding of apply is correct it won't work in this case? I'm trying to write a recursive function that plans the route through all the variables passed in (classed as rooms in my case). So when 2 args are passed in it plans the route from a -> b, but then I want it so if I pass in 3 variables it plans a -> b and then b -> c etc. – benjano Mar 15 '17 at 18:43
  • defining a function with [& args] will bind all arguments you pass to the function to the parameter args – David Bern Mar 15 '17 at 18:51
  • So whatever is passed in will be bound to the variable named args? That doesn't seem like it would work for passing in a various amount of rooms and peforming shortest path on them? – benjano Mar 15 '17 at 18:53

1 Answers1

1

The following should work

(defn fullpath [& stops]
  (map (fn [a b] (journey a b)) stops (rest stops) )

Which for

(fullpath :a :b :c ..)

collects the result of

(journey :a :b)
(journey :b :c)
...

into a collection. Since your return value of journey seems to be nil and you are only interested in the side effect of printing it, you probably want to put in a doall, i.e.

(defn fullpath [& stops]
  (doall (map (fn [a b] (journey a b)) stops (rest stops) ))
j_d
  • 81
  • 3