What is the non-recursive function of the following recursive function? - recursion

(defun filter-numbers-rec (inlist)
"This function filters out non-numbers from its input list and returns
the result, a list of numbers"
(cond
((not (listp inlist))
(princ "Argument must be a list")
(terpri)
())
((null inlist)
())
((not (numberp (car inlist)))
(filter-numbers-rec (cdr inlist)))
(t
(cons (car inlist)
(filter-numbers-rec (cdr inlist))))))

Well, the description of what the function does is that you want to remove each thing from the the list if it is not a number, so a good candidate here is remove-if-not, which you would use as follows:
(remove-if-not 'numberp '(1 a 2 b 3 c #\x (y 4)))
;=> (1 2 3)
If, for some reason, you want to write this in a way that (might) not use recursion, you could use do:
(do ((list '(1 a 2 b 3 c #\x (y 4)) (rest list))
(result '()))
((endp list) (nreverse result))
(when (numberp (car list))
(push (car list) result)))
;=> (1 2 3)
If you don't like the wordiness of do, you can use loop:
(loop :for x :in '(1 a 2 b 3 c #\x (y 4))
:when (numberp x)
:collect x)
;=> (1 2 3)

Related

Return the longest sequence of consecutive numbers from list in lisp

I am a lisp newbie.
I'm trying to create a function in lisp that receives an unsorted list and the function has to sort de list and return a list with the longest sequence of numbers.
Example: (2 1 8 9 3 11 10 20 12 21)(1 2 3 8 9 10 11 12 20 21) -> return (8 9 10 11 12)
I don't want to use the sort function and I have created 2 functions (With some help) to sort, but now I have no idea how I could find and return the longest sequence of numbers.
I could go through the list but, how I can store the numbers and check if a list of consecutive numbers is longer than another?
This are my functions to sort
(defun sortOne (list)
(let ((ca1 (car list)) (cd1 (cdr list)))
(if (null cd1)
list
(let ((cd (sortOne cd1))) ; cd = sorted tail
(let ((ca2 (car cd)) (cd2 (cdr cd)))
(if (<= ca1 ca2)
(cons ca1 cd)
(cons ca2 (cons ca1 cd2))))))))
(defun sortAll (list)
(if (null list)
nil
(let ((s (sortOne list)))
(cons (car s) (sortAll (cdr s))))))
Hope someone can help me.
¡Thanks!
Tonight I managed to do it, but surely it is not the best solution, I would like to know how to use a lambda function or recursion to do it better.
(defun listilla (lista)
(setq lista (sort lista #'<))
(setq lista1 (list (car lista)))
(setq lista2 '())
(loop for i from 0 to (- (length lista) 2) do
(cond ((= (nth i lista) (- (nth (+ i 1) lista) 1))
(push (nth (+ i 1) lista) (cdr (last lista1))))
(t (push lista1 lista2)
(setq lista1 (list (nth (+ i 1) lista)))
)
)
)
(push lista1 lista2)
(setq masLargo (car lista2))
(loop for i from 1 to (- (length lista2) 2) do
(if (< (length (nth i lista2)) (length (nth (+ i 1) lista2)))
(setq masLargo (nth (+ i 1) lista2))
)
)
masLargo
)
(print (listilla '(23 15 6 5 78 4 77)))
(defun group-consecutives (l &optional (acc '()))
(cond ((null l) (nreverse acc))
((and acc (= 1 (- (car l) (caar acc)))) (consecutives (cdr l) (cons (cons (car l) (car acc)) (cdr acc))))
(t (consecutives (cdr l) (cons (list (car l)) (when acc (cons (nreverse (car acc)) (cdr acc))))))))
(defun longest-consecutive (l)
(car (sort (consecutives (sort l #'<)) #'> :key #'length)))
(longest-consecutive '(2 1 8 9 3 11 10 20 12 21))
;;=> (8 9 10 11 12)
Probably the second function is easier to understand like this:
(defun sort-increasing (l)
(sort l #'<))
(defun sort-groups-by-length (groups)
(sort groups #'> #'length))
(defun longest-consecutive (l)
(car (sort-groups-by-length (group-consecutives (sort-increasing l))))))))

Common Lisp calling a deftype method

I'm not been able to make this working on. I'm defining a predicate using deftype SameType(x y) method, which evaluates whether the elements of list x and list y are of the same type, and in the same position. The problem comes when I try to call the predicate for testing. I receive an error ERROR: SameType is undefined This is my code:
(deftype SameType (x y)
`(cond
((and (null x) (null y) T))
(
(and (numberp (car x)) (numberp (car y)))
(SameType (cdr x) (cdr y) )
)
(
(and (stringp (car x)) (stringp (car y)))
(SameType (cdr x) (cdr y) )
)
(
(and (atom (car x)) (atom (car y)))
(SameType (cdr x) (cdr y) )
)
(T nil)
)
)
And this is how I'm calling it
(SameType '(A B C 1 2 4 A) '('() G 2 5 6 A B))
I already checked on various onine resources, even related questions on this site.
deftype can be used to define a type, not a predicate. For instance, to define the type of the lists with only integers, you could write something like:
(defun intlistp (l)
"predicate to check if l is a list consisting only of integers"
(and (listp l) ; l is a list and
(every #'integerp l))) ; every element of l is an integer
(deftype integer-list ()
"the type of list of integers"
`(satisfies intlistp))
and then you can check if a value satisfies this type:
CL-USER> (typep '(1 2 3) 'integer-list)
T
CL-USER> (typep '(1 2.5 3) 'integer-list)
NIL
If you want to check if two lists have the same type according to your definition, then you could define a regular function:
(defun same-type (l1 l2)
"check if lists l1 and l2 have the same length and corresponding
elements of the same CL type"
(cond ((null l1) ; if l1 is null
(null l2)) ; returns true only if also l2 is null
((and (consp l1) ; if l1 is a cons
(consp l2) ; and l2 is a cons too,
(typep (car l1) (type-of (car l2)))) ; and their cars have the same CL type
(same-type (cdr l1) (cdr l2))))) ; go recursively on their cdrs
CL-USER> (same-type '(1 a 3) '(2 b 4))
T
CL-USER> (same-type '(1 "a" 3) '(2 "b" 3))
T
CL-USER> (same-type '(1 a 3) '(2 b 4.5))
NIL
CL-USER> (same-type '(1 a 3) '(2 b 4 3))
NIL
CL-USER> (same-type '(1 2 (3 4)) '(1 6 (4 5)))
T
CL-USER> (same-type '(1 2 (3 4)) '(1 6 (4 5 6)))
T
Note that, as you can see from the last example, the type is checked only for the first level of the list.

Returning newly created list with 1 element inside function

I'm currently working on building a function that returns a row of Pascal's triangle. My function passes in a list that contains a row in Pascal's triangle and returns the next row depending on which row was passed in.
ex. pass in '(1 2 1) and it should return '(1 3 3 1).
However I cannot seem to get the beginning 1 in the list.
(define build-next
(lambda(thisRow)
(cond
[(null? thisRow) '(1)]
[(null? (cdr thisRow)) (cons 1 (cdr thisRow))]
[else (cons (+ (car thisRow) (car (cdr thisRow))) (build-next(cdr thisRow)))])))
(build-next '(1 2 1))
Running this code will give me the output
'(3 3 1)
without the leading 1
Your functions works if the input row has a zero as first element.
Renaming your original function to build-next-helper and introducing
a new build-next that simply calls your existing function after prefixing a zero works fine:
(define build-next-helper
(lambda (thisRow)
(cond
[(null? thisRow) '(1)]
[(null? (cdr thisRow)) (cons 1 (cdr thisRow))]
[else (cons (+ (car thisRow) (car (cdr thisRow)))
(build-next-helper (cdr thisRow)))])))
(define (build-next thisRow)
(build-next-helper (cons 0 thisRow)))
(build-next '(1 2 1))
You can also use a named let to write build-next as follows:
(define (build-next row)
(let loop ([row row]
[acc 0])
(cond
[(zero? acc)
(cons 1 (loop row (add1 acc)))]
[(null? row) empty]
[(null? (cdr row)) (list 1)]
[else
(cons (+ (car row) (cadr row))
(loop (cdr row) acc))])))
The loop parameter acc is used as an accumulator to add the leading 1 in the next row (ie. first cond case).
For example,
(build-next '()) ;;=> '(1)
(build-next '(1)) ;;=> '(1 1)
(build-next '(1 1)) ;;=> '(1 2 1)
(build-next '(1 2 1)) ;;=> '(1 3 3 1)
(build-next '(1 3 3 1)) ;;=> '(1 4 6 4 1)
(build-next '(1 4 6 4 1)) ;;=> '(1 5 10 10 5 1)
Here is a possible solution:
(define build-next
(lambda(thisRow)
(define helper-build-next
(lambda (lst prev)
(if (null? lst)
(list prev)
(cons (+ prev (car lst)) (helper-build-next (cdr lst) (car lst))))))
(if (null? thisRow)
(list 1)
(cons (car thisRow) (helper-build-next (cdr thisRow) (car thisRow))))))
The recursion is performed through a helper function, that gets the rest of the row and the previous element of the row. Initially the function checks if the parameter is the empty list, so that the first row of the triangle is returned. Otherwise, the helper function is called with the initial parameters.

How can i remove parentheses in scheme?

i have a function in scheme, this function calls another function many times, and every time this function appends return value of another function to result value.
but finally i want to get a result such that '(a b c), however i get a result such that '((a) (b) (c)) how can i fix this problem? i have searched but i couldn't find good solution.
my little code like that not all of them.
(append res (func x))
(append res (func y))
(append res (func z))
my code like this
(define (check a )
'(1)
)
(define bos '())
(define (func a)
(let loop1([a a] [res '()])
(cond
[(eq? a '()) res]
[else (let ([ x (check (car a))])
(loop1 (cdr a) (append res (list x)))
)]
)
))
Try this:
(define (func a)
(let loop1 ([a a] [res '()])
(cond
[(eq? a '()) res]
[else
(let ([ x (check (car a))])
(loop1 (cdr a) (append res x)))])))
Notice that the only change I made (besides improving the formatting) was substituting (list x) with x. That will do the trick! Alternatively, but less portable - you can use append* instead of append:
(append* res (list x))
As a side comment, you should use (null? a) for testing if the list is empty. Now if we test the procedure using the sample code in the question, we'll get:
(func '(a b c))
=> '(1 1 1)
It seems that instead of
(loop1 (cdr a) (cdr b) c (append res (list x)))
you want
(loop1 (cdr a) (cdr b) c (append res x))
Basically the trick is to use cons instead of list. Imagine (list 1 2 3 4) which is the same as (cons 1 (cons 2 (cons 3 (cons 4 '())))). Do you see how each part is (cons this-iteration-element (recurse-further)) like this:
(define (make-list n)
(if (zero? n)
'()
(cons n (make-list (sub1 n)))))
(make-list 10) ; ==> (10 9 8 7 6 5 4 3 2 1)
Usually when you can choose direction you can always make it tail recursive with an accumulator:
(define (make-list n)
(let loop ((x 1) (acc '()))
(if (> x n)
acc
(loop (add1 x) (cons x acc))))) ; build up in reverse!
(make-list 10) ; ==> (10 9 8 7 6 5 4 3 2 1)
Now this is a generic answer. Applied to your working code:
(define (func a)
(let loop1 ([a a] [res '()])
(cond
[(eq? a '()) (reverse res)]
[else
(let ([x (check (car a))])
(loop1 (cdr a) (cons (car x) res)))])))
(func '(a b c)) ; ==> (1 1 1)
append replaces the cons so why not put the car og your result to the rest of the list. Since you want the result in order I reverse the result in the base case. (can't really tell from the result, but I guessed since you ise append)

Recursively splitting a list into two using LISP

Using LISP, i need to create a function that splits a list into two lists. The first list consists of 1st, 3rd, 5th, 7th, etc elements and the second list consists of 2nd, 4th, 6th, etc elements.
Output Examples:
(SPLIT-LIST ( )) => (NIL NIL)
(SPLIT-LIST '(A B C D 1 2 3 4 5)) => ((A C 1 3 5) (B D 2 4))
(SPLIT-LIST '(B C D 1 2 3 4 5)) => ((B D 2 4) (C 1 3 5))
(SPLIT-LIST '(A)) => ((A) NIL)
The function need to be recursive.
This is my code so far.
(defun SPLIT-LIST (L)
(cond
((null L) NIL)
((= 1 (length L)) (list (car L)))
(t (cons (cons (car L) (SPLIT-LIST (cddr L))) (cadr L)))))
);cond
);defun
i'm going to try to use flatten later on so that i end up w/ two lists, but for now, i just can't seem to get the sequence correctly.
MY CODE:
> (SPLIT-LIST '(1 2 3 4))
((1 (3) . 4) . 2)
I just can't seem to make the code print 1 3 2 4 instead of 1 3 4 2.
> (SPLIT-LIST '(1 2 3 4 5 6))
((1 (3 (5) . 6) . 4) . 2)
I can't make the second half of the expected output to print in the correct sequence.
Your code
We typically read Lisp code by indentation, and don't write in all-caps. Since we read by indentation, we don't need to put closing parens (or any parens, really) on their own line. Your code, properly formatted, then, is:
(defun split-list (l)
(cond
((null l) '())
((= 1 (length l)) (list (car l)))
(t (cons (cons (car l)
(split-list (cddr l)))
(cadr l)))))
Getting the base cases right
Split-list is always supposed to return a list of two lists. We should cover those base cases first. When l is empty, then there's nothing in the left list or the right, so we can simply return '(() ()). Then first condition then becomes:
((null l) '(() ())) ; or ((endp l) '(() ()))
Judging by your second case, I gather that you want the second and third cases to be: (i) if there's only one element left, it must be an odd-numbered one, and belongs in the left result; (ii) otherwise, there are at least two elements left, and we can add one to each. Then the second condition should be
((= 1 (length l)) (list (car l) '()))
It's actually kind of expensive to check the length of l at each step. You only care whether there is only one element left. You already know that l isn't empty (from the first case), so you can just check whether the rest oflis the empty list. I find it more readable to usefirstandrest` when working with cons cells as lists, so I'd write the second clause as:
((endp (rest l)) (list (list (first l)) '()))
Handling the recursive case
Now, your final case is where there are at least two elements. That means that l looks like (x y . zs). What you need to do is call split-list on zs to get some result of the form (odd-zs even-zs), and then take it apart and construct ((x . odd-zs) (y . even-zs)). That would look something like this:
(t (let ((split-rest (split-list (rest (rest l)))))
(list (list* (first l) (first split-rest))
(list* (second l) (second split-rest)))))
There are actually some ways you can clean that up. We can use destructuring-bind to pull odd-zs and even-zs out at the same time. Since this is the last clause of the cond, and a clause returns the value of the test if there are no body forms, we don't need the initial t. The last clause can be:
((destructuring-bind (odd-zs even-zs) ; *
(split-list (rest (rest l)))
(list (list* (first l) odd-zs)
(list* (second l) even-zs))))))
*I omitted the t test because if a cond clause has no body forms, then the value of the test is returned. That works just fine here.
Putting that all together, we've reworked your code into
(defun split-list (l)
(cond
((endp l) '(() ()))
((endp (rest l)) (list (list (first l)) '()))
((destructuring-bind (odd-zs even-zs)
(split-list (rest (rest l)))
(list (list* (first l) odd-zs)
(list* (second l) even-zs))))))
CL-USER> (split-list '(a b c 1 2 3))
((A C 2) (B 1 3))
CL-USER> (split-list '(a b c d 1 2 3))
((A C 1 3) (B D 2))
Other approaches
I think it's worth exploring some approaches that are tail recursive, as an implementation that supports tail call optimization can convert them to loops. Tail recursive functions in Common Lisp are also typically easy to translate into do loops, which are much more likely to be implemented as iteration. In these solutions, we'll build up the result lists in reverse, and then reverse them when it's time to return them.
Recursing one element at a time
If the left and right slices are interchangeable
If it doesn't matter which of the two lists is first, you can use something like this:
(defun split-list (list &optional (odds '()) (evens '()))
(if (endp list)
(list (nreverse odds)
(nreverse evens))
(split-list (rest list)
evens
(list* (first list) odds))))
CL-USER> (split-list '(a b c 1 2 3))
((A C 2) (B 1 3))
CL-USER> (split-list '(a b c d 1 2 3))
((B D 2) (A C 1 3))
This can actually be written very concisely using a do loop, but that's typically seen as iterative, not recursive:
(defun split-list (list)
(do ((list list (rest list))
(odds '() evens)
(evens '() (list* (first list) odds)))
((endp list) (list (nreverse odds) (nreverse evens)))))
If they're not interchangable
If you always need the list containing the first element of the original list to be first, you'll need a little bit more logic. One possibility is:
(defun split-list (list &optional (odds '()) (evens '()) (swap nil))
(if (endp list)
(if swap
(list (nreverse evens)
(nreverse odds))
(list (nreverse odds)
(nreverse evens)))
(split-list (rest list)
evens
(list* (first list) odds)
(not swap))))
CL-USER> (split-list '(a b c 1 2 3))
((A C 2) (B 1 3))
CL-USER> (split-list '(a b c d 1 2 3))
((A C 1 3) (B D 2))
I think that (if swap … …) is actually a bit ugly. We can use cond so that we can get multiple forms (or if and progn), and swap the values of odds and evens before returning. I think this is actually a bit easier to read, but if you're aiming for a pure recursive solution (academic assignment?), then you might be avoiding mutation, too, so rotatef wouldn't be available, and using a when just to get some side effects would probably be frowned upon.
(defun split-list (list &optional (odds '()) (evens '()) (swap nil))
(cond
((endp list)
(when swap (rotatef odds evens))
(list (nreverse odds) (nreverse evens)))
((split-list (rest list)
evens
(list* (first list) odds)
(not swap)))))
This lends itself to do as well:
(defun split-list (list)
(do ((list list (rest list))
(odds '() evens)
(evens '() (list* (first list) odds))
(swap nil (not swap)))
((endp list)
(when swap (rotatef odds evens))
(list (nreverse odds) (nreverse evens)))))
Recursing two elements at a time
Another more direct approach would recurse down the list by cddr (i.e., (rest (rest …))) and add elements to the left and right sublists on each recursion. We need to be a little careful that we don't accidentally add an extra nil to the right list when there are an odd number of elements in the input, though.
(defun split-list (list &optional (left '()) (right '()))
(if (endp list)
(list (nreverse left)
(nreverse right))
(split-list (rest (rest list))
(list* (first list) left)
(if (endp (rest list))
right
(list* (second list) right)))))
CL-USER> (split-list '(a b c 1 2 3))
((A C 2) (B 1 3))
CL-USER> (split-list '(a b c d 1 2 3))
((A C 1 3) (B D 2))
And again, a do version:
(defun split-list (list)
(do ((list list (rest (rest list)))
(left '() (list* (first list) left))
(right '() (if (endp (rest list)) right (list* (second list) right))))
((endp list) (list (nreverse left) (nreverse right)))))
Here's what I've got:
(defun split-list (lst)
(if lst
(if (cddr lst)
(let ((l (split-list (cddr lst))))
(list
(cons (car lst) (car l))
(cons (cadr lst) (cadr l))))
`((,(car lst)) ,(cdr lst)))
'(nil nil)))
After reading SICP I'm rarely confused about recursion.
I highly recommend it.
Here's my take, using an inner function:
(defun split-list (lst)
(labels ((sub (lst lst1 lst2 flip)
(if lst
(if flip
(sub (cdr lst) (cons (car lst) lst1) lst2 (not flip))
(sub (cdr lst) lst1 (cons (car lst) lst2) (not flip)))
(list (reverse lst1) (reverse lst2)))))
(sub lst nil nil t)))
As a Common Lisp LOOP:
(defun split-list (list)
"splits a list into ((0th, 2nd, ...) (1st, 3rd, ...))"
(loop for l = list then (rest (rest l))
until (null l) ; nothing to split
collect (first l) into l1 ; first split result
unless (null (rest l))
collect (second l) into l2 ; second split result
finally (return (list l1 l2))))
With internal tail-recursive function building the lists in top-down manner (no reverses, loop code probably compiles to something equivalent), with a head-sentinel trick (for simplicity).
(defun split-list (lst &aux (lst1 (list 1)) (lst2 (list 2)))
(labels ((sub (lst p1 p2)
(if lst
(progn (rplacd p1 (list (car lst)))
(sub (cdr lst) p2 (cdr p1)))
(list (cdr lst1) (cdr lst2)))))
(sub lst lst1 lst2)))
Flatten is fun to define in Lisp. But I've never had a use for it.
So if you think "I could use flatten to solve this problem" it's probably because you're trying to solve the wrong problem.
(defun split-list (L)
(if (endp L)
'(nil nil)
(let ((X (split-list (cdr L))))
(list (cons (car L) (cadr X)) (car X))
)))

Resources