How can I generate serial lists by combining any two elements from a longer list, say with 4 elements?
For example, I want to get '(1 2), '(1 3), '(1 4), '(2 3), '(2 4), and '(3 4) based on '(1 2 3 4).
The question asks for the 2-sized list of combinations of a given list. It can be implemented in terms of a more general procedure that produces n-sized combinations:
(define (combinations size elements)
(cond [(zero? size)
'(())]
[(empty? elements)
empty]
[else
(append (map (curry cons (first elements))
(combinations (sub1 size) (rest elements)))
(combinations size (rest elements)))]))
It works as expected when we specify that size=2:
(combinations 2 '(1 2 3 4))
=> '((1 2) (1 3) (1 4) (2 3) (2 4) (3 4))
Here is a solution just as you specified (one function, one argument). For input like '(next rest ...) the solution computes a result for next and then recurses on rest ... - using append to combine the two parts.
(define (combine elts)
(if (null? elts)
'()
(let ((next (car elts))
(rest (cdr elts)))
(append (map (lambda (other) (list next other)) rest)
(combine rest)))))
> (combine '(1 2 3 4))
((1 2) (1 3) (1 4) (2 3) (2 4) (3 4))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With