Ah right! I knew I had to use gen/choose for this, I am still grokking bind :)
Thanks for your help! That indeed did the trick for me :) One thing I am clear about is, If I use gen/return it says it'll not shrink. Does that mean when a test fails for a certain order, it won't try to shrink that order of collection? Because I have used a gen/return at the end of the generator? Thanks again for your help! :) On Fri, Aug 14, 2015 at 8:13 PM, Carlo Zancanaro <carlozancan...@gmail.com> wrote: > Hey Mayank! > > Similarly to your attempt last time, you need to use gen/bind to get the > result of a generator which you can then use to make a new generator. > > (defn- rand-interleave* [coll acc] > (if (seq coll) > (gen/bind (gen/choose 0 (dec (count coll))) > (fn [index] > (let [value (first (get coll index)) > coll (->> (update-in coll [index] next) > (remove empty?) > vec)] > (rand-interleave* coll (conj acc value))))) > (gen/return acc))) > > (defn rand-interleave [& colls] > (rand-interleave* (vec colls) [])) > > The (gen/choose 0 (dec (count coll))) is similar to your rand-count > function, then the generated number is passed to the function as result. > Writing it this way will shrink towards the (apply concat args) (ie. as > it shrinks it will move towards just concatenating the arguments). > > In terms of the recursion: this will eventually overflow the stack. I > don't know of a way to trampoline generators, so I don't know how to avoid > that. (This is a bit of a recurring problem with monadic code in Clojure, I > feel, as algo.monads had a similar problem last time I checked.) For the > moment I'm just ignoring this theoretical problem until it becomes a > practical problem. > > I hope that helps! > > Carlo > > On 14 August 2015 at 23:39, Mayank Jain <firesof...@gmail.com> wrote: > >> Hi Everyone, >> >> Here's the problem I am facing, >> I need to write a generator which takes any number of sequences, >> interleaves them but maintains the order within each sequence. >> Assume each sequence has at least one element. >> >> For example: >> >> (rand-interleave [1 2 3 4] [:a :b] [:A :B :C :D :E]) >>> => [:a 1 2 :b :A :B :C 3 :D 4 :E] >> >> >> (rand-interleave [1 2 3 4]) >>> => [1 2 3 4] >> >> >> (rand-interleave [1]) >>> => [1] >> >> >> (rand-interleave [1] [:a] [:A]) >>> => [:a 1 :A] >> >> >> I have been able to write this down as clojure functions. >> But I am unable to convert this into a test.check generator. >> >> Specifically: >> >> - How to pass random index count without using rand-int i.e. use >> gen/choose >> - How do I write recursive functions which play well with test.check >> >> Here's my take on it (without the generators). >> >> (defn- first-nth >>> "(first-nth [[1 2 3 4] [:a :b :c :d]] >>> 1) >>> => :a" >>> [coll n] >>> (first (nth coll n))) >> >> >> >> (defn- next-nth >>> "(next-nth [[1 2 3 4] [:a :b :c :d]] >>> 1) >>> => [[1 2 3 4] (:b :c :d)]" >>> [coll n] >>> (->> n >>> (nth coll) >>> next >>> (assoc coll n) >>> (remove nil?) >>> vec)) >> >> >> >> (defn- rand-count >>> [coll] >>> (rand-int (count coll))) >> >> >> >> (defn- rand-interleave* >>> [coll acc] >>> (let [n (rand-count coll)] >>> (if (not-empty coll) >>> (rand-interleave* (next-nth coll n) >>> (conj acc >>> (first-nth coll n))) >>> acc))) >> >> >> >> (defn rand-interleave >>> [& args] >>> ;; Make args a vector as I would like to >>> ;; look up elements by their index values. >>> (rand-interleave* (vec args) [])) >> >> >> Looking forward to any suggestions on how to solve it :) >> >> Thanks, >> Mayank. >> >> -- >> You received this message because you are subscribed to the Google >> Groups "Clojure" group. >> To post to this group, send email to clojure@googlegroups.com >> Note that posts from new members are moderated - please be patient with >> your first post. >> To unsubscribe from this group, send email to >> clojure+unsubscr...@googlegroups.com >> For more options, visit this group at >> http://groups.google.com/group/clojure?hl=en >> --- >> You received this message because you are subscribed to the Google Groups >> "Clojure" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to clojure+unsubscr...@googlegroups.com. >> For more options, visit https://groups.google.com/d/optout. >> > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > --- > You received this message because you are subscribed to the Google Groups > "Clojure" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to clojure+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.