get 7 not (7) out of the list? - scheme

Here's my code:
(define step1_list1 '(1 3 (5 7) 9))
(car (cdr (cdr (step1_list1))))
(define step1_list2 '((7)))
(car (step1_list2))
(define step1_list3 '(1 (2 (3 (4 (5 (6 7)))))))
(car (cdr (cdr (cdr (cdr (cdr step1_list3))))))
))
Running this code causes an error:
(1 3 (5 7) 9) is not applicable
What is the problem?

Start small.
(define mylist '(1 2 3))
(display mylist)
(display (car mylist))
(display (car (mylist)))
Run each of those in turn, and see what you get at each step. Once you understand why you get the output you do, then you should be able to fix the code in your question.

In Scheme, (non-quoted) parentheses mean function application. So (car (step1_list2)) tries to execute step1_list2 as a procedure (and then take the car of the result). Instead, you want:
(car step1_list2)

Related

Scheme function for adding elements in nested list [duplicate]

This question already has an answer here:
scheme recursion
(1 answer)
Closed 5 months ago.
I'm trying to create a scheme program that adds the elements of a given list (both simple and nested).
(define (adder a_list)
(cond
((null? a_list) 0)
((list? (car a_list))(adder (car a_list)))
(else (+ (car a_list) (adder (cdr a_list))))
)
)
(adder '(2 (5 4) 6))```
The problem I'm running into is that when I run this, it only adds (5+4) + 2, and then doesn't add the 6. So my output is 11 rather than 17. I know my null statement at the top is causing this issue, but when I take it out I get this error:
car: contract violation
expected: pair?
given: '()
Any tips would be greatly appreciated.
(define (adder a*)
(if (null? a*)
0
(+ (if (pair? (car a*))
(adder (car a*))
(car a*))
(adder (cdr a*)))))
And, shorter:
(define ++
(lambda (a*)
(fold-left (lambda (a x)
(+ a (if (pair? x) (++ x) x)))
0
a*)))
(written in mit/scheme)

Splitting a list recursively in Scheme

What I want to do is define a list such as (define lst '(1 2 3 4 5 6)) and then call (split lst) which will return '((1 3 5) (2 4 6)).
Some examples:
When lst is '(1 2 3 4 5 6) it should return '((1 3 5) (2 4 6))
When lst is '(1 2 3 4 5 6 7) it should return '((1 3 5 7) (2 4 6))
When lst is '("a" "little" "bit" "of" "that" "to" "spice" "things" "up") it should return '(("a" "bit" "that" "spice" "up") ("little" "of" "to" "things"))
It should alternate when building the two lists. So the first index should go in the first list, second index in the second list, third index in the first list, etc.
Here is my current script.
(define (split lst)
(cond ((null? lst) lst)
((null? (cdr lst)) lst)
((cons (cons (car lst) (split (cddr lst))) (cons (cadr lst) (split (cddr lst)))))))
Currently, this is what outputs when I split the list '(1 2 3 4 5 6)
((1 (3 (5) 6) 4 (5) 6) 2 (3 (5) 6) 4 (5) 6)
Lets fix your code step by step:
(define (split lst)
(cond ((null? lst) lst)
((null? (cdr lst)) lst)
((cons (cons (car lst) (split (cddr lst))) (cons (cadr lst) (split (cddr lst)))))))
The first thing I notice is the lack of an else in the last case of the cond. Conds are supposed to look like:
(cond (question-1 answer-1)
(question-2 answer-2)
...
(else else-answer))
With an else inserted your code looks like this:
(define (split lst)
(cond ((null? lst) lst)
((null? (cdr lst)) lst)
(else
(cons (cons (car lst) (split (cddr lst))) (cons (cadr lst) (split (cddr lst)))))))
The next thing is the first base case, or the answer to the (null? lst) cond question. On an empty list what should it return?
It seems like no matter how long the list is, it should always return a list of exactly two inner lists. So when lst is empty the logical answer would be (list '() '()).
(define (split lst)
(cond ((null? lst)
(list '() '()))
((null? (cdr lst)) lst)
(else
(cons (cons (car lst) (split (cddr lst))) (cons (cadr lst) (split (cddr lst)))))))
Next is the second base case, the answer to the (null? (cdr lst)) cond question. Again it should return a list of exactly two inner lists:
(list ??? ???)
The the first index should go in the first list, and then there's nothing to go in the second list.
(list (list (car lst)) '())
In the context of your code:
(define (split lst)
(cond ((null? lst)
(list '() '()))
((null? (cdr lst))
(list (list (car lst)) '()))
(else
(cons (cons (car lst) (split (cddr lst))) (cons (cadr lst) (split (cddr lst)))))))
Now, what is the behavior of this function?
> (split '(1 2 3 4 5 6))
'((1 (3 (5 () ()) 6 () ()) 4 (5 () ()) 6 () ()) 2 (3 (5 () ()) 6 () ()) 4 (5 () ()) 6 () ())
Still not what you want. So what is the last case, recursive case, supposed to do?
Consider what you're "given" and what you need to "produce".
Given:
(car lst) the first element
(cadr lst) the second element
(split (cddr lst)) a list of exactly two inner lists
You should produce:
(list ??? ???)
Where the first ??? hole contains the first element and the first of the two inner lists, and the second ??? hole contains the second element and the second of the two inner lists.
This suggests code like this:
(list (cons (car lst) (first (split (cddr lst))))
(cons (cadr lst) (second (split (cddr lst)))))
Or, since car gets the first and cadr gets the second:
(list (cons (car lst) (car (split (cddr lst))))
(cons (cadr lst) (cadr (split (cddr lst)))))
In the context of your code:
(define (split lst)
(cond ((null? lst)
(list '() '()))
((null? (cdr lst))
(list (list (car lst)) '()))
(else
(list (cons (car lst) (car (split (cddr lst))))
(cons (cadr lst) (cadr (split (cddr lst))))))))
Using it produces what you want:
> (split '(1 2 3 4 5 6))
'((1 3 5) (2 4 6))
> (split '(1 2 3 4 5 6 7))
'((1 3 5 7) (2 4 6))
> (split '("a" "little" "bit" "of" "that" "to" "spice" "things" "up"))
'(("a" "bit" "that" "spice" "up") ("little" "of" "to" "things"))
Now what was the difference between this and what you had before?
Your code before:
(cons (cons (car lst) (split (cddr lst)))
(cons (cadr lst) (split (cddr lst))))
The fixed version:
(list (cons (car lst) (car (split (cddr lst))))
(cons (cadr lst) (cadr (split (cddr lst)))))
The first difference is that your original version uses cons on the outside, while the fixed version uses list instead. This is because (list ??? ???) always returns a list of exactly two elements, while (cons ??? ???) can return a list of any size greater than 1, which has the first thing merged onto an existing second list. (list ??? ???) is what you want here because you specified that it should return a list of exactly two inner lists.
The second difference is in how you use the recursive call (split (cddr lst)).
This has to do with how you interpreted the "given" part of the recursive case. You had assumed that the first call to split would give you the first "inner" list, and the second call to split would give you the second "inner" list. In fact it gives you a list of both of those both times. So for the first one you have to get the "first" or car of it, and for the second one you have get the "second" or cadr of it.
Looks like this might be what you're looking for:
(define (split lst)
(define (loop lst do-odd odds evens)
(if (null? lst)
(list (reverse odds) (reverse evens))
(loop (cdr lst) (not do-odd)
(if do-odd (cons (car lst) odds) odds)
(if (not do-odd) (cons (car lst) evens) evens))))
(loop lst #t '() '()))
In use:
1 ]=> (split '(1 2 3 4 5 6))
;Value 2: ((1 3 5) (2 4 6))
1 ]=> (split '(1 2 3 4 5 6 7))
;Value 3: ((1 3 5 7) (2 4 6))
This uses the variable do-odd in the inner loop function (which is tail-recursive, by the way, so it is fast!) to figure out which list it should add the (car lst) to.
Downsides to this function: the call to reverse in the base case can be expensive if your lists are very long. This may or may not be a problem. Profiling your code will tell you if it's a bottleneck.
UPDATE: You can also use the function reverse!, which destructively modifies the array in question. I did some informal profiling, and it didn't seem to make that much of a difference speed-wise. You will have to test this under your specific circumstances.
Now, if this isn't intended to be performant, use whatever you want! :)
My shortest solution
(define (split l)
(cond ((null? l) '(() ()))
((null? (cdr l)) (list (list (car l)) '()))
(else (map cons (list (car l) (cadr l))
(split (cddr l))))))
Similar but wordier solution
Ensure that split always returns a list of two lists.
Then you can define it quite compactly:
(define (split l)
(cond ((null? l) '(() ()))
((null? (cdr l)) (list (list (car l)) '()))
(else (double-cons (list (car l) (cadr l))
(split (cddr l))))))
with double-cons being:
(define (double-cons l lol)
(list (cons (car l) (car lol))
(cons (cadr l) (cadr lol))))
double-cons:
(double-cons '(a 1) '((b c) (2 3)))
; => '((a b c) (1 2 3))
Other double-cons definitions
This takes more lines but makes it easier to read:
(define (double-cons l lol)
(let ((e1 (car l))
(e2 (cadr l))
(l1 (car lol))
(l2 (cadr lol)))
(list (cons e1 l1) (cons e2 l2))))
Or a double-cons which conses even more elements and lists in parallel:
(define (parallel-cons l lol)
(map cons l lol))
; it is `variadic` and conses as many elements with their lists
; as you want:
(parallel-cons '(1 a A '(a)) '((2 3) (b c d e) (B C) ((b) (c))))
; '((1 2 3) (a b c d e) (A B C) ('(a) (b) (c)))
; this combination of `map` and `cons` is used in the shortest solution above.

Scheme Double All List Values and Write Mapping Function

I have a question on a homework assignment that is as follows:
I have the first part (double-list-elements) complete
(define (double-list-elements s)
(if (null? s)
'()
(cons (* 2 (car s))
(double-list-elements (cdr s)))))
but I honestly have absolutely no idea how to proceed with double-list-elements-one. Any pointers would be greatly appreciated.
Close But No Cigar:
(define (double-list-elements s)
(if (null? s)
'()
(cons (* 2 (car s))
(double-list-elements (cdr s)))))
(define (custom-map proc lst)
(if (null? lst)
'()
(cons (proc lst)
(custom-map proc (cdr lst)))))
(define (double-list-elements-one func s)
(custom-map double-list-elements s))
(double-list-elements-one double-list-elements '(1 2 3 4 5 6))
Output = (list (list 2 4 6 8 10 12) (list 4 6 8 10 12) (list 6 8 10 12) (list 8 10 12) (list 10 12) (list 12))
I need to pass double-list-elements to double-list-elements-one as a parameter as well as the list.
You just have to write your own map, it's very very similar to what you already have, simply pass the part that changes as a procedure parameter, and invoke it on the right place:
(define (mymap proc lst)
(if (null? lst)
'()
(cons <invoke proc on current element>
(mymap proc (cdr lst)))))
(define (double-list-elements-one s)
(mymap <pass a proper lambda> s))
(double-list-elements-one '(1 2 3 4 5))
=> '(2 4 6 8 10)

How to code Power Set in Lisp R5RS [duplicate]

This question already has answers here:
How to do a powerset in DrRacket?
(5 answers)
Closed 7 years ago.
I'm new to functional programming and I have no idea how to code this in Lisp. For example, for a given power set such as (1 2 3), how do I code it in a way to make it: (WITHOUT using Lambda functions)
( () (1) (2) (3) (1 2 3) )
So far, I have:
(define (powerSet lis)
(if (null? lis) '(()))
)
(define (APPENDS lis1 lis2)
(cond
((null? lis1) lis2)
(else (cons (car lis1)
(APPENDS (cdr lis1) lis2)))
)
)
Which just returns the empty set, or nothing.
EDIT:
Thank you so much Chris! That made so much sense. The second variation (without the append-map function) works well. However, if you input (powerset'(1 2 3 4)), it gives you:
(()
(1)
(2)
(1 2)
(3)
(1 3)
(2 3)
(1 2 3)
(4)
(1 4)
(2 4)
(1 2 4)
(3 4)
(1 3 4)
(2 3 4)
(1 2 3 4))
Is there anyway for me to make it look like:
(()
(1)
(2)
(3)
(4)
(1 2)
(1 3)
(1 4)
(2 3)
(2 4)
(3 4)
(1 2 3)
(1 2 4)
(1 3 4)
(2 3 4)
(1 2 3 4))
Thanks so much!
All user-defined functions are lambda (or case-lambda) expressions, including the powerset function you're defining. There is no way to avoid it. However, you can hide the lambda identifier by using internal definitions (it's still a lambda behind the scenes!†).
With this in mind, here's an implementation (requires Racket or SRFI 1):
(define (powerset lst)
(define (make-pair x)
(list x (cons (car lst) x)))
(if (null? lst)
'(())
(append-map make-pair (powerset (cdr lst)))))
If you're trying to avoid append-map or higher-order functions in general, you could jump through a few hoops to do the same thing:
(define (powerset lst)
(define (inner next)
(if (null? next)
'()
(cons (car next)
(cons (cons (car lst) (car next))
(inner (cdr next))))))
(if (null? lst)
'(())
(inner (powerset (cdr lst)))))
† An expression like
(define (foo bar)
baz)
is actually expanded into the following equivalent expression:
(define foo
(lambda (bar)
baz))

How to delete the 2nd to last element from a list in Scheme?

I'm using Scheme and I'm trying to remove the 2nd to last element in the list recursively.
This is what I have:
(define delete
(lambda (num lst)
(cond
((equal? (length lst) 1) '())
((null? lst) '())
(else (cons (car lst)(delete num (cdr lst)))))))
(define second
(lambda(lst)
(delete (- (length lst) 1) lst)))
(second '(1))
(second '(3 5 6))
(second '(2 7 8 4 9))
returns this:
()
(3 5)
(2 7 8 4)
When it should return this:
()
(3 6)
(2 7 8 9)
The (second '(1)) is doing what I intended but I've playing with the other part for a few hours and I'm still at a loss. Any tips or suggestions would be very appreciated at this point.
EDIT:
Wow, Thank you! It was that one line of missing code -_- Duh me!
You never use the num argument. So you will always iterate until the list has 1 element or is null. You could add a special case for when the list has 2 elements:
(define delete
(lambda (num lst)
(cond
((equal? (length lst) 2) (cdr lst))
((equal? (length lst) 1) '())
((null? lst) '())
(else (cons (car lst)(delete num (cdr lst)))))))
(define second
(lambda(lst)
(delete (- (length lst) 1) lst)))
Since the num argument isn't used, you can do:
(define delete_second_last
(lambda (lst)
(cond
((equal? (length lst) 2) (cdr lst))
((equal? (length lst) 1) '())
((null? lst) '())
(else (cons (car lst)(delete_second_last (cdr lst)))))))
(delete_second_last '(3 6 7 9 10))

Resources