Function calling in scheme - function

I have my two functions here in my scheme code and I want to display the output check_even and count_even at once after inputting the user given list. Can anyone help me to make it possible? I'm very new to scheme and I really need your help.
Here's my code:
(define (check_even lst) #function for checking even
(cond ((null? lst) '())
((even? (car lst)) (cons (car lst) (check_even (cdr lst))))
(else (check_even (cdr lst)))))
(define (count_even list) #function for counting even
(if (null? list)
0
( + (if (even? (car list )) 1 0)
(count_even (cdr list)))))

How about using values? it'll allow you to return multiple values, like this:
(define (results lst)
(values (count_even lst)
(check_even lst)))
For example:
(results '(1 2 3 4 5 6 7 8 9 10))
=> 5
'(2 4 6 8 10)

Related

Function to count number of 0 in given arguments in lisp

I want to create a function in LISP
to count the number of 0 in given arguments
Ex
(count_number_of_0 '(1 0 5 9 0 0 0 7 1 0) )
Output : 5
Here is an implementation in Racket, which is a lisp-family language. It would be quite easy to translate into Common Lisp (but a little more verbose in CL):
(define make-counter
(λ (v same?)
(λ (l)
((λ (c)
(c c 0 l))
(λ (c a t)
(if (null? t)
a
(c c (if (same? (first t) v) (+ a 1) a) (rest t))))))))
(define count-zeros
(make-counter 0 =))
And now
> (count-zeros '(1 2 0 3 4 0))
2
one way is:
(defun count-number-of-0 (lst &optional (cnt 0)) ;counter starts at zero
(if lst
(if (and (numberp (car lst)) ;better verify that element is a number
(= 0 (car lst)))
(progn
(setq cnt (+ cnt 1))
(count-number-of-0 (cdr lst) cnt))
(count-number-of-0 (cdr lst) cnt))
cnt)) ;return counter
This should work in all implementations of common-lisp.

Remove multiple characters from a list if they are next to each other in Scheme

I have to make a Dr. Racket program that removes letters from a list if they are following the same letter as itself. For example: (z z f a b b d d) would become
(z f a b d). I have written code for this but all it does is remove the first letter from the list.
Can anyone help?
#lang racket
(define (remove-duplicates x)
(cond ((null? x)
'())
((member (car x) (cons(car(cdr x)) '())))
(remove-duplicates (cdr x))
(else
(cons (car x) (remove-duplicates (cdr x))))))
(define x '( b c c d d a a))
(remove-duplicates x)
(define (remove-dups x)
(cond
[(empty? x) '()]
[(empty? (cdr x)) (list (car x))]
[(eq? (car x) (cadr x)) (remove-dups (cdr x))]
[else (cons (car x) (remove-dups (cdr x)))]))
(cadr x) is short for (car (cdr x)) in case you didn't know.
Also, pattern matching makes list deconstruction often much more readable. In this case not so much, but it's still better than the other version:
(define (rmv-dups x)
(match x
[(list) (list)]
[(list a) (list a)]
[(cons a (cons a b)) (rmv-dups (cdr x))]
[__ (cons (car x) (rmv-dups (cdr x)))]))
This problem will be simpler if you introduce a helper function.
I recommend something like this (where angle brackets mean you need to fill out the details):
(define (remove-duplicates x)
(cond
[ <x is empty> '()] ; no duplicates in empty list
[ <x has one element> x] ; no duplicates in a list with one element
[ <first and second element in x is equal> (cons (car x) (remove-from-front (car x) (cdr x)))]
[else (cons (car x) (remove-duplicates (cdr x)))]))
(define (remove-from-front e x)
(cond
[ <x is empty> '()] ; e is not the first element of x
[ <e equals first element of x> (remove-from-front e (cdr x))] ; skip duplicate
[else (remove-duplicates x)])) ; no more es to remove

scheme, search-last funcion whithout several expressions

I must create a function - (search-last x list), i made this:
(define (search-last o lst)
(let loop ((lst lst))
(if (eqv? (caar lst) o)
(cdar lst)
(if (pair? (cdr lst))
(loop (cdr lst))
o))))
but for ex.
(define l '((1 . 2) (2 . 5) (3 . 5) (2 . 1)))
should be 1 but
my output is 5 i know where i made mistake but i dont know how can i improve it.
I cant use expression with "!" and vector, for, while, set, sort, reverse, list-ref, list-tail, append, length.
A tail recursive solution using named let
(define (search-last o lst)
(let loop ((lst lst) (match #f)) ; when not found match is #f
(cond ((null? lst) match) ; return last match at the end
((eqv? (caar lst) o) ; when found
(loop (cdr lst) (cdar lst))) ; we recurse with new match
(else (loop (cdr lst) match))))); or we keep the old match
You could have created your own reverse function and reverse the list in your named let loop. But my understanding is that this is not the point of the exercise.
This will work:
(define (search-last o lst)
(or
(let loop ((lst lst))
(cond
((null? lst) #f)
((eqv? (caar lst) o) (or (loop (cdr lst)) (cdar lst)))
(else (loop (cdr lst)))))
o))
The trick is that if you find a pair with the required first element, the or clause will search the rest of the list. If it returns #f, i.e. if there is no other such pair in the remaining list, then the clause will return (cdar lst). Otherwise it will return the result of the recursive search-last call. The outer or does the same with the final result, i.e. replacing #f with the argument o.
Testing:
> (search-last 1 '((1 . 2) (2 . 5) (3 . 5) (2 . 1)))
2
> (search-last 2 '((1 . 2) (2 . 5) (3 . 5) (2 . 1)))
1
> (search-last 3 '((1 . 2) (2 . 5) (3 . 5) (2 . 1)))
5
> (search-last 4 '((1 . 2) (2 . 5) (3 . 5) (2 . 1)))
4
FWIW, here's a tail-recursive version:
(define (search-last o lst)
(let loop ((lst lst) (res o))
(cond
((null? lst) res)
((eqv? (caar lst) o) (loop (cdr lst) (cdar lst)))
(else (loop (cdr lst) res)))))

Multiplying 2 lists in Lisp

I have a function that takes 2 lists as input and I would like to make it so that everything in the first list, is multiplied with everything in the second list, and then the sum is calculated.
Here's my function so far:
(defun multiply(a b)
(if (eq a nil)
0
(progn
(* (car a) (car b))
(multiply (car a) (cdr b)))
))
Currently all I'm trying to get it to do is take the first number from the first list, and multiply one by with everything in the second list. However I get this error from when the function is re-called within the function:
(This is what I inputted, '(1 2 3) and '(4 5 6))
The value 1 is not of type list.
(MULTIPLY 1 '(5 6))
Any help would be much appreciated.
Is loop acceptable?
Case 1
If the result should be 90 as in
(+ (* 1 4) (* 1 5) (* 1 6) (* 2 4) (* 2 5) (* 2 6) (* 3 4) (* 3 5) (* 3 6))
then you could do
(defun multiply (a b)
(loop for i in a
sum (loop for j in b
sum (* i j))))
Case 2
If the result is supposed to be 32 as in
(+ (* 1 4) (* 2 5) (* 3 6))
then it would be
(defun multiply (a b)
(loop
for i in a
for j in b
sum (* i j)))
If you want to multiply two lists per element, you should just be able to use mapcar:
(mapcar #'* '(3 4 5) '(4 5 6))
As to the error in your existing function, this line should be:
...
(multiply (cdr a) (cdr b)))
...
What you describe sounds like the dot product:
(defun dot (l1 l2)
(reduce #'+ (mapcar #'* l1 l2)))
The above solution is nice because it is purely functional, but, alas, it creates an unnecessary intermediate list. Of course, a Sufficiently Smart Compiler should be able to eliminate that, but, practically speaking, you are better off using loop:
(defun dot (l1 l2)
(loop for x in l1 and y in l2 sum (* x y)))
Note also that using lists to represent mathematical vectors is not a very good idea, use vectors instead.
I would modify multiply as
(defun multiply(a b)
(if (eq a nil)
0
(+
(* (car a) (car b))
(multiply (cdr a) (cdr b)))))
When you call
(multiply '(1 2 3) '(4 5 6))
it will return the sum
32
(define (*2Ls L1 L2)
(apply map * (list L1 L2)))

LISP function to remove nils

I want to write a function in LISP that will completely remove all NILS in a list. The list may be nested, meaning it can contain other lists inside. For example the list '((state L L L L) NIL (state L L R L) NIL) should be tranformed into '((STATE L L L L) (STATE L L R L)).
(defun remove-nil-recursively (x)
(if (listp x)
(mapcar #'remove-nil-recursively
(remove nil x))
x))
Works for your example:
[1]> (remove-nil-recursively '((state L L L L) NIL (state L L R L) NIL))
((STATE L L L L) (STATE L L R L))
And with nested lists:
[2]> (remove-nil-recursively '(NIL (state L L nil R L) NIL))
((STATE L L R L))
But watch out:
[3]> (remove-nil-recursively '(NIL (state L L (nil) R L) NIL))
((STATE L L NIL R L))
Paul Graham calls this function (recurring into sublists remove-if) "prune" in On Lisp, p. 49. It is one of the utility functions.
(defun prune (test tree)
(labels ((rec (tree acc)
(cond
((null tree) (nreverse acc))
((consp (car tree))
(rec (cdr tree)
(cons (rec (car tree) nil) acc)))
(t (rec (cdr tree)
(if (funcall test (car tree))
acc
(cons (car tree) acc)))))))
(rec tree nil)))
(prune #'evenp '(1 2 (3 (4 5) 6) 7 8 (9)))
(1 (3 (5)) 7 (9))
A generic function in the style of remove-if:
(defun remove-all (predic seq &optional res)
(if (null seq)
(reverse res)
(cond ((and (not (null (car seq))) (listp (car seq)))
(remove-all predic (cdr seq)
(cons (remove-all predic (car seq)) res)))
((funcall predic (car seq))
(remove-all predic (cdr seq) res))
(t (remove-all predic (cdr seq) (cons (car seq) res))))))
Examples:
> (remove-all #'null (list 1 2 'nil 3))
=> (1 2 3)
> (remove-all #'null (list 1 2 'nil '(4 5 nil 6) 3))
=> (1 2 (4 5 6) 3)
> (remove-all #'(lambda (x) (oddp x)) '(1 2 (3 4) 5 6 (7 8 (9 10))))
=> (2 (4) 6 (8 (10)))
(defun remove-if-nil (list) (remove-if-not 'identity list))
remove-if-not takes a predicate and a list, and removes all the items in the list that do not satisfy the predicate, that is, that return nil when evaluated in the predicate. identity, as you can guess, returns exactly the same thing it takes, so (remove-if-not 'identity list) removes every element in list that is nil.