Joseph G
Joseph G

Reputation: 43

Combine sequence with itself recursively, without duplicates

This is hard to explain but easy to show. Not sure why I haven't figured it out myself, so I must be missing something in clojure that is obvious.

I need to combine a vector with itself, into a vector, and I need to combine the first element with all the remaining elements, then the 2nd element, with all the remaining elements (3rd and after).

As a short example: [1 2 3 4 5]

I need a function to get: [[1 2] [1 3] [1 4] [1 5] [2 3] [2 4] [2 5] [3 4] [3 5]]

If this looks like getting half the pairs for a large matrix, you are right. I only want to solve half the matrix minus the middle diagonal. This is the only part I need to be sequential(so I only solve half) and the rest I want to use the reducers library to parallelize the heavier math in the background.

Thanks in advance!

Upvotes: 1

Views: 231

Answers (3)

mobyte
mobyte

Reputation: 3752

(def v [1 2 3 4 5])

(for [i (range (count v)) 
      :let [vv (drop i v)] 
      r (rest vv)] 
  [(first vv) r])

=> ([1 2] [1 3] [1 4] [1 5] [2 3] [2 4] [2 5] [3 4] [3 5] [4 5])

Upvotes: 0

Blacksad
Blacksad

Reputation: 15442

I'd just use a for :

(for [ i (range 1 6) j (range 6) :when (< i j)] [i j])
; => ([1 2] [1 3] [1 4] [1 5] [2 3] [2 4] [2 5] [3 4] [3 5] [4 5])

Upvotes: 3

Kevin
Kevin

Reputation: 25269

What you want is built into clojure/math.combinatorics: https://github.com/clojure/math.combinatorics

The basic example you are looking for is on the readme, but for completeness to this answer, I'll repeat it here:

(ns example.core
    (:require [clojure.math.combinatorics :as combo]))

(combo/combinations [1 2 3] 2)
;;=> ((1 2) (1 3) (2 3))

Upvotes: 3

Related Questions