It compiles right but if i try to use the function I get an error:
function call: expected a function after the open parenthesis, but received 1.
(define (euclid a b)
(if (= b 0) a
(if (= a 0) b
(if (> a b) (euclid(- a b) b)
(euclid (a (- b a) ))))))
There's a misplaced bracket in the last line. This should fix it:
(define (euclid a b)
(if (= b 0)
a
(if (= a 0)
b
(if (> a b)
(euclid (- a b) b)
(euclid a (- b a))))))
When you have several nested conditions, it's better to use cond, like this:
(define (euclid a b)
(cond ((= b 0) a)
((= a 0) b)
((> a b) (euclid (- a b) b))
(else (euclid a (- b a)))))
Related
I'm trying to create a LISP function that creates from a list all possible pairs.
Example of what I'm trying to achieve: (a b c d) --> ((a b) (a c) (a d) (b c) (b d) (c d))
Any advice please? I'm not sure how to approach this problem
Here is a simple solution:
(defun make-couples (x l)
"makes a list of couples whose first element is x and the second is each element of l in turn"
(loop for y in l collect (list x y)))
(defun all-pairs (l)
"makes a list of all the possible pairs of elements of list l"
(loop for (x . y) on l nconc (make-couples x y)))
A recursive solution is:
(defun make-couples (x l)
"makes a list of couples whose first element is x and the second is each element of l in turn"
(if (null l)
nil
(cons (cons x (first l)) (make-couples x (rest l)))))
(defun all-pairs (l)
"makes a list of all the possible pairs of elements of list l"
(if (null l)
nil
(nconc (make-couples (first l) (rest l))
(all-pairs (rest l)))))
Here is a version (this is quite closely related to Gwang-Jin Kim's) which has two nice properties:
it is tail recursive;
it walks no list more than once;
it allocates no storage that it does not use (so there are no calls to append and so on);
it uses no destructive operations.
It does this by noticing that there's a stage in the process where you want to say 'prepend a list of pairs of this element with the elements of this list to this other list' and that this can be done without using append or anything like that.
It does return the results in 'reversed' order, which I believe is inevitable given the above constraints.
(defun all-pairs (l)
(all-pairs-loop l '()))
(defun all-pairs-loop (l results)
(if (null (rest l))
results
(all-pairs-loop (rest l)
(prepend-pairs-to (first l) (rest l) results))))
(defun prepend-pairs-to (e them results)
(if (null them)
results
(prepend-pairs-to e (rest them) (cons (list e (first them))
results))))
the simplest tail recursive variant without explicit loops / mapcar could also look like this:
(defun pairs (data)
(labels ((rec (ls a bs res)
(cond
((null ls) (nreverse res))
((null bs) (rec
(cdr ls)
(car ls)
(cdr ls)
res))
(t (rec
ls
a
(cdr bs)
(cons (cons a (car bs)) res))))))
(rec data nil nil nil)))
CL-USER> (pairs (list 1 2 3 4))
;; ((1 . 2) (1 . 3) (1 . 4) (2 . 3) (2 . 4) (3 . 4))
Tail call recursive solution:
(defun pairs (lst &key (acc '()))
(if (null (cdr lst))
(nreverse acc)
(pairs (cdr lst)
:acc (append (nreverse
(mapcar #'(lambda (el)
(list (car lst) el))
(cdr lst)))
acc))))
Both nreverses are there just for aesthetics (for a nicer looking output). They can be left out.
Try it with:
(pairs '(a b c d))
;; => ((A B) (A C) (A D) (B C) (B D) (C D))
General Combinations
(defun pair (el lst)
"Pair el with each element of lst."
(mapcar (lambda (x) (cons el x)) lst))
(defun dedup (lst &key (test #'eql))
"Deduplicate a list of lists by ignoring order
and comparing the elements by test function."
(remove-duplicates lst :test (lambda (x y) (null (set-difference x y :test test)))))
(defun comb (lst &key (k 3) (acc '()) (test #'eql))
"Return all unique k-mer combinations of the elements in lst."
(labels ((%comb (lst &key (k k) (acc '()) (test #'eql) (total lst))
(let ((total (if total total lst)))
(cond ((or (null (cdr lst)) (zerop k)) (nreverse acc))
((= k 1) (mapcar #'list lst))
(t (let* ((el (car lst))
(rst (remove-if (lambda (x) (funcall test x el)) total)))
(dedup (%comb (cdr lst)
:k k
:total total
:test test
:acc (append (pair el (comb rst :k (1- k) :test test))
acc)))))))))
(%comb lst :k k :acc acc :test test :total lst)))
The number of combinations are calculatable with the combinations formula:
(defun fac (n &key (acc 1) (stop 1))
"n!/stop!"
(if (or (= n stop) (zerop n))
acc
(fac (1- n) :acc (* acc n) :stop stop)))
(defun cnr (n r)
"Number of all r-mer combinations given n elements.
nCr with n and r given"
(/ (fac n :stop r) (fac (- n r))))
We can test and count:
(comb '(a b c d) :k 2)
;; => ((A D) (B D) (B A) (C D) (C B) (C A))
(comb '(a b c d e f) :k 3)
;; => ((B A F) (C B A) (C B F) (C A F) (D C A) (D C B)
;; => (D C F) (D B A) (D B F) (D A F) (E D A) (E D B)
;; => (E D C) (E D F) (E C A) (E C B) (E C F) (E B A)
;; => (E B F) (E A F))
(= (length (comb '(a b c d e f) :k 3)) (cnr 6 3)) ;; => T
(= (length (comb '(a b c d e f g h i) :k 6)) (cnr 9 6)) ;; => T
(define ( addposition x )
(cond
[(empty? x) "empty list"]
[#t (for/list ([i x])
(list i (add1 (index-of x i))))]
))
(addposition (list 'a 'b 'c ))
it returns me '((a 1) (b 2) (c 3)), but I need the list like '(a 1 b 2 c 3)
As a bare minimum to get what you want you can throw that nested list to a (flatten) call:
> (flatten '((a 1) (b 2) (c 3)))
'(a 1 b 2 c 3)
But overall the idea to build mini lists with index-of and then flattening it is not the most performant. Nor will it be correct if your list contains duplicate values.
If we keep our own record of the next index, and using recursion instead of the otherwise handy for/list structure, we can build our list this way:
(define (add-positions xs [ind 0])
(if (null? xs)
xs
(append (list (first xs) ind)
(add-positions (rest xs) (add1 ind))
)))
(add-positions '(a b c d))
;=> '(a 0 b 1 c 2 d 3)
This can be expressed pretty naturally using map and flatten:
;;; Using map and flatten:
(define (list-pos xs (start 0))
(flatten (map (lambda (x y) (list x y))
xs
(range start (+ start (length xs))))))
Here map creates a list of lists, each containing one value from the input list and one value from a range list starting from start, and flatten flattens the result.
This seems more natural to me than the equivalent using for/list, but tastes may differ:
;;; Using for/list:
(define (list-pos xs (start 0))
(flatten (for/list ((x xs)
(p (range start (+ start (length xs)))))
(list x p))))
There are a lot of ways that you could write this, but I would avoid using append in loops. This is an expensive function, and calling append repeatedly in a loop is just creating unnecessary overhead. You could do this:
;;; Using Racket default arguments and add1:
(define (list-pos xs (pos 0))
(if (null? xs)
xs
(cons (car xs)
(cons pos (list-pos (cdr xs) (add1 pos))))))
Here the first element of the list and a position counter are added onto the front of the result with every recursive call. This isn't tail recursive, so you might want to add an accumulator:
;;; Tail-recursive version using inner define:
(define (list-pos xs (start 0))
(define (loop xs pos acc)
(if (null? xs)
(reverse acc)
(loop (cdr xs)
(add1 pos)
(cons pos
(cons (car xs) acc)))))
(loop xs start '()))
Because the intermediate results are collected in an accumulator, reverse is needed to get the final result in the right order.
You could (and I would) replace the inner define with a named let. Named let should work in Racket or Scheme; here is a Scheme version. Note that Scheme does not have default arguments, so an optional argument is used for start:
;;; Tail-recursive Scheme version using named let:
(define (list-pos xs . start)
(let loop ((xs xs)
(pos (if (null? start) 0 (car start)))
(acc '()))
(if (null? xs)
(reverse acc)
(loop (cdr xs)
(add1 pos)
(cons pos
(cons (car xs) acc))))))
All of the above versions have the same behavior:
list-pos.rkt> (list-pos '(a b c))
'(a 0 b 1 c 2)
list-pos.rkt> (list-pos '(a b c) 1)
'(a 1 b 2 c 3)
Here is a simple solution using for/fold
(define (addposition l)
(for/fold ([accum empty]) ([elem l])
(append accum elem)))
I love the for loops in Racket 😌
Note: As pointed out by ad absurdum, append is expensive here. So we can simply reverse first and then use cons to accumulate
(define (addposition l)
(for/fold ([accum empty]) ([elem (reverse l)])
(cons (first elem) (cons (second elem) accum))))
As others have pointed out, you can start by making a list of lists. Let's use a list comprehension:
> (for/list ([x '(a b c)]
[pos (in-naturals 1)])
(list x pos))
'((a 1) (b 2) (c 3))
Here, we iterate in parallel over two sets of data:
The list '(a b c)
The stream (in-naturals 1), which produces 1, 2, 3, ....
We combine them into lists with list, giving this structure:
'((a 1) (b 2) (c 3))
This is called "zipping", and using list comprehensions is a convenient way to do it in Racket.
Next, we want to flatten our list, so it ends up looking like this:
'(a 1 b 2 c 3)
However, you shouldn't use flatten for this, as it flattens not just the outermost list, but any sub-lists as well. Imagine if we had data like this, with a nested list in the middle:
> (flatten
(for/list ([x '(a (b c d) e)]
[pos (in-naturals 1)])
(list x pos)))
'(a 1 b c d 2 e 3)
The nested list structure got clobbered! We don't want that. Unless we have a good reason, we should preserve the internal structure of each element in the list we're given. We'll do this by using append* instead, which flattens only the outermost list:
> (append*
(for/list ([x '(a (b c d) e)]
[pos (in-naturals 1)])
(list x pos)))
'(a 1 (b c d) 2 e 3)
Now that we've got it working, let's put it into a function:
> (define (addposition xs)
(append*
(for/list ([x xs]
[pos (in-naturals 1)])
(list x pos))))
> (addposition '(a b c))
'(a 1 b 2 c 3)
> (addposition '(a (b c d) e))
'(a 1 (b c d) 2 e 3)
Looks good!
I want to show the result of my function as a list not as a number.
My result is:
(define lst (list ))
(define (num->base n b)
(if (zero? n)
(append lst (list 0))
(append lst (list (+ (* 10 (num->base (quotient n b) b)) (modulo n b))))))
The next error appears:
expected: number?
given: '(0)
argument position: 2nd
other arguments...:
10
I think you have to rethink this problem. Appending results to a global variable is definitely not the way to go, let's try a different approach via tail recursion:
(define (num->base n b)
(let loop ((n n) (acc '()))
(if (< n b)
(cons n acc)
(loop (quotient n b)
(cons (modulo n b) acc)))))
It works as expected:
(num->base 12345 10)
=> '(1 2 3 4 5)
(define (sum-two-sqrt a b c)
(cond ((and (<= c a) (<= c b)) sqrt-sum(a b))
((and (<= a b) (<= a c)) sqrt-sum(b c))
((and (<= b a) (<= b c)) sqrt-sum(a c))
)
)
(define (sqrt-sum x y)
(+ (* x x) (*y y))
)
(define (<= x y)
(not (> x y))
(sum-two-sqrt 3 4 5)
This is my code
Please help me to fix the problem. :)
I just start studing Lisp today.
learned some C before but the two language is QUITE DIFFERENT!
This is the question
Define a procedure that takes three numbers as arguments and returns the sum of the squares of the two larger numbers.
If you have better algorithm
POST IT!
Thank you :)
There's no need to define <=, it's a primitive operation. After fixing a couple of typos:
sqrt-sum: you were incorrectly invoking the procedure; the opening parenthesis must be written before the procedure name, not after.
sqrt-sum: (*y y) is incorrect, you surely meant (* y y); the space(s) after an operator matter.
This should work:
(define (sqrt-sum x y)
(+ (* x x) (* y y)))
(define (sum-two-sqrt a b c)
(cond ((and (<= c a) (<= c b)) (sqrt-sum a b))
((and (<= a b) (<= a c)) (sqrt-sum b c))
((and (<= b a) (<= b c)) (sqrt-sum a c))))
Or another alternative:
(define (sum-two-sqrt a b c)
(let ((m (min a b c)))
(cond ((= a m) (sqrt-sum b c))
((= b m) (sqrt-sum a c))
(else (sqrt-sum a b)))))
Following up on a suggestion by #J.Spiral and seconded by #River, the following Racket code reads nicely to me:
#lang racket
(define (squares-of-larger l)
(define two-larger (remove (apply min l) l))
(for/sum ([i two-larger]) (* i i)))
(squares-of-larger '(3 1 4)) ;; should be 25
Please note that this solution is entirely functional, since "remove" just returns a new list.
Also note that this isn't even in the same neighborhood with HtDP; I just wanted to express this concisely, and show off for/sum.
I didn't have Scheme interpreter here, but below seems to be shorter then other suggestions :) So it's in CL, but should look very similar in Scheme.
(defun sum-two-sqrt (a b c)
(let ((a (max a b))
(b (max (min a b) c)))
(+ (* a a) (* b b))))
In Scheme this would translate to:
(define (sum-two-sqrt a b c)
(let ((a (max a b))
(b (max (min a b) c)))
(+ (* a a) (* b b))))
the algorithm seems to work, just turn
*y
to
* y
whitespace is important here, else you're telling the interpreter you want to usethe function *y
add a close paren after
(define (<= x y) (not (> x y))
sqrt-sum(a b)
turns to
(sqrt-sum a b)
and ditto for the other sqrt-sum calls
edit: also a possibility:
(define (square a) (* a a))
(define (square-sum a b c)
(- (+ (square a)
(square b)
(square c))
(square (min a b c))))
Given a list, how would I select a new list, containing a slice of the original list (Given offset and number of elements) ?
EDIT:
Good suggestions so far. Isn't there something specified in one of the SRFI's? This appears to be a very fundamental thing, so I'm surprised that I need to implement it in user-land.
Strangely, slice is not provided with SRFI-1 but you can make it shorter by using SRFI-1's take and drop:
(define (slice l offset n)
(take (drop l offset) n))
I thought that one of the extensions I've used with Scheme, like the PLT Scheme library or Swindle, would have this built-in, but it doesn't seem to be the case. It's not even defined in the new R6RS libraries.
The following code will do what you want:
(define get-n-items
(lambda (lst num)
(if (> num 0)
(cons (car lst) (get-n-items (cdr lst) (- num 1)))
'()))) ;'
(define slice
(lambda (lst start count)
(if (> start 1)
(slice (cdr lst) (- start 1) count)
(get-n-items lst count))))
Example:
> (define l '(2 3 4 5 6 7 8 9)) ;'
()
> l
(2 3 4 5 6 7 8 9)
> (slice l 2 4)
(3 4 5 6)
>
You can try this function:
subseq sequence start &optional end
The start parameter is your offset. The end parameter can be easily turned into the number of elements to grab by simply adding start + number-of-elements.
A small bonus is that subseq works on all sequences, this includes not only lists but also string and vectors.
Edit: It seems that not all lisp implementations have subseq, though it will do the job just fine if you have it.
(define (sublist list start number)
(cond ((> start 0) (sublist (cdr list) (- start 1) number))
((> number 0) (cons (car list)
(sublist (cdr list) 0 (- number 1))))
(else '())))
Try something like this:
(define (slice l offset length)
(if (null? l)
l
(if (> offset 0)
(slice (cdr l) (- offset 1) length)
(if (> length 0)
(cons (car l) (slice (cdr l) 0 (- length 1)))
'()))))
Here's my implementation of slice that uses a proper tail call
(define (slice a b xs (ys null))
(cond ((> a 0) (slice (- a 1) b (cdr xs) ys))
((> b 0) (slice a (- b 1) (cdr xs) (cons (car xs) ys)))
(else (reverse ys))))
(slice 0 3 '(A B C D E F G)) ;=> '(A B C)
(slice 2 4 '(A B C D E F G)) ;=> '(C D E F)