How do I traverse a tree in Scheme? - recursion

I'm new to scheme and I am trying to learn how to traverse a B-tree. I'm limited to certain commands from the language which is making this even more complicated.
Here's what I have so far:
(define tree'("R" 100 999
(
("R" 100 199
(
("L" 120 140 160 180)
)
)
("R" 200 299
(
("L" 220 240 260 280)
)
)
)))
(define (treeTraversal a)
(if(equal? (null? a) #t) 0
(cdr (treeTraversal (cdr a)))))
(treeTraversal tree)
When I run it via debugger it shows that it is going down the list first clipping that first "R" off then 100, then 999, but from there the list goes null and show's "()" in the debugger. After that I get the error:
mcdr: contract violation
expected: mpair?
given: 0
I understand that it is returning 0 because the function sees an empty list now but I don't understand why the list goes null instead of continuing to read into the nested list.
Any ideas and suggestions are appreciated. This is my first time posting a question so please be patient with me :)

(define (treeTraversal a)
(if (null? a)
#!null
(if (pair? a)
(cons (treeTraversal (car a))
(treeTraversal (cdr a)))
a)))
will traverse and duplicate your tree.

Related

Representing an amount of money with specific bills

I want to write a function in Racket which takes an amount of money and a list of specific bill-values, and then returns a list with the amount of bills used of every type to make the given amount in total. For example (calc 415 (list 100 10 5 2 1)) should return '(4 1 1 0 0).
I tried it this way but this doesn't work :/ I think I haven't fully understood what you can / can't do with set! in Racket, to be honest.
(define (calc n xs)
(cond ((null? xs) (list))
((not (pair? xs))
(define y n)
(begin (set! n (- n (* xs (floor (/ n xs)))))
(list (floor (/ y xs))) ))
(else (append (calc n (car xs))
(calc n (cdr xs))))))
Your procedure does too much and you use mutation which is uneccesary. If you split the problem up.
(define (calc-one-bill n bill)
...)
;; test
(calc-one-bill 450 100) ; ==> 4
(calc-one-bill 450 50) ; ==> 9
Then you can make:
(define (calc-new-n n bill amount)
...)
(calc-new-n 450 100 4) ; ==> 50
(calc-new-n 450 50 9) ; ==> 0
Then you can reduce your original implememntation like this:
(define (calc n bills)
(if (null? bills)
(if (zero? n)
'()
(error "The unit needs to be the last element in the bills list"))
(let* ((bill (car bills))
(amount (calc-one-bill n bill)))
(cons amount
(calc (calc-new-n n bill amount)
(cdr bills))))))
This will always choose the solution with fewest bills, just as your version seems to do. Both versions requires that the last element in the bill passed is the unit 1. For a more complex method, that works with (calc 406 (list 100 10 5 2)) and that potentially can find all combinations of solutions, see Will's answer.
This problem calls for some straightforward recursive non-deterministic programming.
We start with a given amount, and a given list of bill denominations, with unlimited amounts of each bill, apparently (otherwise, it'd be a different problem).
At each point in time, we can either use the biggest bill, or not.
If we use it, the total sum lessens by the bill's value.
If the total is 0, we've got our solution!
If the total is negative, it is invalid, so we should abandon this path.
The code here will follow another answer of mine, which finds out the total amount of solutions (which are more than one, for your example as well). We will just have to mind the solutions themselves as well, whereas the code mentioned above only counted them.
We can code this one as a recursive-backtracking procedure, calling a callback with each successfully found solution from inside the deepest level of recursion (tantamount to the most deeply nested loop in the nested loops structure created with recursion, which is the essence of recursive backtracking):
(define (change sum bills callback)
(let loop ([sum sum] [sol '()] [bills bills]) ; "sol" for "solution"
(cond
((zero? sum) (callback sol)) ; process a solution found
((< sum 0) #f)
((null? bills) #f)
(else
(apply
(lambda (b . bs) ; the "loop":
;; 1. ; either use the first
(loop (- sum b) (cons b sol) bills) ; denomination,
;; 2. ; or,
(loop sum sol bs)) ; after backtracking, don't!
bills)))))
It is to be called through e.g. one of
;; construct `the-callback` for `solve` and call
;; (solve ...params the-callback)
;; where `the-callback` is an exit continuation
(define (first-solution solve . params)
(call/cc (lambda (return)
(apply solve (append params ; use `return` as
(list return)))))) ; the callback
(define (n-solutions n solve . params) ; n assumed an integer
(let ([res '()]) ; n <= 0 gets ALL solutions
(call/cc (lambda (break)
(apply solve (append params
(list (lambda (sol)
(set! res (cons sol res))
(set! n (- n 1))
(cond ((zero? n) (break)))))))))
(reverse res)))
Testing,
> (first-solution change 406 (list 100 10 5 2))
'(2 2 2 100 100 100 100)
> (n-solutions 7 change 415 (list 100 10 5 2 1))
'((5 10 100 100 100 100)
(1 2 2 10 100 100 100 100)
(1 1 1 2 10 100 100 100 100)
(1 1 1 1 1 10 100 100 100 100)
(5 5 5 100 100 100 100)
(1 2 2 5 5 100 100 100 100)
(1 1 1 2 5 5 100 100 100 100))
Regarding how this code is structured, cf. How to generate all the permutations of elements in a list one at a time in Lisp? It creates nested loops with the solution being accessible in the innermost loop's body.
Regarding how to code up a non-deterministic algorithm (making all possible choices at once) in a proper functional way, see How to do a powerset in DrRacket? and How to find partitions of a list in Scheme.
I solved it this way now :)
(define (calc n xs)
(define (calcAssist n xs usedBills)
(cond ((null? xs) usedBills)
((pair? xs)
(calcAssist (- n (* (car xs) (floor (/ n (car xs)))))
(cdr xs)
(append usedBills
(list (floor (/ n (car xs)))))))
(else
(if ((= (- n (* xs (floor (/ n xs)))) 0))
(append usedBills (list (floor (/ n xs))))
(display "No solution")))))
(calcAssist n xs (list)))
Testing:
> (calc 415 (list 100 10 5 2 1))
'(4 1 1 0 0)
I think this is the first program I wrote when learning FORTRAN! Here is a version which makes no bones about using everything Racket has to offer (or, at least, everything I know about). As such it's probably a terrible homework solution, and it's certainly prettier than the FORTRAN I wrote in 1984.
Note that this version doesn't search, so it will get remainders even when it does not need to. It never gets a remainder if the lowest denomination is 1, of course.
(define/contract (denominations-of amount denominations)
;; split amount into units of denominations, returning the split
;; in descending order of denomination, and any remainder (if there is
;; no 1 denomination there will generally be a remainder).
(-> natural-number/c (listof (integer-in 1 #f))
(values (listof natural-number/c) natural-number/c))
(let handle-one-denomination ([current amount]
[remaining-denominations (sort denominations >)]
[so-far '()])
;; handle a single denomination: current is the balance,
;; remaining-denominations is the denominations left (descending order)
;; so-far is the list of amounts of each denomination we've accumulated
;; so far, which is in ascending order of denomination
(if (null? remaining-denominations)
;; we are done: return the reversed accumulator and anything left over
(values (reverse so-far) current)
(match-let ([(cons first-denomination rest-of-the-denominations)
remaining-denominations])
(if (> first-denomination current)
;; if the first denomination is more than the balance, just
;; accumulate a 0 for it and loop on the rest
(handle-one-denomination current rest-of-the-denominations
(cons 0 so-far))
;; otherwise work out how much of it we need and how much is left
(let-values ([(q r)
(quotient/remainder current first-denomination)])
;; and loop on the remainder accumulating the number of bills
;; we needed
(handle-one-denomination r rest-of-the-denominations
(cons q so-far))))))))

Stuck while writing a recursion function in racket beginner language?

So recently I learned recursive function and I am trying some exercise then I am just stuck.
Question is
list-nth-item, that consumes a list, (lst), and a natural number, (n), and
produces the n-th element in lst if exists, otherwise the function produces false. Note
that the first item is in index 0. For example: (list-nth-item (list 1 2 3) 0)produces 1
Here is my code
;;list-nth-item consumes list and a natural number
;;and produces the n-th element in the list or false
;;list-nth-item: List Nat -> (Anyof Any false)
(define (list-nth-item lst n)
(cond
[(empty? lst)false]
[(= n 0)(first lst)]
[else ????]))
(list-nth-item (list 1 2 3)2)--> should produce 3
I know thus is not a proper recursion, also when n = 0 it should produce first number in the list example (list-nth-item (list 1 2 3)0)should give1.
I am new to this just not getting how to form a recursion.
Think of list as a conveyor belt: you check if you arrived to your item (using you first case (= n 0)), and if not (else case) you just shift the belt by taking the tail of list (using cdr function) and repeating the process again.
This can be done like following:
(define (list-nth-item lst n)
(cond
[(empty? lst) #f]
[(zero? n) (car lst)]
[else (list-nth-item ; <-- repeats the process
(cdr lst) ; <-- shifts the "belt"
(sub1 n))])) ; <-- updates the number of steps to go
PS: this is already done by list-ref function.

Lisp recursive function missing base case on first call

I started programming with lisp yesterday so please excuse if I am making some really newbie mistake. I am trying to create a function which calculates the bell numbers using the bell triangle and my recursive triangle function is not working properly. I am also sure if I got my recursive triangle function working that my recursive bell function is somehow also broken.
When I test my triangle function I get the output:
(defun bell(l n)
(if(< n 1)(list 1))
(if (= n 1)(last l))
(bell (triangle (reverse l) (last l) (list-length l)) (- n 1))
)
(defun triangle(pL nL i)
(if(<= i 0)
(write "equals zero!")
(reverse nL)
)
(triangle pL (append (list (+ (nth i pL) (nth i nL))) nL) (- i 1))
)
(write (triangle '(1) '(1) 0))
=>
"equals zero!""equals zero!"
*** - NTH: -1 is not a non-negative integer
For some reason, it is printing my debug code twice even though the function should be meeting my base case on the first call.
For some reason, it is printing my debug code twice even though the function should be meeting my base case on the first call.
It is printed twice because if is not doing what you think it does. The first if test is true, therefore equals zero! is printed. After that, a recursive call to triangle function is invoked. The test is again true (-1 <= 0), so equals zero! is again printed. Finally, you get an error because nthcdr function is called with -1. I strongly recommend you a good lisp debugger. The one from Lispworks is pretty good.
I honestly don't get the logic of what you were trying to achieve with your code. so I wrote mine:
(defun generate-level (l &optional (result))
"given a list l that represents a triangle level, it generates the next level"
(if (null l) result
(if (null result)
(generate-level l (list (car (last l))))
(generate-level (cdr l) (append result
(list (+ (car l)
(car (last result)))))))))
(defun bell (levels &optional (l))
"generate a bell triangle with the number of labels given by the first parameter"
(unless (zerop levels)
(let ((to-print (if (null l) (list 1) (generate-level l))))
(print to-print)
(bell (1- levels) to-print))))
Things to understand the implementation:
&optional (parameter): this parameter is optional and nil by default.
append concatenates two lists. I'm using it to insert in the back of the list.
let ((to-print x)) creates a new variable binding (local variable) called to-print and initialized to x.
I almost forgot to mention how if works in common lisp:
(if (= x 1) y z) means if x is equal to 1 then return y, otherwise z.
Now if you call the function to create a Bell triangle of 7 levels:
CL-USER 9 > (bell 7)
(1)
(1 2)
(2 3 5)
(5 7 10 15)
(15 20 27 37 52)
(52 67 87 114 151 203)
(203 255 322 409 523 674 877)
NIL
It would be nicer to print it with the appropiate padding, like this:
1
1 2
2 3 5
5 7 10 15
15 20 27 37 52
52 67 87 114 151 203
203 255 322 409 523 674 877
but I left that as an exercise to the reader.
Your ifs don't have any effect. They're evaluated, and produce results, but then you discard them. Just like
(defun abc ()
'a
'b
'c)
would evaluate 'a and 'b to produce the symbols a and b, and then would evaluate 'c to produce the symbol c, which would then be returned. In the case of
(if(<= i 0)
(write "equals zero!") ; then
(reverse nL) ; else
)
you're comparing whether i is less than or equal to zero, and if it is, you print equals zero, and if it's not, you (non-destructively) reverse nL and discard the result. Then you finish the function by making a call to triangle. It seems like you probably want to return the reversed nL when i is less than or equal to zero. Use cond instead, since you can have multiple body forms, as in:
(cond
((<= i 0) (write ...) (reverse nL))
(t (triangle ...)))
You could also use if with progn to group the forms:
(if (<= i 0)
(progn
(write ...)
(reverse nL))
(triangle ...))
Your other function has the same problem. If you want to return values in those first cases, you need to use a form that actually returns them. For instance:
(if (< n 1)
(list 1)
(if (= n 1)
(last l)
(bell #| ... |#)))
More idiomatic would be cond, and using list rather than l, which looks a lot like 1:
(cond
((< n 1) (list 1))
((= n 1) (last list))
(t (bell #| ... |#)))
Thank you all for the explanations. I eventually arrived at the code below. I realized that the if block worked something like..
(if (condition) (execute statement) (else execute this statement))
(defun bell(l n)
(if (< n 2)(last l)
(bell (triangle l (last l) 0) (- n 1))
)
)
(defun triangle(pL nL i)
(if(= i (list-length pL)) nL
(triangle pL (append nL (list (+ (nth i pL) (nth i nL)))) (+ i 1))
)
)
(write (bell (list 1) 10))

scheme check-expect output record combined with record-procedures

i am currently programming in scheme and i have written the following record-procedures that records a creature (= kreatur in German) with the character traits strength (= stärke), knowledge (= wissen) and readiness to assume a risk (= risikobereitschaft), i defined two creatures named "ronugor" and "garnolaf" (the names are not my idea, its from a exercise i didn't come up with ;) ) and then i wrote a procedure to mix the character traits of these two creatures (strengh -5%, knowledge unchanged, readiness to assume a risk still 0) to receive a new creature named "ronulaf".
this is my code:
(: stärke (kreatur -> number))
(: wissen (kreatur -> number))
(: risikobereitschaft (kreatur -> number))
(define-record-procedures kreatur
make-kreatur
kreatur?
(stärke
wissen
risikobereitschaft))
; check-property (i kept this out of the posted code to shorten it)
;define the creatures garnolaf and ronugor
(: make-kreatur (number number number -> kreatur))
(define garnolaf
(make-kreatur 100 0 0))
(: make-kreatur (number number number -> kreatur))
(define ronugor
(make-kreatur 0 100 0))
;signaturen
(: garnolaf? (kreatur -> boolean))
(check-expect (garnolaf? garnolaf) #t)
(check-expect (garnolaf? ronugor) #f)
(define garnolaf?
(lambda (x)
(and (= (stärke x) 100)
(= (wissen x) 0)
(= (risikobereitschaft x) 0))))
(: ronugor? (kreatur -> boolean))
(check-expect (ronugor? garnolaf) #f)
(check-expect (ronugor? ronugor) #t)
(define ronugor?
(lambda (x)
(and (= (stärke x) 0)
(= (wissen x) 100)
(= (risikobereitschaft x) 0))))
;mixing of the creatures
(: ronulaf (kreatur kreatur -> kreatur))
;this is where i am missing a check-expect, i suppose
(define ronulaf
(lambda (r g)
(make-kreatur (* 0.95 (stärke g))
(wissen r)
0)))
the question i now have is how i can write a check-expect for the procedure ronulaf. i would write is somehow like this:
(check-expect (ronulaf ronugor garnolaf) #<record:kreatur 95.0 100 0>)
but it doesn't work. does anybody have a better idea for a check-expect?
thanks already!
eva
Notice how your garnolaf? and ronugor? procedures are written? Now write something similar for ronulaf. That's it!
Try this:
(check-expect (ronulaf ronugor garnolaf) (make-kreatur 95 100 0))
Not all objects representations can be feed into read and become that object. #< in the beginning makes it look like an evaluated procedure and it's the same for those.

Lisp: How to print out the recursive function to print each item in the list and sublist without quotes and return the number of items?

I want my function to print each item in the list and sublist without quotes and return the number of items. The output of the list also needs to be in order, but my function is printing in reverse. I'm not sure why, is there any reasons why? Any suggestions to how I can recursively count the number of items and return that number? In addition why is the last item printed is supposed to be 9.99 instead of 100.999?
Edit: Thanks for the help so far. Just last question: Is there a way to make any output like DAY to be in lower case (day), or is that something that can't be done?
My function:
(defun all-print (inlist)
(cond
((not (listp inlist))
(format t "Error, arg must be a list, returning nil")
())
((null inlist) 0)
((listp (car inlist))
(ffn (append (car inlist)(cdr inlist))))
(t
(format t "~a " (car inlist) (ffn (cdr inlist))))))
My output example:
CL-USER 1 > (all-print (list 5 "night" 3 (list 9 -10) (quote day) -5.9 (* 100.999)))
100.999 -5.9 DAY -10 9 3 night 5
NIL
What it's suppose to output example:
5 night 3 9 -10 day -5.9 9.99 ;print
8 ;returns
It looks like all-print is supposed to be called ffn, since it looks like those are supposed to be recursive calls. In the rest of this answer, I'm just going to use ffn since it's shorter.
Why the output is in reverse
At present, your final cond clause makes the recursive call before doing any printing, because your recursive call is an argument to format:
(format t "~a " (car inlist) (ffn (cdr inlist)))
; ------------ -----------------
; 3rd 4th
All the arguments to format, including the 4th in this case, are evaluated before format is called. The 4th argument here will print the rest of the list, and then format will finally print the first element of the list. Your last cond clause should do the printing, and then make the recursive call:
(cond
…
(t
(format t "~a " (car inlist))
(ffn (cdr inlist))))
Why you get 100.999 rather than 9.99
You're getting 100.999 in your output rather than 9.99 (or something close to it) because the value of (* 100.999) is simply the value of 100.999. I'm guessing that you wanted (* 10 0.999) (note the space between 10 and 0.99). That still won't be quite 9.99 because of floating point arithmetic, though, but it will be close.
How to get the number of elements printed
uselpa's answer provides a good solution here. If you're supposed to return the number of elements printed, then every return value from this function should be a number. You have four cases,
not a list — returning nil is not a great idea. If this can't return a number (e.g., 0), then signal a real error (e.g., with (error "~A is not a list" inlist).
inlist is empty — return 0 (you already do)
(car inlist) is a list — here you make a recursive call to ffn. Since the contract says that it will return a count, you're fine. This is one of the reasons that it's so important in the first case (not a list) that you don't return a non-number; the contract depends on every call that returns returning an number.
In the final case, you print one item, and then make a recursive call to ffn. That recursive call returns the number of remaining elements that are printed, and since you just printed one, you need to add one to it. Thus the final cond clause should actually be something like the following. (Adding one to something is so common that Common Lisp has a 1+ function.)
(cond
…
(t
(format t "~a " (car inlist))
(1+ (ffn (cdr inlist))))) ; equivalent to (+ 1 (ffn (cdr inlist)))
A more efficient solution
We've addressed the issues with your original code, but we can also ask whether there are better approaches to the problem.
Don't append
Notice that when you have input like ((a b c) d e f), you create the list (a b c d e f) and recurse on it. However, you could equivalently recurse on (a b c) and on (d e f), and add the results together. This would avoid creating a new list with append.
Don't check argument types
You're checking that the input is a list, but there's really not much need to do that. If the input isn't a list, then using list processing functions on it will signal a similar error.
A new version
This is somewhat similar to uselpa's answer, but I've made some different choices about how to handle certain things. I use a local function process-element to handle elements from each input list. If the element is a list, then we pass it to print-all recursively, and return the result of the recursive call. Otherwise we return one and print the value. (I used (prog1 1 …) to emphasize that we're returning one, and printing is just a side effect. The main part of print-all is a typical recursion now.
(defun print-all (list)
(flet ((process-element (x)
(if (listp x)
(print-all x)
(prog1 1
(format t "~A " x)))))
(if (endp list)
0
(+ (process-element (first list))
(print-all (rest list))))))
Of course, now that we've pulled out the auxiliary function, the iteration is a bit clearer, and we see that it's actually a case for reduce. You might even choose to do away with the local function, and just use a lambda function:
(defun print-all (list)
(reduce '+ list
:key (lambda (x)
(if (listp x)
(print-all x)
(prog1 1
(format t "~A " x))))))
Here's my suggestion on how to write this function:
(defun all-print (lst)
(if (null lst)
0 ; empty list => length is 0
(let ((c (car lst))) ; bind first element to c
(if (listp c) ; if it's a list
(+ (all-print c) (all-print (cdr lst))) ; recurse down + process the rest of the list
(progn ; else
(format t "~a " c) ; not a list -> print item, then
(1+ (all-print (cdr lst)))))))) ; add 1 and process the rest of the list
then
? (all-print (list 5 "night" 3 (list 9 -10) (quote day) -5.9 (* 100.999)))
5 night 3 9 -10 DAY -5.9 100.999
8

Resources