Scheme member function, unsure of my definition - function

I want
(member? 'a '((d d) (d d)))
to return false
what am I doing wrong
(define (member? x list)
(cond
((null? list) #t )
(else ( or (or (eq? (car (car list)) x) (eq? (cdr (car list)) x)) (member? x (cdr list) ))
)))
If someone can tell me what is wrong with my member function I would greatly appreciate it.

((null? list) #t )
You're returning true if the list is empty. That's wrong.

Try this, it's a more general solution:
(define (member? ele lst)
(cond ((null? lst) #f)
((not (list? lst))
(equal? ele lst))
(else (or (member? ele (car lst))
(member? ele (cdr lst))))))
Notice that if you want to search inside a list of (arbitrarily nested) lists, the recursion is a little bit more elaborate: you have to consider the cases when the list is empty, when the list is not a list but a single element, and you have to recur on both the car and cdr parts of the list.
For example, the above definition will work for lists such as this:
(member? 'x '((a b) (c (x))))
> #t

Related

How can I improve my function to work better?

I am coding a function where I need to create a new list by inserting a certain value into the list after position N. Here is the code:
(DEFUN insertNth (L N insValue)
(cond ((NULL L) NIL)
((NULL (CDR L)) (CONS (CAR L) (insValue)))
(T (CONS (CAR L) (insertNth (CDR L) N insValue)))
)
)
When I try to test the code, I receive this error: *** - EVAL: undefined function INSVALUE. Is there a step or a piece of the function I may be missing?
(defun insertNth (l N insValue &optional (acc '()) (counter 0))
(cond ((null l) (nreverse acc))
((= N counter) (nconc (nreverse acc) (list insValue) l))
(t (insertNth (cdr l) N insValue (cons (car l) acc) (1+ counter)))))
I took the destructive functions nreverse and nconc due to performance reasons.
Destructive functions here have no danger, but improve performance.
You can, however, use the non-destructive functions reverse and append instead which will be more familiar to you.

Squaring all the elements in a list by Scheme

I wanted to square all elements in a list by the Scheme programming language.
my code is:
(define (square n) (* n *n))
(define (fun items factor)
(if (null? items)
0
(cons (* (fun (car items)
factor))
(fun (cdr items)
factor) ) ) ) )
(display (fun '( 1 2 3 4) square))
I'm showing these errors:
ERROR: In procedure car:
ERROR: In procedure car:
Wrong type (expecting pair): 1
You have a couple of errors:
The square procedure has an extra * that shouldn't be there
If we're building a list as output, then the base case should return the empty list '(), not 0.
The part where you operate on the current element of the list is incorrect, you should simply call the factor procedure on the car of the list, and there's no need to multiply again, square will take care of that.
This should fix them:
(define (square n) (* n n))
(define (fun items factor)
(if (null? items)
'()
(cons (factor (car items))
(fun (cdr items) factor))))
In real life, you don't need to implement this procedure yourself, map is already built-in and it's as simple to use as this:
(map square '(1 2 3 4))
=> '(1 4 9 16)
Here is other method:
(define factor-list
(lambda (l factor return)
(if (null? l)
(return '())
(factor-list (cdr l)
factor
(lambda (rest)
(return (cons (factor (car l))
rest)))))))
(define input '(1 2 3 4))
(factor-list input (lambda (x) (* x x)) (lambda (x) x))
Tail recursive implementation of map (to not to overwrite built-in map I called it *map).
(define (square x) (* x x))
(define (*map func lst (acc '()))
"Apply func on each element of the list."
(cond ((null? lst) (reverse acc))
(else (*map func (cdr lst) (cons (func (car lst)) acc)))))
Run it by:
(*map square '(1 2 3)) ;; '(1 4 9)

Scheme function that returns the shortest of the two lists

you must return a function that returns the shorter of the two lists. Wrote such function, but there is an error:
else: not allowed as an expression in: (else (sh (cdr shA) (cdr shB)))
I don't know how to fix it.
(define (shorter a b)
(let sh ((shA a) (shB b))
(cond
(((null? shA) a)
((null? shB) b)
(else (sh (cdr shA) (cdr shB)))))))
You've got too many parentheses - this is an entire expression:
(((null? shA) a)
((null? shB) b)
(else (sh (cdr shA) (cdr shB))))
and you can't have else in that position.
The syntax is (cond clause1 clause2 ...), not (cond (clause1 clause2 ...)), so you need
(define (shorter a b)
(let sh ((shA a) (shB b))
(cond
((null? shA) a)
((null? shB) b)
(else (sh (cdr shA) (cdr shB))))))

Combining two functions in LISP to atomize list and then find max?

So, id like to take in a list of numbers, atomize it (to remove nested integers), then find the max value. I have two functions written that accomplish this individually, but can't figure out how to combine them in LISP so I can make one call and have them both run. Any help would be appreciated.
:Atomize function to remove nests
:(atomify ‘( a (b c) (e (f (g h) i)) j)->(a b c e f g h i j)
(defun atomify (numbers)
(cond ((null numbers) nil)
((atom (car numbers))
(cons (car numbers)
(atomify (cdr numbers))))
(t
(append (atomify (car numbers))
(atomify (cdr numbers))))))
:Max value of a list of integers function
(defun large_atom (numbers)
(if (null numbers)
0
(max (first numbers)
(large_atom (rest numbers)))))
Jamie. Your way has two steps:
1. Flatten list
2. Find max value from result of 1'st step
In this case it's true way. But you need do it with one function call. It's easy. Just use labels, apply and of course max
(defun foo (lst)
(labels ((flatten (lst acc)
(cond
((null lst)
acc)
((consp (car lst))
(flatten (cdr lst) (flatten (car lst) acc)))
(t
(flatten (cdr lst) (cons (car lst) acc))))))
(apply #'max (flatten lst nil))))
Another way, is do not flatten source list. But in this case you need find first value to compare with other values. Try it yourself.
Here is another way to solve the problem: rather than flattening the list, this walks down it recursively. This is very explicit about what the structure of the list must be: a good list is a non-null proper list each of whose elements is either an integer or a good list.
The problem with this approach is that it's not tail recursive so it will necessarily fail on very large structures (and even if it was tail recursive CL does not promise to deal with tail recursion.
(defun greatest-integer (good-list)
;; a good list is one of:
;; - a cons of a good list and either a good list or ()
;; - a cons of an integer and either a good list or ()
;; In particular it can't be () and it can't be an improper list
;;
(destructuring-bind (a . b) good-list
;; a can be an integer or a good list, b can be null or a good list
(etypecase b
(null
(etypecase a
(integer a)
(cons (greatest-integer a))))
(cons
(max (etypecase a
(integer a)
(cons (greatest-integer a)))
(greatest-integer b))))))

Can AND/OR use a recursive function to get the value and use it in Common Lisp?

I have been stuck on this for a while. i have tried and I am not getting it. I thought I was getting it, but the fact that this isn't working is confusing. I should due getting 1 but keep getting nil. The purpose is to simplify the expression using the rules(which I added below). My problem:
(defun simplify (main-list)
(setq count 1)
(if (and (eq t (atom (car (cdr main-list))))
(eq t (atom (car (cdr (cdr main-list))))))
(print "this says that the 2 ands are cons cells"))
(if (and (eq nil (cdr main-list))
(eq t (atom (car main-list))))
(print "reached end of file, going back now"))
(if (eq 'and (car main-list))
(progn
(if (and (eq t (atom (car (cdr main-list))))
(eq nil (atom (car (cdr (cdr main-list))))))
(if (or (eq nil (car (cdr main-list)))
(simplify (car (cdr (cdr main-list)))))
nil
(if (eq 1 (car (cdr main-list)))
(simplify (car (cdr (cdr main-list))))
(if (eq 1 (simplify (car (cdr (cdr main-list)))))))))
(if (and (eq t (atom (car (cdr main-list))))
(eq t (atom (car (cdr (cdr main-list))))))
(if (or (eq nil (car (cdr main-list)))
(eq nil (car (cdr (cdr main-list)))))
nil
(if (eq 1 (car (cdr main-list)))
(car (cdr (cdr main-list)))
(if (eq 1 (car (cdr (cdr main-list))))
(car (cdr main-list)))))))))
The list I am using is:
(and 1 (and 1 1))
This is a simple version of what I am trying to accomplish, but I am tackling it a step at a time since I am completely new to the language. These are the rules for the AND I am suppose to follow for this Homework:
(and x nil) => nil;
(and nil x) => nil;
(and x 1) => x;
(and 1 x) => x;
I have tested it by doing
(simplify (car(cdr(cdr x))))
and I added counts to see if its even looping, but it is not. So my guess it has something to do with the recursive function calls that are within the if statements in the first block of code. Any explanations as to why would be greatly appreciated.
(defun simplify (expression)
(if (consp expression)
(destructuring-bind (op arg1 arg2)
expression
(ecase op
(and (cond ((or (null arg1) (null arg2))
nil)
((eql 1 arg1)
(simplify arg2))
((eql 1 arg2)
(simplify arg1))))))
expression))