Interesting idea. Will look into how shuffle works and see if I can adapt that instead. Thanks :)
On Sat, Aug 15, 2015 at 7:56 AM, Gary Fredericks <fredericksg...@gmail.com> wrote: > Another kind of approach that would be worth trying is adapting > test.check's own shuffle generator > <https://github.com/clojure/test.check/blob/e3256cbaa3a98b1d688475fe190aa97ad255e08b/src/main/clojure/clojure/test/check/generators.clj#L447-465>. > It generates a sequence of pairs of indexes and then swaps the elements at > those indexes. The benefits are that you avoid the stack issues and also > other disadvantages that come with using bind. > > I tried one that only did adjacent swaps, and only when they didn't > violate the constraint, but it took a lot of swaps for it to get really > mixed up. I think something more clever could be better. > > Gary > > On Friday, August 14, 2015 at 9:43:52 AM UTC-5, Carlo 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 <fires...@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 clo...@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+u...@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+u...@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.