Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Partition by a seq of integers

Tags:

clojure

What would be a more idiomatic way to partition a seq based on a seq of integers instead of just one integer?

Here's my implementation:

(defn partition-by-seq
  "Return a lazy sequence of lists with a variable number of items each
  determined by the n in ncoll.  Extra values in coll are dropped."
  [ncoll coll]
  (let [partition-coll (mapcat #(repeat % %) ncoll)]
    (->> coll
         (map vector partition-coll)
         (partition-by first)
         (map (partial map last)))))

Then (partition-by-seq [2 3 6] (range)) yields ((0 1) (2 3 4) (5 6 7 8 9 10)).

like image 272
ToBeReplaced Avatar asked Mar 05 '13 16:03

ToBeReplaced


People also ask

What is meant by integer partition?

In number theory and combinatorics, a partition of a positive integer n, also called an integer partition, is a way of writing n as a sum of positive integers. Two sums that differ only in the order of their summands are considered the same partition. (If order matters, the sum becomes a composition.)

How do you calculate partition of a number?

A multiset of positive integers that add to n is called a partition of n. Thus the partitions of 3 are 1+1+1, 1+2 (which is the same as 2+1) and 3. The number of partitions of k is denoted by p(k); in computing the partitions of 3 we showed that p(3)=3.

How many partitions will be formed for the integer 3?

How many partitions will be formed for the integer 3? Explanation: We need to find the combinations of positive integers which give 3 as their sum. These will be {3}, {2,1}, {1,1,1}. Thus the correct answer is 3.

What is Ramanujan partition theory?

Ramanujan's approximate formula, developed in 1918, helped him spot that numbers ending in 4 or 9 have a partition number divisible by 5, and he found similar rules for partition numbers divisible by 7 and 11. Without offering a proof, he wrote that these numbers had “simple properties” possessed by no others.


2 Answers

Your implementation looks fine, but there could be a more simple solution which uses simple recursion wrapped in lazy-seq(and turns out to be more efficient) than using map and existing partition-by as in your case.

(defn partition-by-seq [ncoll coll]
  (if (empty? ncoll)
    '()
    (let [n (first ncoll)]
      (cons (take n coll)
            (lazy-seq (partition-by-seq (rest ncoll) (drop n coll)))))))
like image 79
Ankur Avatar answered Nov 12 '22 16:11

Ankur


A variation on Ankur's answer, with a minor addition of laziness and when-let instead of an explicit test for empty?.

 (defn partition-by-seq [parts coll]
    (lazy-seq
      (when-let [s (seq parts)]
        (cons
          (take (first s) coll)
          (partition-by-seq (rest s) (nthrest coll (first s)))))))
like image 24
Rafał Dowgird Avatar answered Nov 12 '22 16:11

Rafał Dowgird