Fork me on GitHub
#beginners
<
2016-09-23
>
dunn.mat02:09:22

I’m trying to divide up a vector into a list of x vectors. I thought of using partition and partition-all but they all take the size I want each vector to be, but I’m trying to make x vectors, and have them be as close to the same size as possible. Basically if I have:

[1 2 3 4 5 6 7 8 9]  and want 5 groups I want them like ([1 2] [3 4] [5 6] [7 8] [9])
Is there a function similar to partition-all that would do this? I can’t use partition-all because my input list is of variable length so i don’t know how long I want each list to be, but I do know I want them to always be in x groups

isaac_cambron02:09:39

(defn partition-x [x col]
  (partition-all (/ (count col) x) col))

dunn.mat02:09:51

I tried that, but since it comes out as a decimal and gives the wrong amount of groups sometimes. For example, with 15 items, 9 groups, that function gives me 8 groups

isaac_cambron02:09:39

oh right, you need two groups of 1 at the end. that does seem a little tricky

dunn.mat03:09:53

yeah, it’s more like a "best-effort distribute coll amongst n lists"

plexus12:09:54

(let [c1 (chan)
      c2 (chan)]
  (go (>! c1 :val1)
      (>! c2 :val2))
  [(<!! (go (alt! c1 ([v] [:result1 v]) 
                  c2 ([x y] [:result2 x y]))))
   (<!! (go (alt! c1 ([v] [:result1 v]) 
                  c2 ([x y] [:result2 x y]))))])

plexus12:09:58

I had to try it out myself to figure out how it behaves, the docs aren't super clear. If the "operation" is of the form ([x] ,,,) then x will be bound to the value that came from the channel

plexus12:09:25

if it's ([x y] ,,,) then x still receives the value, and y is bound to the channel

plexus12:09:55

in this case in each branch we know exactly which channel was used, but you can also specifiy multiple channels in a vector, so then it will be useful to know which one was actually used

dfan12:09:28

@dunn.mat Probably unidiomatic in some way since I’m a Clojure newbie, but:

dfan12:09:40

(defn partition-x
  ([num-groups coll]
   (partition-x num-groups coll (count coll)))
  ([num-groups coll len]
   (if (= num-groups 1)
     (list coll)
     (let [group-size (quot (+ len num-groups -1)  num-groups)
           [first-group rest-coll] (split-at group-size coll)]
       (cons first-group
             (partition-x (dec num-groups) rest-coll (- len group-size)))))))

rusua13:09:06

thank you @plexus!! All clear now 😉 So with your example, and the docs, I see that basically x ([v] v) gets you the value from the channel where x is just one single channel. I was confused, because [x y c] ([v] v) is also possible, for those cases in which you wouldn't care what channel was exactly the one you got the value from. I guess those cases exist, but the docs weren't really covering that case. Thanks again, it was very helpful!

plexus13:09:33

my pleasure! come back if you have any more questions 🙂

rusua13:09:55

Thanks 🙂 I will!

snow14:09:22

Hi everyone. I'm currently learning clojure and try some challenges on hackerrank. There was a challenge to print each element of an array n times. My solution looks like this

((fn [num lst]
   (map 
     #(loop [cnt 0]
        (when (< cnt num)
          (println %)
          (recur (inc cnt))))
     lst))
   3 [1 2 3 4])
which is kinda complicated in my opinion. Is there another shorter and more elegant way to solve this?

dfan14:09:34

(defn repeat-print [num lst]
  (doseq [elt lst] (dotimes [n num] (println elt))))

dfan14:09:05

Use doseq instead of map if you’re throwing away the result

dfan14:09:23

And dotimes is the idiomatic way to perform that inner loop

dunn.mat14:09:35

@dfan this gives the right output, but I too wonder if it’s a little unidiomatic. I’ll play around at trying to simplify it but this is a good place to start. Thanks!

snow14:09:51

@dfan thank you, didn't know these two functions yet 🙂

dfan14:09:53

Yeah, the important thing is to guess (as you did) that there must be a more elegant way 🙂

plexus14:09:37

@snow a more "functional" solution

plexus14:09:42

(run! println (mapcat (partial repeat 3) [1 2 3 4]))

vinnyataide23:09:19

hello guys, is there any link to examples of clojure spec code?

vinnyataide23:09:55

I can see the vision but I still lack the experience