How to rewrite recursive procedure (repeated f n) as an iterative process using Racket? - iteration

This is what I have for recursive procedure (repeated f n) that applies the function f n times to an argument:
(define (repeated f count)
(if (= count 1)
f
(lambda (x)
(f ((repeated f (- count 1)) x)))))
E.g. ((repeated sqr 3) 2) returns 256, i.e. (sqr(sqr(sqr 2))).
But I have no idea how to implement repeated as an iterative process using Racket. Any advice is much obliged.

A typical solution for converting a recursive process to an iterative process is to enlist the aid of an accumulator.
Any way you slice it, repeated will have to return a procedure. One solution would use a named let inside the returned procedure that iterates n times, keeping track of the results in an accumulator. Here is a version of repeated that returns a unary procedure; note that there is no input validation here, so calls like ((repeated f 0) 'arg) will lead to trouble.
(define (repeated f n)
(lambda (x)
(let iter ((n n)
(acc x))
(if (= n 1) (f acc)
(iter (- n 1)
(f acc))))))
Named let expressions are very handy for things like this, but you could also define a helper procedure to do the same thing. I will leave that solution as an exercise for OP.
scratch.rkt> ((repeated sqr 3) 2)
256
scratch.rkt> ((repeated add1 8) 6)
14

I think using for/fold makes a cleaner solution
(define ((repeated f n) x)
(for/fold ([acc x]) ([i (in-range n)]) (f acc)))
Using it:
> ((repeated sqr 3) 2)
256
> ((repeated add1 8) 6)
14

Related

While loops working mechanism of a program in Scheme

DrRacket user.
I'm struggling to understand how this program works.I wrote it myself and it does what it must but I can't understand how.
I define while loops as:
(define (while test body)
(if (test)
(begin
(body)
(while test body))
(void)))
Now I need to write a program that applies the given procedure to each element of a mutable list.
Here what I wrote:
(define (mlist-map-while f x)
(while (lambda() (not (null? x)))
(lambda ()
(set-mcar! x (f (mcar x)))
(set! x (mcdr x))))
(void))
So, defining
list1 (mlist 1 2 3)
and applying
(mlist-map-while (lambda (x) (+ x 1)) list1)
we get '(2 3 4).
The thing that I don't understand is how the first element of the list stays in it, because if it's done how I wrote here
(set! x (mcdr x))
the first procedure that sets -mcar! must be useless and be overlapped with the second. Like in this example:
(define list1 (mlist 1 2 3))
(set-mcar! list1 9)
(set-mcdr! list1 (mcdr list!))
and we lack the first element, but this program somehow leaves it in and gives the desired output. I would like to know how it works and whether there is another way of traversing the given list.
There is a big difference between set-cdr! abd set!. The first alters the pair's cdr pointer, while the latter alters the binding, thus what the name should point to.
In your mlist-map-while the variable x alters the car, then changes what x represents, to be the cdr of x. It never changes the cdr so your binding list1 always points to the first pair while x points to the first, then second, etc...
Thus it's more like this:
(define list1 (mlist 1 2 3))
(define list1-ref list1) ; variable pointing to the same value as list1
(set-mcar! list1-ref 9) ; set-car! changes the pair
(set! list1-ref (mcdr list)) ; set! updates what list1-ref points to
list1 ; ==> (9 2 3)
list-ref ; ==> (2 3)
You can iterate over a list in the same fashion without using set!, with recursion:
(define (fold function init lst)
(if (null? lst)
init
(fold function
(function (car lst) init)
(cdr lst))))
(fold + 0 '(1 2 3)
; ==> 6
(fold cons '() '(1 2 3))
; ==> (3 2 1)
Notice that here we recurse and change what lst is, to be the cdr. Every recursion has its own lst, which is not to be confused with the caller's own. It ends up doing the same as set! in your example, without mutation.

SICP - Is my recursive definition of an iterative process for factorial bad?

I am studying the awesome book SICP. Despite being great, it is a really tough book. I am having problems with the long tail recursion,id est, a recursion definition for an iterative process.
The book presents this iterative procedure for factorial:
(define (factorial n)
(fact-iter 1 1 n))
(define (fact-iter product counter max-count)
(if (> counter max-count)
product
(fact-iter (* counter product)
(+ counter 1)
max-count)))
I tried doing one approach without looking at the book example. I got this:
(define (factorial n)
(factorial-iter n 1 n))
(define (factorial-iter a product counter)
(if (= counter 0)
product
(factorial-iter (- a 1)
(* product a)
(- counter 1))))
Is my approach wrong in some sense?
There is nothing wrong in your approach, it calculates correctly the factorial, there is only something superfluous. You can note that the two variables a and counter have always the same value since they are updated always in the same way. So you can get rid of one of them, and simplify your function in this way:
(define (factorial n)
(factorial-iter n 1))
(define (factorial-iter a product)
(if (= a 0)
product
(factorial-iter (- a 1)
(* product a))))
Finally, to stay on the safe side, you can change the test for the termination to see if a is less than or equal to 0, so the function will not loop endless with a negative argument:
(define (factorial-iter a product)
(if (<= a 0)
product
(factorial-iter (- a 1)
(* product a))))

What's wrong with my tail-recursive sum procedure?

What's wrong with my tail-recursive sum procedure? My tail-recursive scheme procedure will not run.
Code:
(define (sum term a next b)
(define iter result i)
(if (> i b)
result
(iter (+ result (term i)) (next i))
(iter 0 a )))
(define (increment x)(+ x 1))
(define (sum-square a b)
(sum (lambda(x)(* x x)) a increment b))
(define (sum-int a b)
(define (identity a) a)
(sum identity a increment b))
(sum-int 5 10)
(sum-square 5 10)
Error:
Error: execute: unbound symbol: "result" [sum-int, (anon), sum, (anon), sum-square, sum, (anon)]
You have parentheses problems in sum. Try this:
(define (sum term a next b)
(define (iter result i)
(if (> i b)
result
(iter (+ result (term i)) (next i))))
(iter 0 a))
In particular, notice that this line was wrong, that's not how you define a procedure:
(define iter result i)
And the corresponding closing parentheses is wrong, too. A strict discipline of correctly indenting and formatting the code will make these kind of errors easier to catch, use a good IDE for this.

Using local variables in scheme

I have been asked to translate a couple of C functions to scheme for an assignment. My professor very briefly grazed over how Scheme works, and I am finding it difficult to understand. I want to create a function that checks to see which number is greater than the other, then keeps checking every time you input a new number. The issue I am having is with variable declaration. I don't understand how you assign a value to an id.
(define max 1)
(define (x x)
(let maxfinder [(max max)]
(if (= x 0)
0
(if (> max x)
max
((= max x) maxfinder(max))))))
The trouble I keep running into is that I want to initialize max as a constant, and modify x. In my mind this is set up as an infinite loops with an exit when x = 0. If max is > x, which it should not be for the first time through, then set max = to x, and return x. I don't know what to do with the constant max. I need it to be a local variable. Thanks
Parenthesis use is very strict. Besides special forms they are used to call procedures. eg (> max x) calls procedure > with arguments max and x. ((if (> x 3) - +) 6 x) is an example where the if form returns a procedure and the result is called.
((= max x) ...) evaluates (= max x) and since the result is not a procedure it will fail.
maxfinder without parenthesis is just a procedure object.
(max) won't work since max is a number, not a procedure.
As for you problem. You add the extra variables you need to change in the named let. Eg. a procedure that takes a number n and makes a list with number 0-n.
(define (make-numbered-list n)
(let loop ((n n) (acc '()))
(if (zero? n)
acc
(loop (- n 1) (cons n acc)))))
Local variables are just locally bound symbols. This can be rewritten
(define (make-numbered-list n)
(define (loop n acc)
(if (zero? n)
acc
(loop (- n 1) (cons n acc))))
(loop n '()))
Unlike Algol dialects like C you don't mutate variables in a loop, but use recusion to alter them.
Good luck
If i understand you correctly, you are looking for the equivalent of a C function's static variable. This is called a closure in Scheme.
Here's an example implementation of a function you feed numbers to, and which will always return the current maximum:
(define maxfinder
(let ((max #f)) ; "static" variable, initialized to False
(lambda (n) ; the function that is defined
(when (or (not max) (< max n)) ; if no max yet, or new value > max
(set! max n)) ; then set max to new value
max))) ; in any case, return the current max
then
> (maxfinder 1)
1
> (maxfinder 10)
10
> (maxfinder 5)
10
> (maxfinder 2)
10
> (maxfinder 100)
100
So this will work, but provides no mechanism to reuse the function in a different context. The following more generalised version instantiates a new function on every call:
(define (maxfinder)
(let ((max #f)) ; "static" variable, initialized to False
(lambda (n) ; the function that is returned
(when (or (not max) (< max n)) ; if no max yet, or new value > max
(set! max n)) ; then set max to new value
max))) ; in any case, return the current max
use like this:
> (define max1 (maxfinder)) ; instantiate a new maxfinder
> (max1 1)
1
> (max1 10)
10
> (max1 5)
10
> (max1 2)
10
> (max1 100)
100
> (define max2 (maxfinder)) ; instantiate a new maxfinder
> (max2 5)
5
Define a function to determine the maximum between two numbers:
(define (max x y)
(if (> x y) x y))
Define a function to 'end'
(define end? zero?)
Define a function to loop until end? computing max
(define (maximizing x)
(let ((input (begin (display "number> ") (read))))
(cond ((not (number? input)) (error "needed a number"))
((end? input) x)
(else (maximizing (max x input))))))
Kick it off:
> (maximizing 0)
number> 4
number> 1
number> 7
number> 2
number> 0
7

SICP making change

So; I'm a hobbyist who's trying to work through SICP (it's free!) and there is an example procedure in the first chapter that is meant to count the possible ways to make change with american coins; (change-maker 100) => 292. It's implemented something like:
(define (change-maker amount)
(define (coin-value n)
(cond ((= n 1) 1)
((= n 2) 5)
((= n 3) 10)
((= n 4) 25)
((= n 5) 50)))
(define (iter amount coin-type)
(cond ((= amount 0) 1)
((or (= coin-type 0) (< amount 0)) 0)
(else (+ (iter amount
(- coin-type 1))
(iter (- amount (coin-value coin-type))
coin-type)))))
(iter amount 5))
Anyway; this is a tree-recursive procedure, and the author "leaves as a challenge" finding an iterative procedure to solve the same problem (ie fixed space). I have not had luck figuring this out or finding an answer after getting frustrated. I'm wondering if it's a brain fart on my part, or if the author's screwing with me.
The simplest / most general way to eliminate recursion, in general, is to use an auxiliary stack -- instead of making the recursive calls, you push their arguments into the stack, and iterate. When you need the result of the recursive call in order to proceed, again in the general case, that's a tad more complicated because you're also going to have to be able to push a "continuation request" (that will come off the auxiliary stack when the results are known); however, in this case, since all you're doing with all the recursive call results is a summation, it's enough to keep an accumulator and, every time you get a number result instead of a need to do more call, add it to the accumulator.
However, this, per se, is not fixed space, since that stack will grow. So another helpful idea is: since this is a pure function (no side effects), any time you find yourself having computed the function's value for a certain set of arguments, you can memoize the arguments-result correspondence. This will limit the number of calls. Another conceptual approach that leads to much the same computations is dynamic programming [[aka DP]], though with DP you often work bottom-up "preparing results to be memoized", so to speak, rather than starting with a recursion and working to eliminate it.
Take bottom-up DP on this function, for example. You know you'll repeatedly end up with "how many ways to make change for amount X with just the smallest coin" (as you whittle things down to X with various coin combinations from the original amount), so you start computing those amount values with a simple iteration (f(X) = X/value if X is exactly divisible by the smallest-coin value value, else 0; here, value is 1, so f(X)=X for all X>0). Now you continue by computing a new function g(X), ways to make change for X with the two smallest coins: again a simple iteration for increasing X, with g(x) = f(X) + g(X - value) for the value of the second-smallest coin (it will be a simple iteration because by the time you're computing g(X) you've already computed and stored f(X) and all g(Y) for Y < X -- of course, g(X) = 0 for all X <= 0). And again for h(X), ways to make change for X with the three smallest coins -- h(X) = g(X) + g(X-value) as above -- and from now on you won't need f(X) any more, so you can reuse that space. All told, this would need space 2 * amount -- not "fixed space" yet, but, getting closer...
To make the final leap to "fixed space", ask yourself: do you need to keep around all values of two arrays at each step (the one you last computed and the one you're currently computing), or, only some of those values, by rearranging your looping a little bit...?
Here is my version of the function, using dynamic programming. A vector of size n+1 is initialized to 0, except that the 0'th item is initially 1. Then for each possible coin (the outer do loop), each vector element (the inner do loop) starting from the k'th, where k is the value of the coin, is incremented by the value at the current index minus k.
(define (counts xs n)
(let ((cs (make-vector (+ n 1) 0)))
(vector-set! cs 0 1)
(do ((xs xs (cdr xs)))
((null? xs) (vector-ref cs n))
(do ((x (car xs) (+ x 1))) ((< n x))
(vector-set! cs x (+ (vector-ref cs x)
(vector-ref cs (- x (car xs)))))))))
> (counts '(1 5 10 25 50) 100)
292
You can run this program at http://ideone.com/EiOVY.
So, in this thread, the original asker of the question comes up with a sound answer via modularization. I would suggest, however, that his code can easily be optimized if you notice that cc-pennies is entirely superfluous (and by extension, so is cc-nothing)
See, the problem with the way cc-pennies is written is that, because there's no lower denomination to go, all it will do by mimicking the structure of the higher denomination procedures is iterate down from (- amount 1) to 0, and it will do this every time you pass it an amount from the cc-nickels procedure. So, on the first pass, if you try 1 dollar, you will get an amount of 100, so (- amount 1) evaluates to 99, which means you'll undergo 99 superfluous cycles of the cc-pennies and cc-nothing cycle. Then, nickels will pass you 95 as amount, so you get 94 more wasted cycles, so on and so forth. And that's all before you even move up the tree to dimes, or quarters, or half-dollars.
By the time you get to cc-pennies, you already know you just want to up the accumulator by one, so I'd suggest this improvement:
(define (count-change-iter amount)
(cc-fifties amount 0))
(define (cc-fifties amount acc)
(cond ((= amount 0) (+ 1 acc))
((< amount 0) acc)
(else (cc-fifties (- amount 50)
(cc-quarters amount acc)))))
(define (cc-quarters amount acc)
(cond ((= amount 0) (+ 1 acc))
((< amount 0) acc)
(else (cc-quarters (- amount 25)
(cc-dimes amount acc)))))
(define (cc-dimes amount acc)
(cond ((= amount 0) (+ 1 acc))
((< amount 0) acc)
(else (cc-dimes (- amount 10)
(cc-nickels amount acc)))))
(define (cc-nickels amount acc)
(cond ((= amount 0) (+ 1 acc))
((< amount 0) acc)
(else (cc-nickels (- amount 5)
(cc-pennies amount acc)))))
(define (cc-pennies amount acc)
(+ acc 1))
Hope you found this useful.
The solution I came up with is to keep count of each type of coin you're using in a 'purse'
The main loop works like this; 'denom is the current denomination, 'changed is the total value of coins in the purse, 'given is the amount of change I need to make and 'clear-up-to takes all the coins smaller than a given denomination out of the purse.
#lang scheme
(define (sub changed denom)
(cond
((> denom largest-denom)
combinations)
((>= changed given)
(inc-combinations-if (= changed given))
(clear-up-to denom)
(jump-duplicates changed denom)) ;checks that clear-up-to had any effect.
(else
(add-to-purse denom)
(sub
(purse-value)
0
))))
(define (jump-duplicates changed denom)
(define (iter peek denom)
(cond
((> (+ denom 1) largest-denom)
combinations)
((= peek changed)
(begin
(clear-up-to (+ denom 1))
(iter (purse-value) (+ denom 1))))
(else
(sub peek (+ denom 1)))))
(iter (purse-value) denom))
After reading Alex Martelli's answer I came up with the purse idea but just got around to making it work
You can solve it iteratively with dynamic programming in pseudo-polynomial time.