I'm trying to learn a Lisp language and have settled on Guile and am trying to solve this problem:
You are given an integer array coins representing coins of different denominations and an integer amount representing a total amount of money.
Return the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return -1.
You may assume that you have an infinite number of each kind of coin.
Fundamentally, I understand the basic of dynamic programming where you can use recursion and memoization in order to save calculating at lower depths, but as Lisp I would expect it to be perfect for this type of problem. The problem I am having is returning separate lists for each combination of coins.
For an example case, consider target of 6 with coins [2, 3]. The simple tree would look like this:
The correct answer would be (3 3) with the other "complete" solution being (2 2 2).
However, if I try and construct these, the form I would want to use (without memoization) would look something like this.
(define get-coins (lambda (coins target)
(cond
((= target 0) '())
; not quite sure how to "terminate" a list here
; An idea is to return (list -1) and then filter
; lists that contain -1
((< target 0) ?????)
(else
; for each coin, recurse
(map (lambda (v)
(cons v (get-coins coins (- target v))))))
)
))
However, this doesn't return more lists as it goes through. Rather, it creates nested lists. And this is my problem. Any help with this would be greatly appreciated.
I wanted to avoid nested lists, so I used a variable results:
(define (get-coins coins target)
(let ((results '()))
Then I defined the function get-coins-helper, similar to your get-coins. And whenever I found some possible result, I used set! to update results:
(letrec ((get-coins-helper
(lambda (coins target result)
(cond ((= target 0) (set! results (cons result results)))
((< target 0) '())
(else (map (lambda (value)
(get-coins-helper coins
(- target value)
(cons value result)))
coins))))))
Then I called (get-coins-helper coins target '()) to find all possible results and at the end, I checked the value of results and returned -1 (if results are empty) or the shortest element of results:
(if (null? results)
-1
(car (sort results (lambda (x y) (< (length x)
(length y))))))
Full code:
(define (get-coins coins target)
(let ((results '()))
(letrec ((get-coins-helper
(lambda (coins target result)
(cond ((= target 0) (set! results (cons result results)))
((< target 0) '())
(else (map (lambda (value)
(get-coins-helper coins
(- target value)
(cons value result)))
coins))))))
(get-coins-helper coins target '())
(if (null? results)
-1
(car (sort results (lambda (x y) (< (length x)
(length y)))))))))
Some tests:
> (get-coins '(2 3) 6)
'(3 3)
> (get-coins '(2 3) 1)
-1
Using fold to choose best solutions. The result is a list whose car is the number of coins and cdr is the list of chosen coins. In the event that no solutions are feasible, (+inf.0) is returned.
(use-modules (srfi srfi-1))
(define (get-coins coins target)
(fold (lambda (coin best)
(let [(target (- target coin))]
(cond [(zero? target)
(list 1 coin)]
[(positive? target)
(let* [(res (get-coins coins target))
(score' (1+ (car res)))]
(if (< score' (car best))
(cons score' (cons coin (cdr res)))
best))]
[(negative? target)
best])))
(list +inf.0)
coins))
(get-coins (list 2) 6)
$8 = (3 2 2 2)
(get-coins (list 2 3) 6)
$9 = (2 3 3)
(get-coins (list 9) 6)
$10 = (+inf.0)
If you read the question carefully, all you need to keep track of is the number of coins needed to reach the target amount. You don't have generate every possible combination of coins to reach the target, just the one that minimizes the number of coins. And you don't even have to remember what that particular combination is, just its length. This simplifies things a bit since there's no need to build any lists.
For each denomination of coin that can possibly be used to reach the goal (So no coins bigger than the difference between the goal and the current sum), get the counts for using one of them and for using none of them, and return the minimum (Or -1 if no options present themselves).
(define (get-coins coins target)
(calculate-coins coins 0 0 target))
;; Do all the work in a helper function
(define (calculate-coins coins coin-count amount target)
(cond
((= amount target) coin-count) ; Success
((null? coins) -1) ; Failure
((> (car coins) (- target amount)) ; Current coin denomination is too big; skip it
(calculate-coins (cdr coins) coin-count amount target))
(else
;; Cases to consider:
;; Adding one of the current coin to the total and leaving open using more
;; Not using any of the current coins
(let ((with-first
(calculate-coins coins (+ coin-count 1) (+ amount (car coins)) target))
(without-first
(calculate-coins (cdr coins) coin-count amount target)))
(cond
((= with-first -1) without-first)
((= without-first -1) with-first)
(else (min with-first without-first)))))))
If you do want to get every possible combination of coin, one way is to, for each list of combinations that use a given coin, use append to combine it with a list of previous ways:
(use-modules (srfi srfi-1))
(define (get-coins2 coins target)
(define (helper target) ; This time define a nested helper function
(fold
(lambda (coin ways)
(cond
((= coin target) (cons (list coin) ways))
((< coin target)
(append
(map (lambda (c) (cons coin c))
(helper (- target coin)))
ways))
(else ways)))
'()
coins))
(let* ((ways (helper target))
(table (make-hash-table (length ways))))
;; Store each combination as a key in a hash table to remove duplicates
(for-each (lambda (way) (hash-set! table (sort-list way <) #t)) ways)
(hash-map->list (lambda (k v) k) table)))
Examples:
scheme#(guile-user)> (load "coins.scm")
scheme#(guile-user)> (get-coins '(2) 6)
$1 = 3
scheme#(guile-user)> (get-coins2 '(2) 6)
$2 = ((2 2 2))
scheme#(guile-user)> (get-coins '(2 3) 6)
$3 = 2
scheme#(guile-user)> (get-coins2 '(2 3) 6)
$4 = ((2 2 2) (3 3))
scheme#(guile-user)> (get-coins '(9) 6)
$5 = -1
scheme#(guile-user)> (get-coins2 '(9) 6)
$6 = ()
scheme#(guile-user)> (get-coins2 '(2 3) 12)
$7 = ((3 3 3 3) (2 2 2 3 3) (2 2 2 2 2 2))
scheme#(guile-user)> (get-coins '(5 2 3 4) 21)
$8 = 5
scheme#(guile-user)> (get-coins2 '(5 2 3 4) 21)
$9 = ((2 2 2 5 5 5) (2 3 3 4 4 5) (2 4 5 5 5) (3 3 3 4 4 4) (2 2 3 4 5 5) (4 4 4 4 5) (2 2 4 4 4 5) (2 2 3 3 3 4 4) (2 2 2 2 2 3 4 4) (2 2 2 2 4 4 5) (3 3 3 3 4 5) (2 2 2 2 3 3 3 4) (2 2 2 2 2 2 2 3 4) (2 2 2 2 2 2 4 5) (3 3 3 3 3 3 3) (2 2 3 3 3 3 5) (2 2 2 2 2 2 3 3 3) (2 2 2 2 2 3 3 5) (3 3 5 5 5) (2 2 2 2 2 2 2 2 2 3) (2 2 2 2 3 5 5) (2 2 2 2 2 2 2 2 5) (2 3 4 4 4 4) (2 2 2 3 4 4 4) (2 3 3 3 3 3 4) (2 2 2 3 3 4 5) (2 2 2 3 3 3 3 3) (2 3 3 3 5 5) (3 4 4 5 5))
scheme#(guile-user)> (filter (lambda (way) (= (length way) 5)) (get-coins2 '(5 2 3 4) 21))
$10 = ((2 4 5 5 5) (4 4 4 4 5) (3 3 5 5 5) (3 4 4 5 5))
There are many ways to do it, here is a brute-force solution. It is not elegant but it is simple.
(define mk/pairs
(lambda (sum coin/list)
((lambda (s) (s s
(map (lambda (x) (iota (+ 1 (quotient sum x)))) coin/list)
(lambda (s) s) ))
(lambda (s l* ret)
(if (null? l*)
(ret '(()))
(s s (cdr l*)
(lambda (r)
(ret (apply
append
(map (lambda (x) (map (lambda (y) (cons y x)) (car l*)))
r))))))))))
(define cost
(lambda (s pair coin/list)
(let ((sum (apply + (map * pair coin/list))))
(and (= s sum) pair))))
(define solve
(lambda (sum coin/list)
(let ((pairs (mk/pairs sum coin/list)))
(let ((solutions
(sort (filter (lambda (x) x)
(map (lambda (p) (cost sum p coin/list)) pairs))
(lambda (p1 p2)
(< (apply + p1)
(apply + p2))))))
(if (null? solutions)
"fail"
(car solutions))))))
A test looks like so:
% mit-scheme < coins.scm
MIT/GNU Scheme running under GNU/Linux
1 ]=> (solve 8 '(2 3 1))
;Value: (1 2 0)
1 ]=> (solve 6 '(2 3))
;Value: (0 2)
meaning that you have 1 coin of 2 and 2 coins of 3 in the first example and 2 coins of 3 in the second example.
I have used standard R6RS, so you should be able to convert it directly from mit/scheme to guile.
Related
Example of what function should do:
(list 3 4 6 9 7) ←→ 3x^4 + 4x^3 + 6x^2 + 9x + 7
What I have so far:
(define (poly-eval x numlist)
(compute-poly-tail x numlist 0 0))
(define (compute-poly-tail xn list n acc)
(cond
[(null? list) acc]
[else (compute-poly-tail (first list) (rest list)
(+ acc (* (first list) (expt xn n))) (+ n 1))]))
(check-expect(poly-eval 5 (list 1 0 -1)) 24)
(check-expect(poly-eval 0 (list 3 4 6 9 7)) 7)
(check-expect(poly-eval 2 (list 1 1 0 1 1 0)) 54)
Expected results:
(check-expect(poly-eval 5(list 1 0 -1)) 24)
(check-expect(poly-eval 0 (list 3 4 6 9 7))7)
(check-expect(poly-eval 2 (list 1 1 0 1 1 0)) 54)
I am getting a run-time error. Can someone spot what I am doing wrong. I don't know why I am getting these results.
There are a couple of errors in the code:
You need to process the coefficient's list in the correct order, corresponding to their position in the polynomial! you can either:
reverse the list from the beginning and process the coefficients from right to left (simpler).
Or start n in (sub1 (length numlist)) and decrease it at each iteration (that's what I did).
The order and value of the arguments when calling the recursion in compute-poly-tail is incorrect, check the procedure definition, make sure that you pass along the values in the same order as you defined them, also the first call to (first list) doesn't make any sense.
You should not name list a parameter, this will clash with the built-in procedure of the same name. I renamed it to lst.
This should fix the issues:
(define (poly-eval x numlist)
(compute-poly-tail x numlist (sub1 (length numlist)) 0))
(define (compute-poly-tail xn lst n acc)
(cond
[(null? lst) acc]
[else (compute-poly-tail xn
(rest lst)
(- n 1)
(+ acc (* (first lst) (expt xn n))))]))
It works as expected:
(poly-eval 5 (list 1 0 -1))
=> 24
(poly-eval 0 (list 3 4 6 9 7))
=> 7
(poly-eval 2 (list 1 1 0 1 1 0))
=> 54
Build power coefficient and unknown list than use map function.
; 2*3^1+4*3^0
; input is 3 and '(2 4)
; we need '(3 3) '(2 4) '(1 0)
; use map expt build '(3^1 3^0)
; use map * build '(2*3^1 4*3^0)
; use foldr + 0 sum up
(define (poly-eval x coefficient-ls)
(local ((define power-ls (reverse (build-list (length coefficient-ls) values)))
(define unknown-ls (build-list (length coefficient-ls) (λ (i) x))))
(foldr + 0 (map * coefficient-ls (map expt unknown-ls power-ls)))))
I am writing a scheme program in dr racket that takes a list of numbers representing a matrix sets an item in the list to the number given. So far it works for case row 1 column 1 and knows where to place the number but any other case it makes lists of lists. I have attempted to make a function to help but still receive the same error. Any help would be greatly appreciated.
The error I'm getting:
(setCell Matrix 2 2 9)
((2 4 6 8) (1 (9 5 7)) (2 9 0 1))
I need
(setCell Matrix 2 2 9)
((2 4 6 8) (1 9 5 7) (2 9 0 1))
Any help would be greatly appreciated.
(define Matrix '(( 2 4 6 8 )( 1 3 5 7)( 2 9 0 1)))
;getCell Matrix Row Column
;if i want row 2 col 2
(define (getCell Matrix Row Column)
(if (= Row 1)
(if (= Column 1)
(car (car Matrix))
(getCell (cons (cdr (car Matrix)) ()) Row (- Column 1))
)
(getCell (cdr Matrix) (- Row 1) Column)
)
)
;> (getCell Matrix 1 1)
;2
;(define Matrix '(( 2 4 6 8 )( 1 3 5 7)( 2 9 0 1)))
;setCell Matrix Row Column Item
(define (setCell Matrix Row Column Item)
(if (= Row 1)
(if (= Column 1)
(helpMe Matrix Item)
(cons
(cons (car (car Matrix))
(setCell (cons (cdr (car Matrix)) ()) Row (- Column 1) Item))
(cdr Matrix))
)
(cons (car Matrix) (setCell (cdr Matrix) (- Row 1) Column Item))
)
)
(define (helpMe Matrix Item)
(cons (cons Item (cdr (car Matrix))) (cdr Matrix)))
;ERROR:
;>(setCell Matrix 2 2 9)
;((2 4 6 8) (1 (9 5 7)) (2 9 0 1))
;> (setCell Matrix 1 1 9)
;((9 4 6 8) (1 3 5 7) (2 9 0 1))
This is a common problem.
The basic idea is coordinate, data structure shape, make a good abstraction, visting all element, given coordinate get corresponding value.
In here we define upper left element is (1,1) (so we have to minus 1)
First we want build a same matrix. Second each value determine by function f. And f input is coordinate (i,j) so f is a function call upgrade function. You can set any rule. Like a common question is ask you build diagonal matrix the rule will be i=j. (It a beautiful abstraction)
It's means we must make this coordinate
(0,0) (0,1) (0,2) ... (0,(length (first m))
(1,0) (1,1) (1,2) ... (1,(length (first m))
(2,0 ...
...
(length of matrix),0) ... ((length of matrix),(length (first m)))
Then we send coordinate to f. So we can let f return original value in input matrix but when i = row and j = column we return new value (item). The same idea you can build vector or orthers not just list. The same idea can use to build triangle circle or something else not just rectangle.
#lang racket
(define (setCell m row column item)
(local ((define index-i (- row 1))
(define index-j (- column 1))
(define (f i j)
(if (and (= i index-i) (= j index-j))
item
(list-ref (list-ref m i) j))))
(build-list (length m) (lambda (i) (build-list (length (first m)) (lambda (j) (f i j)))))))
;;; TEST
(define k
'((1 2 3)
(1 2 3)
(1 2 3)))
(setCell k 1 1 100)
(setCell k 2 3 100)
(define k2
'((1 2 3)
(1 2 3)))
(setCell k2 1 3 100)
(setCell k2 2 3 100)
I am writing a scheme program in dr racket that takes a list of numbers representing a matrix sets an item in the list to the number given.
#lang racket
(define matrix-id (build-list 4 (λ (x) (build-list 4 (λ (y) (if (= x y) 1 2))))))
;; => '((1 0 0 0) (0 1 0 0) (0 0 1 0) (0 0 0 1))
;; [X] Number Number X [List-of [Lis-of X]] -> [List-of [Lis-of X]]
(define (set-mat row col item mat)
(for/list ([l mat] [i (length mat)])
(for/list ([e l] [j (length l)])
(if (and (= i row) (= j col))
item
e))))
(set-mat 1 1 'fef matrix-id)
;; => '((1 0 0 0) (0 fef 0 0) (0 0 1 0) (0 0 0 1))
I am trying to learn Scheme, and I encounter a problem.
I am able to make a recursive function to create a list like (5,4,3,2,1). But I don't know how to create a function
(let's say (define (make_list n)) )
that has ascending order of elements likes (1,2,3,4,5....n).
Someone some hint?
(define (make_list n)
(if (= n 1)
(list 1)
(append (list n) (make_list (- n 1)))))
So this is how I make a list with n element, and it returns
> (make_list 3)
'(3 2 1)
> (make_list 5)
'(5 4 3 2 1)
What I need is to return something like:
> (make_list 3)
'(1 2 3)
> (make_list 5)
'(1 2 3 4 5)
You can make a list of ascending elements with the range function:
> (range 1 20)
'(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19)
If you want to iterate over this list consider using in-range instead, which will generate the list items as needed, e.g.:
> (in-range 1 20)
#<stream>
> (for ([i (in-range 1 20)])
(displayln (* i 10)))
10
20
30
...
However usually the likes of map, filter and fold are better ways to handle iteration.
Read the documentation here:
https://docs.racket-lang.org/reference/pairs.html#%28def._%28%28lib._racket%2Flist..rkt%29._range%29%29
You should avoid using append where it is not necessary.
Append adds elements to the back of your list, for which it first needs to traverse the entire list to find the end. Cons does not need to do this, it can just add elements to the front immediately.
Both an ascending list and a descending one can be created using just cons.
(define (desc-list n)
(if (= n 1)
(list 1)
(cons n (desc-list (- n 1)))))
> (desc-list 5)
'(5 4 3 2 1)
(define (asc-list from to)
(if (> from to)
'()
(cons from (asc-list (+ from 1) to))))
> (asc-list 1 5)
'(1 2 3 4 5)
Though you could use append if you really want too.
All you have to do to get what you want then is reverse the parameters you pass to append.
(define (make_list n)
(if (= n 1)
(list 1)
(append (make_list (- n 1)) (list n))))
> (make_list 5)
'(1 2 3 4 5)
So you were very close.
Based on your current definition you have
(make-list 5) = (append (list 5) (make-list 4))
= { 5 } + { 4 ..... 1 }
but you want
(make-list 5) = { 1 ..... 4 } + { 5 }
= (append ... ...)
so to change the order of the result you just need to change the order in which you are creating the result.
Don't make a list one element a time with append. append appends two lists linear time so if you do that for each element in an argument you might make it quadratic time.
Lists are cons-ed from end to beginning. If you want to make a list 0..n you need to count downwards from n while you are accumulating, like this:
(define (make-list n)
(define (helper n acc)
(if (< n 0)
acc
(helper (- n 1) (cons n acc))))
(helper n '()))
Sometimes you cannot do that and then you usually would first make the list in reverse, then reverse it. that is two linear time operations making the end result linear too:
(define (sum lst1 lst2)
(let helper ((lst1 lst1) (lst2 lst2) (acc '()))
(if (null? lst1)
(reverse acc)
(helper (cdr lst1)
(cdr lst2)
(cons (+ (car lst1) (car lst2)) acc)))))
Just adding to this thread that srfi-1 contains the iota function
; (iota numElems [start] [step])
> (iota 10)
(0 1 2 3 4 5 6 7 8 9)
> (iota 10 0 2)
(0 2 4 6 8 10 12 14 16 18)
> (iota 10 10 1)
(10 11 12 13 14 15 16 17 18 19)
Think about using a sub-procedure. You could use your code as the sub-procedure and just reverse the result in the main procedure:
(define (make-list n)
(define (sub n)
(if (= n 1)
(list 1)
(append (list n) (sub (- n 1)))))
(reverse (sub n)))
Alternatively, and more efficiently, you can use an accumulator (called res in this example); it uses cons rather than append, and doesn't need an extra reverse step:
(define (make-list n)
(define (sub n res)
(if (< n 1)
res
(sub (- n 1) (cons n res))))
(sub n null))
I have a project about the game "Oware", we are supposed to write the game in the program Dr.Racket.
These are the rules for the game, they explain it pretty well, illustrating with pictures: http://www.awale.info/jugar-a-lawale/les-regles-de-lawale/?lang=en
Im kinda stuck on the first exercise, i have the method, but its not giving the numbers in the right order.
The first function we have to write is called "distribute" which should re-put x grains in the holes, giving the result in a form of a list consisting of the number of grains rest and the new numbers for the holes.
This is whats expected:
(distribute 5 '(2 3 1 5 5 2)) -> (0 (3 4 2 6 6 2))
(distribute 5 '(2 3 1)) -> (2 (3 4 2))
What I wrote:
(define distribue
(lambda (n l)
(if (or (= n 0) (null? l))
(list l n)
(cons (+ (car l) 1) (distribue (- n 1) (cdr l))))))
What it gives:
(distribue 5 '(2 3 1 5 5 2)) -> (3 4 2 6 6 (2) 0)
(distribue 5 '(2 3 1)) -> (3 4 2 () 2)
I was trying to change the list cons append, but never got the expected form of answer
How about
(define (distribue n l)
(define (iterator n p q)
(if (or (= n 0) (null? q))
(list n (append p q))
(iterator (- n 1) (append p (list (+ 1 (car q)))) (cdr q))))
(iterator n '() l))
where
(distribue 5 '(2 3 1 5 5 2))
(distribue 5 '(2 3 1))
returns
'(0 (3 4 2 6 6 2))
'(2 (3 4 2))
as required.
I am trying to write a procedure that takes a a symbol and a list and inserts the symbol at every possible position inside the given list (thus generating a list of lists). I have coded the following definitions, which I must implement:
1
(define (insert-at pos elmt lst)
(if (empty? lst) (list elmt)
(if (= 1 pos)
(cons elmt lst)
(cons (first lst)
(insert-at (- pos 1) elmt (rest lst))))))
2
(define (generate-all-pos start end)
(if (= start end)
(list end)
(cons start (generate-all-pos (+ start 1) end))))
1 takes a position in a list (number), a symbol and the list itself and inserts the symbol at the requested position.
2 takes a start and a target position (numbers) and creates a sorted list with numbers from start to target.
So far I have got this:
(define (insert-everywhere sym los)
(cond
[(empty? los) (list sym)]
[else (cons (insert-at (first (generate-all-pos (first los)
(first (foldl cons empty los)))) sym los) (insert-everywhere sym (rest los)))
]
)
)
Which results in
> (insert-everywhere 'r '(1 2 3))
(list (list 'r 1 2 3) (list 2 'r 3) (list 3 'r) 'r)
so I actually managed to move the 'r' around. I'm kind of puzzled about preserving the preceding members of the list. Maybe I'm missing something very simple but I've stared and poked at the code for quite some time and this is the cleanest result I've had so far. Any help would be appreciated.
Óscar López's answer shows how you can do this in terms of the procedures that you've already defined. I'd like to point out a way to do this that recurses down the input list. It uses an auxiliary function called revappend (I've taken the name from Common Lisp's revappend). revappend takes a list and a tail, and efficiently returns the same thing that (append (reverse list) tail) would.
(define (revappend list tail)
(if (null? list)
tail
(revappend (rest list)
(list* (first list) tail))))
> (revappend '(3 2 1) '(4 5 6))
'(1 2 3 4 5 6)
The reason that we're interested in such a function is that as we recurse down the input list, we can build up a list of the elements we've already seen, but it's in reverse order. That is, as we walk down (1 2 3 4 5), it's easy to have:
rhead tail (revappend rhead (list* item tail))
----------- ----------- -----------------------------------
() (1 2 3 4 5) (r 1 2 3 4 5)
(1) (2 3 4 5) (1 r 2 3 4 5)
(2 1) (3 4 5) (1 2 r 3 4 5)
(3 2 1) (4 5) (1 2 3 r 4 5)
(4 3 2 1) (5) (1 2 3 4 r 5)
(5 4 3 2 1) () (1 2 3 4 5 r)
In each of these cases, (revappend rhead (list* item tail)) returns a list with item inserted in one of the positions. Thus, we can define insert-everywhere in terms of rhead and tail, and revappend, if we build up the results list in reverse order, and reverse it at the end of the loop.
(define (insert-everywhere item list)
(let ie ((tail list)
(rhead '())
(results '()))
(if (null? tail)
(reverse (list* (revappend rhead (list* item tail)) results))
(ie (rest tail)
(list* (first tail) rhead)
(list* (revappend rhead (list* item tail)) results)))))
(insert-everywhere 'r '(1 2 3))
;=> '((r 1 2 3) (1 r 2 3) (1 2 r 3) (1 2 3 r))
What's interesting about this is that the sublists all share the same tail structure. That is, the sublists share the structure as indicated in the following “diagram.”
;=> '((r 1 2 3) (1 r 2 3) (1 2 r 3) (1 2 3 r))
; ----- +++ o
; +++ o
; o
The insert-everywhere procedure is overly complicated, a simple map will do the trick. Try this:
(define (insert-everywhere sym los)
(map (lambda (i)
(insert-at i sym los))
(generate-all-pos 1 (add1 (length los)))))
Also notice that in Racket there exists a procedure called range, so you don't need to implement your own generate-all-pos:
(define (insert-everywhere sym los)
(map (lambda (i)
(insert-at i sym los))
(range 1 (+ 2 (length los)))))
Either way, it works as expected:
(insert-everywhere 'r '(1 2 3))
=> '((r 1 2 3) (1 r 2 3) (1 2 r 3) (1 2 3 r))