Cons the first element of every sublist? - scheme

I'm writing a function to get me the children nodes of a parent, my code is:
(define (children elem tree)
(if (eqv? tree '())
'()
(if (= elem (car tree))
(getchilds (cdr tree))
(children elem (cdr tree)))))
(define (getchilds childNodes)
(cond ((null? childNodes) '())
(else (cons (caar childNodes) (getchilds (cdr childNodes))))))
This half works.
(children 10 '(10 (2 (4 (9 (3)) (12 (1 (2))) (16))) (5 (7) (21)) (6)))
outputs (2 5 6) which is what I expect
but (children 2 '(10 (2 (4 (9 (3)) (12 (1 (2))) (16))) (5 (7) (21)) (6))) fails.
I get a
=: contract violation
expected: number?
given: (2 (4 (9 (3)) (12 (1 (2))) (16)))
argument position: 2nd
other arguments...:
I think it's because (= elem (car tree) expect a number as a second parameter, but if I do
(car '(2 (4 (9 (3)) (12 (1 (2))) (16))))
output is 2
So I'm not quite sure where my logic fails. Anybody got an idea?

Consider your input list of (10 (2 (4 (9 (3)) (12 (1 (2))) (16))) (5 (7) (21)) (6)) (called tree in your code).
When you recurse with (cdr tree) (as you do in (children elem (cdr tree))), the new tree (in the recursive call) becomes ((2 (4 (9 (3)) (12 (1 (2))) (16))) (5 (7) (21)) (6)). That means (car tree) is (2 (4 (9 (3)) (12 (1 (2))) (16))) (5 (7) (21)) (6). That's not a number.

Related

How would I write a Scheme procedure that takes in a tree (represented as a list) and return that list with its elements reversed essentially?

I am having trouble writing a Scheme procedure that takes a tree (represented as a list) and returns a list whose elements are all the leaves of the tree arranged in right to left order.
For example, if I were to call: ( leaves '(((1 2) (3 4)) ((1 2) (3 4))) ) I would get: '(4 3 2 1 4 3 2 1)
I have the following so far, and the output is technically correct, but there is an issue with the parenthesis:
(define (leaves givenList)
(if (null? givenList) givenList
(if (list? (car givenList))
(append (leaves (cdr givenList)) (cons (leaves (car givenList)) '()))
(append (leaves (cdr givenList)) (list (car givenList))))))
The output when I call: ( leaves '(((1 2) (3 4)) ((1 2) (3 4))) ) is: (((4 3) (2 1)) ((4 3) (2 1)))
I need to get rid of the parenthesis on the inside and just get: '(4 3 2 1 4 3 2 1)
Any help or insight is greatly appreciated. Thanks!

How to Replace elements in a nested list in Scheme

I am trying to have a list like this...
'((0 1 2) (3 4 5) (6 7 8) (0 3 6) (1 4 7) (2 5 8) (0 4 8) (2 4 6))
and replace all occurrences of a certain number.
For example when running
(replace 4 "x" '((0 1 2) (3 4 5) (6 7 8) (0 3 6) (1 4 7) (2 5 8) (0 4 8) (2 4 6)))
The Desired output is
'((0 1 2) (3 x 5) (6 7 8) (0 3 6) (1 x 7) (2 5 8) (0 x 8) (2 x 6)))
What I have tried so far is
(define (replace var player list)
(if (null? list)
'()
(if (list? (car list))
(replace var player (cdr list))
(if (equal? var (car list))
(cons player (replace var player (cdr list)))
(cons (car list) (replace var player (cdr list)))
))))
Which when I run to replace all 1's with an x the output is '(0 "x" 2)
You are on the right track, you are only missing actually applying the function on (car lst) whenever the first element is a list itself, ie:
...
(if (list? (car list))
(cons (replace var player (car list)) ;; missing this
(replace var player (cdr list)))
(if ...
Also, avoid using built-in procedures as variable names (eg. list), and when using conditionals, instead of nesting multiple if statements, use cond or its relatives that better translate to the conventional if ... else if ... else ... idea.

contract violation expected: number?-Scheme

I am new to racket and scheme and I am attempting to map the combination of a list to the plus funtion which take each combination of the list and add them together like follows:
;The returned combinations
((1 3) (2 3) (1 4) (2 4) (3 4) (1 5) (2 5) (3 5) (4 5) (1 6) (2 6) (3 6) (4 6) (5 6) (1 2) (2 2) (3 2) (4 2) (5 2) (6 2))
; expected results
((2) (5) (5).....)
Unfortunately I am receiving the contract violation expected error from the following code:
;list of numbers
(define l(list 1 2 3 4 5 6 2))
(define (plus l)
(+(car l)(cdr l)))
(map (plus(combinations l 2)))
There are a couple of additional issues with your code, besides the error pointed out by #DanD. This should fix them:
(define lst (list 1 2 3 4 5 6 2))
(define (plus lst)
(list (+ (car lst) (cadr lst))))
(map plus (combinations lst 2))
It's not a good idea to call a variable l, at first sight I thought it was a 1. Better call it lst (not list, please - that's a built-in procedure)
In the expected output, weren't you supposed to produce a list of lists? add a call to list to plus
You're not passing plus in the way that map expects it
Do notice the proper way to indent and format your code, it'll help you in finding bugs
You want (cadr l). Not (cdr l) in your plus function:
(define (plus l)
(+ (car l) (cadr l)))
Where x is (cons 1 (cons 2 '())):
(car x) => 1
(cdr x) => (cons 2 '())
(cadr x) == (car (cdr x)) => 2

printing pairs from a list in scheme

I'm trying to print pairs from one list kinda like a subset in scheme but with two elements just like this
(1 2 3 4 5)
((1 2) (1 3) (1 4) (1 5) (2 3) (2 4) (2 5) (3 4) (3 5) (4 5))
the code I wrote doesn't work
(define (subset x)
(if ( null? x) x
(map cons x (subset (cdr x)))))
this just return an empty list
I prefer to write the lambdas explicitly, makes it easier to understand what arguments are passed:
(define subset
(lambda (lst)
(if (null? lst)
lst
(append (map (lambda (el) (cons (car lst) el)) (cdr lst))
(subset (cdr lst)))
)))
(subset '(1 2 3 4 5))
=> ((1 . 2) (1 . 3) (1 . 4) (1 . 5) (2 . 3) (2 . 4) (2 . 5) (3 . 4) (3 . 5) (4 . 5))
EDIT: The explanation about map below is only valid in some versions of scheme, read Sylwester's comment to this answer.
map traverses n lists supplied to it and applies proc to the n elements in the same position in the lists. This means it can apply proc no more times than the length of the shortest list, but you keep giving it an empty list (from the last recursive call backwards).
(BTW this is in plain scheme)
In #lang racket that is very easy since we have combinations:
(combinations '(1 2 3 4 5) 2)
; ==> ((1 2) (1 3) (2 3) (1 4) (2 4) (3 4) (1 5) (2 5) (3 5) (4 5))
Now this does not print anything. To get it print to the terminal you can use displayln:
(displayln (combinations '(1 2 3 4 5) 2))
; ==> #<void>, ((1 2) (1 3) (2 3) (1 4) (2 4) (3 4) (1 5) (2 5) (3 5) (4 5)) printed to terminal as side effect
If order of items is also important, following can be used:
(define (subsets l)
(let loop ((n 0) ; run a loop for each item
(ol '())) ; start with blank output list
(cond
[(= n (length l)) (reverse ol)] ; output ol when last item reached;
[else
(let* ((x (list-ref l n)) ; get one item
(jl (for/list ((i l) ; get remaining list
(j (in-naturals))
#:unless (= j n))
i))
(kl (for/list ((i jl)) ; make combinations with each of remaining list
(list x i))))
(loop (add1 n) (cons kl ol)))])))
Testing:
(subsets '(1 2 3 4 5))
Output:
'(((1 2) (1 3) (1 4) (1 5))
((2 1) (2 3) (2 4) (2 5))
((3 1) (3 2) (3 4) (3 5))
((4 1) (4 2) (4 3) (4 5))
((5 1) (5 2) (5 3) (5 4)))

How to get levels of a corresponding element of a list in Scheme [duplicate]

This question already has answers here:
Scheme - Replacing elements in a list with its index
(4 answers)
Closed 7 years ago.
I want to print the level of every list element in scheme in the following manner.
List: '(1 (20 (3 (4 40) 3) 2) 1)
expected result: '(0 (1 (2 (3 4) 5) 6) 7)
Kindly help.
Something like this:
(define (print-level x current-level)
(define (deeper x) (print-level x (+ current-level 1)))
(define (same x) current-level)
(define (print-element x)
(if (list? x)
(map deeper x)
(same x)))
(map print-element x))

Resources