How can i append string to list? - list

I am trying to completing a school assignment where i have to write a function which takes two arguments where the first condition is the length of the list is greater than 4 which is working,however,the problems begins with appending the a variable "s" to the list.for e,g
(define SOB (λ ( s L1)
(cond
((string? s)
((list? L1) (> 4)
(append s L1))))))
this is my code i have been trying to find ways to do this but i keep getting errors.this is input test
(SOB "hi" '(1 2 3 4 5 6))
and this is the error i receive
append: contract violation
expected: list?
given: "hi"
i am new to racket and i would really appreciate some help with this

The correct function is cons, not append. append is for concatenating multiple lists, but s is not a list.
You also need to combine all your conditions with and.
(define SOB (λ ( s L1)
(cond
((and (string? s) (list? L1) (> (length L1) 4))
(cons s L1))))

Related

How can I append two lists together? Scheme

I need help merging two lists together. My goal is to replace "a" with "abc". I've already done a counter etc but somehow I can't append these two lists (list which is an empty list and '("abc") as my new list that I want to add).
I've tried to add more brackets but the problem just keeps getting worse the more I add.
(define (umwandl tr)
(cond ((null? tr) (display "Kein Text eingegeben"))
(else (uff (string->list tr) '())))) ; string wird nict inliste umgweandel
(define (uff tr liste)
(cond ((null? tr)(list->string liste))
(else
(cond ((equal? (first (rest (first (start1 (first tr))))) 1)
**((append list (list '("abc"))))))**
(uff (rest tr) liste))))
My error messages are either that ('("abc")) isn't an argument or it just gives me "" as an answer. It would be super nice if anyone could help!
Learning Scheme or any Lisp means getting to know list structure. A list (1 2 3) can be made like (cons 1 (cons 2 (cons 3 '()))) and I like to think that element in a list that does not have a . means there is one and the rest has an extra set of paranthesis. Done recursive! Thus:
'(1 2 3) ; ==
'(1 . (2 3)) ; ==
'(1 . (2 . (3))) ; ==
'(1 . (2 . (3 . ()))) ; ==> (1 2 3)
I see the dots that aren't there when I see lists so I know 3 is caddr since I pass . ( 2 times (dd) and then jump into the car, thus caddr.
Appending two lists together means copying the first list and replaceing () with the second list. Thus append can be defined as:
(define (my-append l1 l2)
(if (null? l1)
l2
(cons (car l1)
(my-append (cdr l1) l2))))
Replacing one element with another. You need to do the same BUT you compare the first element in each iteration and based on that either use the element you found or the replacement. If you want to compare strings then you need to use equal? since (eqv? "hello" "hello") ; ==> #f is a valid result.

Write a scheme that returns a list of even numbers

Write a Scheme function that returns the list of even numbers in a given list of integer numbers.The list may not be simple,nested lists can occur and you need to find the even numbers inside those.
(DEFINE (evenlist numberlist)
using this as a body and getting the result sth like this
(DEFINE (evenlist numberlist)
Result:(2 4 6 4)
(define (evenlist numberlist)
(cond
((null? numberlist) '())
(else(not (= 0 (modulo (numberlist) 2))(evenlist(car numberlist))))
))
this is what i have done , i am new to lisp so dont blame me :(
You have to do a bit more of work if the input list is an arbitrarily nested list of lists. This is the standard template to process such lists (cases: empty list, non-list or a list of lists), plus additional logic to flatten the result (that's why append is used here):
(define (evenlist numberlist)
(cond ((null? numberlist) '())
((not (pair? numberlist))
(if (even? numberlist) (list numberlist) '()))
(else
(append (evenlist (car numberlist))
(evenlist (cdr numberlist))))))

Insert element to circular list using scheme

I have a circular list, eg: #0=(1 2 3 4 . #0#).
What I want to do is to insert a new element (x) into this list so that the outcome is #0=(x 1 2 3 4 . #0#). I have been trying using this code (x is the circular list):
(define (insert! elm)
(let ((temp x))
(set-car! x elm)
(set-cdr! x temp)))
However, I think that set-cdr! is not working like I want it to. What am I missing here? Maybe I am way off?
The easiest way to prepend an element to a list is to modify the car of the list, and set the cdr of the list to a new cons whose car is the original first element of the list and whose cdr is the original tail of the list:
(define (prepend! x list) ; list = (a . (b ...))
(set-cdr! list (cons (car list) (cdr list))) ; list = (a . (a . (b ...)))
(set-car! list x)) ; list = (x . (a . (b ...)))
(let ((l (list 1 2 3)))
(prepend! 'x l)
(display l))
;=> (x 1 2 3)
Now, that will still work with circular lists, because the cons cell (i.e., pair) that is the beginning of the list remains the same, so the "final" cdr will still point back to object that is the beginning. To test this, though, we need some functions to create and sample from circular lists, since they're not included in the language (as far as I know).
(define (make-circular list)
(let loop ((tail list))
(cond
((null? (cdr tail))
(set-cdr! tail list)
list)
(else
(loop (cdr tail))))))
(define (take n list)
(if (= n 0)
'()
(cons (car list)
(take (- n 1)
(cdr list)))))
(display (take 10 (make-circular (list 1 2 3))))
;=> (1 2 3 1 2 3 1 2 3 1)
Now we can check what happens if we prepend to a circular list:
(let ((l (make-circular (list 1 2 3))))
(prepend! 'x l)
(display (take 15 l)))
;=> (x 1 2 3 x 1 2 3 x 1 2 3 x 1 2)
Since you're trying to prepend an element to a circular list, you need to do two things:
Insert a new cons cell at the front of the list containing the additional element. This is easy because you can just perform a simple (cons elm x).
You also need to modify the recursive portion of the circular list to point at the newly created cons cell, otherwise the circular portion will only include the old parts of the list.
To perform the latter, you need a way to figure out where the "end" of the circular list is. This doesn't actually exist, since the list is, of course, circular, but it can be determined by performing an eq? check on each element of the list until it finds an element equal to the head of the list.
Creating a helper function to do this, a simple implementation of insert! would look like this:
(define (find-cdr v lst)
(if (eq? v (cdr lst)) lst
(find-cdr v (cdr lst))))
(define (insert! elm)
(set! x (cons elm x))
(set-cdr! (find-cdr (cdr x) (cdr x)) x))

Scheme function to reverse a list

For my programming languages class I'm supposed to write a function in Scheme to reverse a list without using the pre-made reverse function. So far what I got was
(define (reverseList lst)
(COND
((NULL? lst) '())
(ELSE (CONS (reverseList(CDR lst)) (CAR lst)))
))
The problem I'm having is that if I input a list, lets say (a b c) it gives me (((() . c) . b) . a).
How am I supposed to get a clean list without multiple sets of parenthesis and the .'s?
The problem with your implementation is that cons isn't receiving a list as its second parameter, so the answer you're building isn't a proper list, remember: a proper list is constructed by consing an element with a list, and the last list is empty.
One possible workaround for this is to use a helper function that builds the answer in an accumulator parameter, consing the elements in reverse - incidentally, this solution is tail recursive:
(define (reverse lst)
(reverse-helper lst '()))
(define (reverse-helper lst acc)
(if (null? lst)
acc
(reverse-helper (cdr lst) (cons (car lst) acc))))
(reverse '(1 2 3 4 5))
=> '(5 4 3 2 1)
You are half way there. The order of the elements in your result is correct, only the structure needs fixing.
What you want is to perform this transformation:
(((() . c) . b) . a) ; input
--------------------
(((() . c) . b) . a) () ; trans-
((() . c) . b) (a) ; for-
(() . c) (b a) ; mation
() (c b a) ; steps
--------------------
(c b a) ; result
This is easy to code. The car and cdr of the interim value are immediately available to us. At each step, the next interim-result is constructed by (cons (cdr interim-value) interim-result), and interim-result starts up as an empty list, because this is what we construct here - a list:
(define (transform-rev input)
(let step ( (interim-value input) ; initial set-up of
(interim-result '() ) ) ; the two loop variables
(if (null? interim-value)
interim-result ; return it in the end, or else
(step (car interim-value) ; go on with the next interim value
(cons ; and the next interim result
(... what goes here? ...)
interim-result )))))
interim-result serves as an accumulator. This is what's known as "accumulator technique". step represents a loop's step coded with "named-let" syntax.
So overall reverse is
(define (my-reverse lst)
(transform-rev
(reverseList lst)))
Can you tweak transform-rev so that it is able to accept the original list as an input, and thus skip the reverseList call? You only need to change the data-access parts, i.e. how you get the next interim value, and what you add into the interim result.
(define (my-reverse L)
(fold cons '() L)) ;;left fold
Step through the list and keep appending the car of the list to the recursive call.
(define (reverseList lst)
(COND
((NULL? lst) '())
(ELSE (APPEND (reverseList(CDR lst)) (LIST (CAR lst))))
))
Instead of using cons, try append
(define (reverseList lst)
(if (null? lst)
'()
(append (reverseList (cdr lst)) (list (car lst)) )
)
)
a sample run would be:
1]=> (reverseList '(a b c 1 2 + -))
>>> (- + 2 1 c b a)
car will give you just one symbol but cdr a list
Always make sure that you provide append with two lists.
If you don't give two lists to the cons it will give you dotted pair (a . b) rather than a list.
See Pairs and Lists for more information.

Scheme: adding 2 lists by index

I need to write a function in Scheme (Racket) that takes two not necessarily equal
length lists and return a list which each element is the sum of the elements of the same
index from the two lists. if the lists' length is not equal the shorter one should append to itself until it reaches the size of the longer one. for example:
=> (addLists '(1 2 3 4) '(1 2))
(2 4 4 6)
=> (addLists '(1 2 3 4) '(1 2 3 4 5))
(2 4 6 8 6)
Until now I was able to write a function that completes this for equal length lists, but the problem lies with how do I increase the length of the shorter list within this function (or with a helper function that gets a list and a size and extends it properly).
(define (sumListPairs lst1 lst2)
(if (null? lst1) null
(cons (+ (car lst1) (car lst2))
(sumListPairs (cdr lst1) (cdr lst2)))))
Will appreciate any help, Thank you.
This can be done, but since I have the impression that this is a homework exercise, I'll only give a hint. First, introduce a named-let to do the actual recursion. Then, expand the number of cases in the recursion from two to four.
(define (sumListPairs lst1 lst2)
(let loop ((l1 lst1) (l2 lst2))
(cond ((and (null? l1) (null? l2)) null)
((null? l1) ...)
((null? l2) ...)
(else (cons (+ (car lst1) (car lst2))
(loop (cdr l1) (cdr l2)))))))
Now, fill in the ... parts. Note that you have access to all of l1, l2, lst1 and lst2. (You might want to refactor a bit after you're done, since the cases will be quite similar.)