I'm learning clojure (coming from ruby) and having some trouble wrapping my head around the best way to generate collections.
I'd like to write a function that takes two arguments -- the vector ary and integer sum -- and generates a new 2D vector in which each row's sum is <= the input sum (ignore input validation). The conceptual point I'm having trouble with is how to keep the state of "sum of current row" while also building up a new collection.
Here's what I've got:
(defn split-after-sum [ary sum]
(reduce (fn [acc i]
(let [inner-sum (+ (last acc) i)]
(if (< inner-sum sum)
[(conj (first acc) i) (+ i (last acc))]
[(conj (first acc) i "X") 0])))
[[] 0] ary))
I'm passing reduce a 2 element vector in order to keep track of both the collection I'm building and the total count of this row.
It sort of works. I haven't figured out how to actually make the result a 2D array so it's just sticking "X"s where the splits should be:
(first (split-after-sum [1 1 1 1 1 1 1 1 1] 2)) => [1 1 "X" 1 1 "X" 1 1 "X" 1 1 "X" 1]
Ideal output would be:
(split-after-sum [1 1 1 1 1 1 1 1 1] 2) => [[1 1] [1 1] [1 1] [1 1] [1]]
I know there are a few things jumbled up in here, but I think an idiomatic answer to this problem would be enlightening.