scheme recursion - recursion

I am trying to create a scheme recursive function deep_count that counts the sum of the numbers even if it's nested in sub lists.
(define deep_count
(lambda (xs)
(cond
((empty? xs) 0)
((list? (first xs)) (+
(deep_count (first xs))
(deep_count (rest xs))))
(else (+ 1 (deep_count (rest xs)))))))
(deep_count '(1 2 3 (4 5 6) ((7 8 9) 10 (11 (12 13)))))
But I am getting 13 instead of 91.
Whats wrong here?
EDIT: never mind, I know why.

There's a small mistake at the end. Change this:
(+ 1 (deep_count (rest xs)))
... For this, and you're all set:
(+ (first xs) (deep_count (rest xs)))

Related

How to return false if the number is not found in the list

So, I am trying to do this hw problem: write a function that takes two arguments, a list and a number, and the function returns the index of the leftmost occurrence of the number in the list. For example:
If '(1 2 3 3 4) and num = 3, then it returns 2
If '(3 2 3 3 4) and num = 3, then it returns 0
I was able to do that part but what if the number was never found? What if I want to return false when num is not found in the list? How do I do that?
Please remember, I am trying to do this in proper recursion, not tail recursion.
Here's my code.
(define (first_elt_occ lst num)
(cond
((null? lst) #f)
((eq? (car lst) num) 0)
(else
(+ 1 (first_elt_occ (cdr lst) num)))))
(first_elt_occ '(1 2 3 3 4) 3) ;2
(first_elt_occ '(3 2 3 3 4) 3) ;0
(first_elt_occ '(1 2 5 4 3) 3) ;4
(first_elt_occ '(1 2 5 4 3) 6) ;Error
;(makes sense because you can't add boolean expression)
Another question I have is, how would I approach this problem, if I was asked to return the index of the rightmost occurrence of the number in a list (proper recursion). For example: '(3 4 5 4 3 7 ), num = 3 returns 4.
Thank you!
As suggested in the comments, this will be easier if we implement the procedure using tail recursion - by the way, tail recursion is "proper recursion", what makes you think otherwise?
By defining a helper procedure called loop and passing the accumulated result in a parameter, we can return either #f or the index of the element:
(define (first_elt_occ lst num)
(let loop ((lst lst) (acc 0))
(cond
((null? lst) #f)
((equal? (car lst) num) acc)
(else (loop (cdr lst) (add1 acc))))))
If, for some bizarre requirement you can't use tail recursion in your solution, it's possible to rewrite you original solution to account for the case when the answer is #f - but this isn't as elegant or efficient:
(define (first_elt_occ lst num)
(cond
((null? lst) #f)
((equal? (car lst) num) 0)
(else
(let ((result (first_elt_occ (cdr lst) num)))
(if (not result) #f (add1 result))))))
Either way, it works as expected:
(first_elt_occ '(1 2 3 3 4) 3) ; 2
(first_elt_occ '(3 2 3 3 4) 3) ; 0
(first_elt_occ '(1 2 5 4 3) 3) ; 4
(first_elt_occ '(1 2 5 4 3) 6) ; #f
I don't recommend actually taking this approach because a normal tail-recursive implementation is a lot more efficient, simpler, and easier to understand, but you can use a continuation to short-circuit unwinding the call stack in the failure case:
(define (first_elt_occ lst num)
(call/cc
(lambda (return)
(letrec ((loop (lambda (lst)
(cond
((null? lst) (return #f))
((= (car lst) num) 0)
(else (+ 1 (loop (cdr lst))))))))
(loop lst)))))
The basic find first occurrence "skeleton" function is
(define (first_elt_occ lst num)
(and (not (null? lst))
(or (equal (car lst) num)
(first_elt_occ (cdr lst) num))))
This does not return index though. How to add it in?
(define (first_elt_occ lst num)
(and (not (null? lst))
(or (and (equal (car lst) num) 0)
(+ 1 (first_elt_occ (cdr lst) num)))))
Does it work? Not if the element isn't there! It'll cause an error then. How to fix that? Change the +, that's how!
(define (first_elt_occ lst num)
(let ((+ (lambda (a b) (if b (+ a b) b))))
(and (not (null? lst))
(or (and (= (car lst) num) 0)
(+ 1 (first_elt_occ (cdr lst) num))))))
And now it works as expected:
> (first_elt_occ '(1 2 3 3 4) 3)
2
> (first_elt_occ '(3 2 3 3 4) 3)
0
> (first_elt_occ '(3 2 3 3 4) 5)
#f
And to get your second desired function, we restructure it a little bit, into
(define (first_elt_occ lst num)
(let ((+ (lambda (a b) ...... )))
(and (not (null? lst))
(+ (and (= (car lst) num) 0)
(first_elt_occ (cdr lst) num)))))
Now, what should that new + be? Can you finish this up? It's straightforward!
It's unclear why you are opposed to tail recursion. You talk about "proper recursion", which is not a technical term anyone uses, but I assume you mean non-tail recursion: a recursive process rather than an iterative one, in SICP terms. Rest assured that tail recursion is quite proper, and in general is preferable to non-tail recursion, provided one does not have to make other tradeoffs to enable tail recursion.
As Óscar López says, this problem really is easier to solve with tail recursion. But if you insist, it is certainly possible to solve it the hard way. You have to avoid blindly adding 1 to the result: instead, inspect it, adding 1 to it if it's a number, or returning it unchanged if it's false. For example, see the number? predicate.

racket: add a number to each element of nested list

I'm trying to write this function recursively. Please let me know if there's a library function for this in Racket documentation. Trying to add a number to every atomic element of a nested list. I'm guaranteed the list is only 2-deep
(define (add_to_all x li) (cond
((number? li) (+ li x))
((and (=(len li)1) (number?(car li))) (list (add_to_all x (car li))))
((=(len li)1) (add_to_all x (car li)))
(else (list (add_to_all x (car li)) `(,#(add_to_all x (cdr li)))))))
Example usage:
(define list_of_lists `((1 2 3)(4 5 6)))
(add_to_all 1 list_of_lists)
Bug: I'm getting too many nested lists at the end of my return value:
'((2 (3 (4))) (5 (6 (7))))
where it should be
'((2 3 4) (5 6 7))
I think the problem is in the last else condition block, but I'm not sure how to "unnest" that trailing part to get what I want
Whether the list is 2-deep or N-deep, it doesn't really matter, the algorithm can be the same.
(define (add-to-all x xs)
(cond ((null? xs)
null)
((list? (car xs))
(cons (add-to-all x (car xs))
(add-to-all x (cdr xs))))
(else
(cons (+ x (car xs))
(add-to-all x (cdr xs))))))
(add-to-all 10 '((1 2) (3 4) (5 (6 (7 8 9)))))
;; '((11 12) (13 14) (15 (16 (17 18 19))))
The procedure can be generalized to allow any operation to be performed on all atoms of a nested list
(define (map* f xs)
(cond ((null? xs)
null)
((list? (car xs))
(cons (map* f (car xs))
(map* f (cdr xs))))
(else
(cons (f (car xs))
(map* f (cdr xs))))))
(define (add-to-all x xs)
(map* (curry + x) xs))
(add-to-all 10 '((1 2) (3 4) (5 (6 (7 8 9)))))
;; '((11 12) (13 14) (15 (16 (17 18 19))))
There's a simpler way than recursion:
(define (add x li)
(for/list ([e li]) (+ x e)))
(define (add_to_all x li)
(map (lambda(sublist)(add x sublist))
li))
Usage:
(add_to_all 1 '((1 2 3)(4 5 6)))
If someone knows a library function for this operation, please answer as well
I think this problem can be generalized to "How do I map over nested lists?".
I am working off the assumption the procedure should also add numbers to top level elements, e.g.: (add-to-all 1 '(1 2 (3 4) 5)) yields '(2 3 (4 5) 6).
Here is a recursive solution based on the question:
(define (add-to-all x li)
(cond
[(number? li) (+ li x)]
[(list? li) (map (curry add-to-all x) li)]
[else li]))
A more generalized solution:
(define (map* proc ls)
(for/list ([elem ls])
(if (list? elem)
(map* proc elem)
(proc elem))))
(define (add-to-all x li)
(define (proc e)
(if (number? e)
(+ x e)
e))
(map* proc li))
I didn't see a procedure like map* in the standard Racket library, but I only looked for several minutes :).

0/1 Knapsack in Scheme

Am in on the right track for programming the knapsack problem in scheme? My program doesn't have to account for objects "values" , only their weights. The goal is to take the best combination of items so that I have approximately half of the weight in my bag.
(define (split-equip wlst)
(define (sum lst)
(define (sum-h accum lst1)
(if (null? lst)
(/ accum (length lst))
(sum-h (+ (car lst1) accum) (cdr lst1))))
(sum-h 0 lst))
(define (split-equip-h)
(let ((target-w (/ (sum wlst) 2)))
I am tempted to write my program to output a list with all of the different combinations of weights possible and then traversing the list until I find the best set of weights, but not sure how to implement this.
Since this is already your second attempt at this (the first question was deleted), I'll show you a solution in Racket. You should read it like pseudo-code and translate it into the Scheme variant you have been taught.
Disclaimer: I suck at these kind of exercises. That should be another reason for you to understand and reformulate this. But the results of my code still seem correct.
Here's the code:
#lang racket
(define (knapsack lst)
(define half (/ (apply + lst) 2)) ; compute half of total
(printf "list : ~a\nhalf : ~a\n" lst half)
(define (combs lst1 (lst2 null)) ; compute all the combinations
(if (null? lst1)
(if (null? lst2)
null
(list (reverse lst2)))
(append
(combs (cdr lst1) lst2) ; case 1 -> we don't carry the iten
(combs (cdr lst1) (cons (car lst1) lst2))))) ; case 2 -> we do
(for/fold ((delta half) (res null)) ((c (in-list (combs lst)))) ; determine the best fit
(let* ((sm (apply + c)) (newdelta (abs (- half sm))))
(cond
((< newdelta delta) (values newdelta (list c)))
((= newdelta delta) (values delta (cons c res)))
(else (values delta res))))))
(time
(let-values (((delta res) (knapsack (cdr (range 0 24 3)))))
(printf "result: ~a\ndelta : ~a\n" res delta)))
and here's what it says:
list : (3 6 9 12 15 18 21)
half : 42
result: ((3 6 12 21) (3 6 15 18) (3 9 12 18) (3 18 21) (6 9 12 15) (6 15 21) (9 12 21) (9 15 18))
delta : 0
cpu time: 6 real time: 5 gc time: 0
Hope this helps. Don't hesitate to ask questions if there's something you don't get!

Finding the position of a number in a list

Hey guys, I have a homework question that's been frustrating me to no end! I'm supposed to create index-of-least that will take a non-empty list and return the index of the smallest number in the list. The index of the (car ls) = 0, index of the (car (cdr ls)) = 1, and so on.
A helper needs to be created that will keep track of the current-position, least-position, least-value, and list. So far, I have this program (that doesn't load) that shows the basic algorithm.. But I'm having a hard time keeping track of everything and putting it into chez scheme code.
(define index-helper
(lambda (ls current-position least-position least-value)
(if (> (car ls) least-value)
(add1 (car ls (cdr ls (add1 current-position))))
(car ls (cdr ls (add1 current-position))))))
;trace
;ls: (4231) c-pos: 0 least-value: 5 least-pos: 0
;ls: (231) c-pos: 1 least-value: 4 least-pos: 1
;ls: (31) c-pos 2 least-value: 2 least-pos: 2
;ls: 1 c-pos: 3 l-v: 2 l-pos: 2
;ls '() c-pos: 4 l-v: 1 l-pos: 4
;*least-position = current-position
I already googled this and found similar questions in python, but I don't understand the code because I'm new to programming. :P
If anyone can give me a hint, I'd really appreciate it!
You want two functions. The first function find the least element x. The second function finds the index of the element x in the list.
Something like:
(define (find-least xs)
(foldl (lambda (e acc) (min e acc)) (car xs) xs))
(define (elem-index x xs)
(define (elem-index-find x xs ind)
(cond
((empty? xs) ind)
((eq? x (car xs))
ind)
(else (elem-index-find x (cdr xs) (+ ind 1)))))
(if (empty? xs)
(error "empty list")
(elem-index-find x xs 0)))
(define (index-of-least xs)
(let ((least (find-least xs)))
(elem-index least xs)))
Test:
> (index-of-least (list 5 8 4 9 1 3 7 2))
4
Or, in one pass:
(define (index-of-least-1-pass xs)
(define (index-do least ind-least ind xs)
(cond
((empty? xs) ind-least)
((< (car xs) least)
(index-do (car xs) (+ ind 1) (+ ind 1) (cdr xs)))
(else
(index-do least ind-least (+ ind 1) (cdr xs)))))
(index-do (car xs) 0 0 (cdr xs)))
Test:
> (index-of-least-1-pass (list 5 8 4 9 1 3 7 2))
4
In index-do helper function first you check if the intermediate list is empty; this is a base case, when we have got just one element int the list, and return its index.
Next condition checks if the next element of the intermediate list is greater than the current least value, and if so, we call helper with the new value of least and its index.
The last condition is selected, when the next element is not greater than the least, and it calls the helper function with the same values of least and ind-least, and the intermediate list with head element removed until there are no elements in the list, and we approached the base case, when there are no elements in the list.
A good example for named let:
(define (index-of-least xs)
(let loop ((i 0) (p 0) (x (car xs)) (xs (cdr xs)))
(cond ((null? xs) p)
((< (car xs) x) (loop (+ i 1) (+ i 1) (car xs) (cdr xs)))
(else (loop (+ i 1) p x (cdr xs))))))
(index-of-least (list 5 8 4 9 1 3 7 2)) => 4

How do you properly compute pairwise differences in Scheme?

Given a list of numbers, say, (1 3 6 10 0), how do you compute differences (xi - xi-1), provided that you have x-1 = 0 ?
(the result in this example should be (1 2 3 4 -10))
I've found this solution to be correct:
(define (pairwise-2 f init l)
(first
(foldl
(λ (x acc-data)
(let ([result-list (first acc-data)]
[prev-x (second acc-data)])
(list
(append result-list (list(f x prev-x)))
x)))
(list empty 0)
l)))
(pairwise-2 - 0 '(1 3 6 10 0))
;; => (1 2 3 4 -10)
However, I think there should be more elegant though no less flexible solution. It's just ugly.
I'm new to functional programming and would like to hear any suggestions on the code.
Thanks.
map takes multiple arguments. So I would just do
(define (butlast l)
(reverse (cdr (reverse l))))
(let ((l '(0 1 3 6 10)))
(map - l (cons 0 (butlast l)))
If you want to wrap it up in a function, say
(define (pairwise-call f init l)
(map f l (cons init (butlast l))))
This is of course not the Little Schemer Way, but the way that avoids writing recursion yourself. Choose the way you like the best.
I haven't done scheme in dog's years, but this strikes me as a typical little lisper type problem.
I started with a base definition (please ignore misplacement of parens - I don't have a Scheme interpreter handy:
(define pairwise-diff
(lambda (list)
(cond
((null? list) '())
((atom? list) list)
(t (pairwise-helper 0 list)))))
This handles the crap cases of null and atom and then delegates the meat case to a helper:
(define pairwise-helper
(lambda (n list)
(cond
((null? list) '())
(t
(let ([one (car list)])
(cons (- one n) (pairwise-helper one (cdr list))))
))))
You could rewrite this using "if", but I'm hardwired to use cond.
There are two cases here: null list - which is easy and everything else.
For everything else, I grab the head of the list and cons this diff onto the recursive case. I don't think it gets much simpler.
After refining and adapting to PLT Scheme plinth's code, I think nearly-perfect solution would be:
(define (pairwise-apply f l0 l)
(if (empty? l)
'()
(let ([l1 (first l)])
(cons (f l1 l0) (pairwise-apply f l1 (rest l))))))
Haskell tells me to use zip ;)
(define (zip-with f xs ys)
(cond ((or (null? xs) (null? ys)) null)
(else (cons (f (car xs) (car ys))
(zip-with f (cdr xs) (cdr ys))))))
(define (pairwise-diff lst) (zip-with - (cdr lst) lst))
(pairwise-diff (list 1 3 6 10 0))
; gives (2 3 4 -10)
Doesn't map finish as soon as the shortest argument list is exhausted, anyway?
(define (pairwise-call fun init-element lst)
(map fun lst (cons init-element lst)))
edit: jleedev informs me that this is not the case in at least one Scheme implementation. This is a bit annoying, since there is no O(1) operation to chop off the end of a list.
Perhaps we can use reduce:
(define (pairwise-call fun init-element lst)
(reverse (cdr (reduce (lambda (a b)
(append (list b (- b (car a))) (cdr a)))
(cons (list init-element) lst)))))
(Disclaimer: quick hack, untested)
This is the simplest way:
(define (solution ls)
(let loop ((ls (cons 0 ls)))
(let ((x (cadr ls)) (x_1 (car ls)))
(if (null? (cddr ls)) (list (- x x_1))
(cons (- x x_1) (loop (cdr ls)))))))
(display (equal? (solution '(1)) '(1))) (newline)
(display (equal? (solution '(1 5)) '(1 4))) (newline)
(display (equal? (solution '(1 3 6 10 0)) '(1 2 3 4 -10))) (newline)
Write out the code expansion for each of the example to see how it works.
If you are interested in getting started with FP, be sure to check out How To Design Program. Sure it is written for people brand new to programming, but it has tons of good FP idioms within.
(define (f l res cur)
(if (null? l)
res
(let ((next (car l)))
(f (cdr l) (cons (- next cur) res) next))))
(define (do-work l)
(reverse (f l '() 0)))
(do-work '(1 3 6 10 0))
==> (1 2 3 4 -10)

Resources