How can I improve my function to work better? - function

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.

Related

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))))))

Scheme: Convert from Let to Lambda

so I'm trying to experiment with some code and change between the two scheme expression methods of let and lambda.
The code I have is as follows:
(let splice ((l '()) (m (car s)) (r (cdr s)))
(append
(map (lambda (x) (cons m x)) (perm (append l r)))
(if (null? r) '()
(splice (cons m l) (car r) (cdr r)))))
I'm trying to change the outermost let definitions to lambda format, but it's a bit confusing due to the nested nature of the code. What I have attempted to do so far is:
(lambda (splice (l m r))
(append
(map (lambda (x) (cons m x)) (perm (append l r)))
(if (null? r) '()
(cut (cons m l) (car r) (cdr r)))))
(('()) (car upList) (cdr upList))
This is clearly wrong, but I don't know how to proceed further...
I wrote a post about how let is transformed into lambda behind the scenes, which you may find helpful.
According to the expansion described in my post, your code would expand into:
((rec (splice l m r)
(append (map (lambda (x) (cons m x)) (perm (append l r)))
(if (null? r)
'()
(splice (cons m l) (car r) (cdr r)))))
'() (car s) (cdr s))
which then expands to:
((letrec ((splice (lambda (l m r)
(append (map (lambda (x) (cons m x)) (perm (append l r)))
(if (null? r)
'()
(splice (cons m l) (car r) (cdr r)))))))
splice)
'() (car s) (cdr s))

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))

Scheme member function, unsure of my definition

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