There are quite some things to be improved here, the first would be to use the more idiomatic defn
instead of (def name (fn
scheme. The next would be your names which I find to be not very clear. Others have pointed you in the direction to use partition
, which I would agree to, but in the solution below I tried to keep to the spirit of your approach.
As you've discovered yourself, it makes a lot of sense to turn the number into a sequence of digits, because we're gonna need sequence operations anyway. So let's start with that:
(defn decimal-digits [number]
(letfn [(ddigits-helper [number result]
(if (number > 0)
(recur (int (/ number 10)) (conj result (mod number 10)))
result))]
(ddigits-helper number '())))
This approach uses simple math to collect the numbers. It also shows the use of recur
for recursion and uses an accumulator (the result
argument) to collect intermediate results.
Here are your two initial functions which we assume to operate on a list of digits now:
(defn new-part [number size]
(take size number))
(defn rest-part [number size]
(drop size number))
As discussed, you could also use partition
or split-at
.
Now, your main function could look like this:
(defn partition-number
[number size]
(let [digits (decimal-digits number)]
(cond (> size (count digits)) digits
true (cons (new-part digits size)
(partition-number
(digits-to-decimal (rest-part digits size))
size)))))
This is very close in style to your approach but shows that we need to turn the digits back to a number because that's what partition-number
expects.
(defn digits-to-decimal [digits]
(let [powers-of-ten (iterate (partial * 10) 1)
digits (reverse digits)]
(reduce +
(map-indexed (fn [position digit]
(* digit (nth powers-of-ten position)))
digits))))
However, if we restructure partition-number
to also use a helper function with an accumulator, we can also use recur
which is how one can avoid blowing the stack on recursive calls in clojure:
(defn partition-number
[number size]
(letfn [(partnumb-helper [digits size result]
(cond (> size (count digits)) (conj result digits)
true (recur (rest-part digits size)
size
(conj result (new-part digits size)))))]
(partnumb-helper (decimal-digits number) size '[])))
Note that this way we also spare to convert between numbers and digits all the time.