How do I get out of this recursive function when n = -1? - recursion

The problem I have to solve is how many oranges are in a pyramid if each level has 2^n oranges. I think I have the basis for the solution, however this is an infinite recursion. How do I get out of this function when n has reached -1 and display the solution? This is in scheme.
I've used this to help me set up what I need:
(+ (expt 2 0) (+ (expt 2 1) (+ (expt 2 2) (expt 2 3))))
3 is arbitrary and I only used it to help me write out the solution
(define oranges
(lambda (n)
(+ (expt 2 n) (oranges(- n 1)))))
Running this will not work because it is an infinite loop.

When you're writing a recursive procedure, it's mandatory to have a base case: it's the exit point of the recursion, otherwise it'll loop infinitely. Ask yourself: when should my procedure end? what should I return in that case?
In your case is simple, you literally wrote the answer in the title: how should we handle the case when n = -1? (or -2, or -3...?) Just return a meaningful value! I'd suggest 0, because we're doing an addition.
Now, in your code ask with an if expression whether we're in a value when we should return, and then return 0 - otherwise do the recursive step, which will eventually reach the base case. This is what I mean:
(define oranges
(lambda (n)
(if (< n 0)
0
(+ (expt 2 n) (oranges (- n 1))))))
It works as expected:
(oranges 3)
=> 15

When you make a recursive function, there are different parts that are compulsory. You need the general case and the basic cases. You have forgotten the basic cases also known as exit condition. Your exit condition is n = 0, so your program will be:
(define (oranges n)
(cond [(= n 0) 1]
[else (+(expt 2 n)(oranges(- n 1)))]
)
)
Tested:
(oranges 1)
=> 3
(oranges 0)
=> 1
(oranges 2)
=> 7

Related

Why is my code getting stuck in a recursive call when a negative argument gets passed through?

I'm trying to implement a recursive procedure in Scheme that takes the square of the number without using multiplication by using the formula n^2=1+3+5+...+(n+n-1). The if(< n 0) statement is in case a negative number is the argument. I know I could easily just use abs but I wanted to try coding it without abs.
When (Square1 2) is called it returns the correct value, but when I called (Square1 -2) it gets stuck in the recursive call.
I think I managed to narrow it down to the Square1(+ n -1) being the cause of the problem, but I am not sure why this is causing a problem. I tried programming this using the same logic in Java and it seems that my logic is correct. This is my first functional language so there is probably something I am not understanding.
(define Square1
(lambda (n)
(if (= n 0)
0)
(if (< n 0)
(Square1 (* -1 n)))
(if (= n 1)
1
(+ (+ (+ n n) -1) (Square1 (+ n -1))))))
The problem is that the procedure gets stuck in the the second if, never reaching the base case because of the way your conditions are structured. We should split the problem in two parts: one procedure for checking the cases when n <= 0 and the other for performing the loop in the general case.
Be aware that in a Scheme procedure, only the result of the last expression gets returned - the other expressions are executed for sure, but their results ignored. In the case of an if expression, structure it so it always has an "else" part. Having said that, this should work:
(define (aux n)
(if (= n 1)
1
(+ (+ (+ n n) -1)
(aux (+ n -1)))))
(define (square1 n)
(if (= n 0)
0
(if (> n 0)
(aux n)
(aux (- n)))))
The above solution is correct, but not that idiomatic. We can do better!
The aux procedure should be internal to the main procedure, because it won't be used anywhere else
Instead of nesting ifs, it's nicer to use cond
We could use existing procedures for common task, like zero?, positive?, sub1
For efficiency, we should use tail recursion whenever possible
This is how a more idiomatic answer might look, it works the same as the first one:
(define (square1 n)
(define (aux n acc)
(if (= n 1)
acc
(aux (sub1 n) (+ acc (sub1 (+ n n))))))
(cond ((zero? n) 0)
((positive? n) (aux n 1))
(else (aux (- n) 1))))
Either way, it works as expected:
(square1 -4)
=> 16
(square1 -3)
=> 9
(square1 -2)
=> 4
(square1 -1)
=> 1
(square1 0)
=> 0
(square1 1)
=> 1
(square1 2)
=> 4
(square1 3)
=> 9
(square1 4)
=> 16

Square of Sums in racket/scheme

I am writing the square of sums in racket/scheme recursively. The code sums the numbers right, but it doesn't square it right. I don't know what I am doing wrong. If I pass 10, it should be 3025.
(define (squareOfSums n)
(if (= n 0)
0
(expt (+ n (squareOfSums (- n 1))) 2)))
You should do the squaring only once, at the end of the recursion. Currently, your code squares at every iteration. One way to solve this problem would be to separate the sum part into a helper procedure, and square the result of calling it. Like this:
(define (squareOfSums n)
(define (sum n)
(if (= n 0)
0
(+ n (sum (- n 1)))))
(sqr (sum n)))
Also, did you know that there's a formula to add all natural numbers up to n? This is a nicer solution, with no recursion needed:
(define (squareOfSums n)
(sqr (/ (* n (+ n 1)) 2)))
Either way, it works as expected:
(squareOfSums 10)
=> 3025
Here's a version which I think is idiomatic but which I hope no-one who knows any maths would write:
(define (square-of-sums n)
(let loop ([m n] [sum 0])
(if (> m 0)
(loop (- m 1) (+ sum m))
(* sum sum))))
Here's the version someone who knows some maths would write:
(define (square-of-sums n)
(expt (/ (* n (+ n 1)) 2) 2))
I wish people would not ask homework questions with well-known closed-form solutions: it's actively encouraging people to program badly.
If you start out with your function by writing out some examples, it will be easier to visualize how your function will work.
Here are three examples:
(check-expect (SquareOfSums 0) 0)
(check-expect (SquareOfSums 2) (sqr (+ 2 1))) ;9
(check-expect (SquareOfSums 10) (sqr (+ 10 9 8 7 6 5 4 3 2 1))) ;3025
As we can see clearly, there are two operators we are using, which should indicate that we need to use some sort of helper function to help us out.
We can start with out main function squareOfSums:
(define (squareOfSums n)
(sqr (sum n)))
Now, we have to create the helper function.
The amount of times that you use the addition operator depends on the number that you use. Because of this reason, we're going to have to use natural recursion.
The use of natural recursion requires some sort of base case in order for the function to 'end' somewhere. In this case, this is the value 0.
Now that we have identified the base case, we can create our helper function with little issue:
(define (sum n)
(if (= 0 n)
0
(+ n (sum (sub1 n)))))

Recursive function returns sum, struggling to understand why?

The following function was given to me on a review sheet:
(define mystery(lambda(m n)
(cond
((= m 0) n)
((= n 0) m)
(#t (+ 2(mystery(- m 1)(- n 1))))
)))
The first two conditions are simple, it's just the recursive otherwise that's confusing me. It just seems to me that the recursion will continue until they both equal zero, which certainly doesn't return the sum. Can someone provide an explanation?
First, let's format the code a bit better to see what's happening:
(define (mystery m n)
(cond ((= m 0) n)
((= n 0) m)
(else (+ 2 (mystery (- m 1) (- n 1))))))
Now, remember that a cond executes only the action corresponding to the first condition that is true (from top to bottom), the others are ignored. If none of the conditions is true, then the else part is executed. The important thing to remember is that only one action is executed.
In particular, your mystery procedure will stop when either m or n becomes zero, not when both become zero. When one of the two reaches zero, the recursion starts to unwind, returning the sum. You can see this when tracing the execution - for example, in Racket:
(require racket/trace)
(trace mystery)
(mystery 3 2)
>(mystery 3 2)
> (mystery 2 1)
> >(mystery 1 0)
< <1
< 3
<5
Just to elaborate on Óscar López's answer (I can't format this in a comment): I find that it's often useful to write these sorts of little recursive maths functions down as if they were maths:
Let m and n be natural numbers, then
n + m = n if m = 0;
n + m = m if n = 0;
n + m = n - 1 + m - 1 + 2;
there are no other cases.
I feel the best way is not to nest but to precompute. Looking at the base case we test with either zero:
(mystery 0 2) ; ==> 2
(nystery 3 0) ; ==> 3
Thus every time at least one argument is zero it returns the other argument. Lets try with a non zero value and remember the second you see a value we have already done before you just switch it with its result:
(mystery 1 3) ; ==
(+ 2 (mystery 0 2)) ; == (we switch known value)
(+ 2 2)
; ==> 4
(mystery 4 1) ; == (we substitute with the expression)
(+ 2 (mystery 3 0)) ; == (we switch known value)
(+ 2 3)
; ==> 5
Since we know the base case always returns the other value we don't need to precalculate it. Here is a go that does that:
(mystery 3 9) ; == (we substitute with the expression)
(+ 2 (mystery 2 8) ; == (we substitute with the expression)
(+ 2 (+ 2 (mystery 1 7))) ; == (we substitute with the expression)
(+ 2 (+ 2 (+ 2 (mystery 0 6))) ; == (we substitute with the expression, n, which is 6)
(+ 2 (+ 2 (+ 2 6))) ; == (we substitute (+ 2 6))
(+ 2 (+ 2 8)) ; == (we substitute (+ 2 8))
(+ 2 10) ; == (we substitute (+ 2 10)
; ==> 12
We can generalize what will happen. The lowest of n and m will decide when the recursion ends. At each step it will add 2 and recurse. Thus it is a fancy way of making:
(define (double-min n m)
(let ((vmin (min n m))
(vmax (max n m)))
(+ (* 2 vmin) (- vmax vmin))))
Which again is a fancy way of adding the two numbers since if n > m, then 2*m+(n-m) = m+m+(n-m) = m+n
(define mystery(lambda(m n)
(cond
((= m 0) n)
((= n 0) m)
(#t (+ 2 (mystery (- m 1) (- n 1))))
)))
First and second conditions are obvious.
Explanation of how the third statement is working:
1 each is taken out of m and n and kept as 2 outside this function.
This is continued till either m is 0 or n is 0.
The first 2 cases are obvious, the sum of 2 numbers where one of the numbers is 0, is equal to the other number.
In the last case, after checking the arguments for 0, we know for sure that both of them are non-0. Assuming that mystery returns the sum of its 2 arguments, then
(+ 2 (mystery (- arg1 1) (- arg2 1)))
will return a sum that is equal to (mystery arg1 arg2) and will eventually halt when one of the arguments is 0, returning the desired result.
Assuming that mystery returns the sum of its 2 arguments is key here and is called the recursive leap of faith. (Google it)

how can i call a function that takes an argument in racket?

I am still new in racket language.
I am implementing a switch case in racket but it is not working.
So, I shift into using the equal and condition. I want to know how can i call a function that takes input. for example: factorial(n) function
I want to call it in :
(if (= c 1) (factorial (n))
There are two syntax problems with this snippet:
(if (= c 1) (factorial (n)))
For starters, an if expression in Racket needs three parts:
(if <condition> <consequent> <alternative>)
The first thing to fix would be to provide an expression that will be executed when c equals 1, and another that will run if c is not equal to 1. Say, something like this:
(if (= c 1) 1 (factorial (n)))
Now the second problem: in Scheme, when you surround a symbol with parentheses it means that you're trying to execute a function. So if you write (n), the interpreter believes that n is a function with no arguments and that you're trying to call it. To fix this, simply remove the () around n:
(if (= c 1) 1 (factorial n))
Now that the syntax problems are out of the way, let's examine the logic. In Scheme, we normally use recursion to express solutions, but a recursion has to advance at some point, so it will eventually end. If you keep passing the same parameter to the recursion, without modifying it, you'll get caught in an infinite loop. Here's the proper way to write a recursive factorial procedure:
(define (factorial n)
(if (<= n 0) ; base case: if n <= 0
1 ; then return 1
(* n (factorial (- n 1))))) ; otherwise multiply and advance recursion
Notice how we decrement n at each step, to make sure that it will eventually reach zero, ending the recursion. Once you get comfortable with this solution, we can think of making it better. Read about tail recursion, see how the compiler will optimize our loops as long as we write them in such a way that the last thing done on each execution path is the recursive call, with nothing left to do after it. For instance, the previous code can be written more efficiently as follows, and see how we pass the accumulated answer in a parameter:
(define (factorial n)
(let loop ([n n] [acc 1])
(if (<= n 0)
acc
(loop (- n 1) (* n acc)))))
UPDATE
After taking a look at the comments, I see that you want to implement a switchcase procedure. Once again, there are problems with the way you're declaring functions. This is wrong:
(define fact(x)
The correct way is this:
(define (fact x)
And for actually implementing switchcase, it's possible to use nested ifs as you attempted, but that's not the best way. Learn how to use the cond expression or the case expression, either one will make your solution simpler. And anyway you have to provide an additional condition, in case c is neither 1 nor 2. Also, you're confounding the parameter name - is it c or x? With all the recommendations in place, here's how your code should look:
(define (switchcase c)
(cond ((= c 1) (fact c))
((= c 2) (triple c))
(else (error "unknown value" c))))
In racket-lang, conditionals with if has syntax:
(if <expr> <expr> <expr>)
So in your case, you have to provide another <expr>.
(define (factorial n)
(if (= n 1) 1 (* n (factorial (- n 1)))))
;^exp ^exp ^exp
(factorial 3)
The results would be 6
Update:
(define (factorial n)
(if (= n 1) 1 (* n (factorial (- n 1)))))
(define (triple x)
(* 3 x))
(define (switchcase c)
(if (= c 1)
(factorial c)
(if(= c 2)
(triple c) "c is not 1 or 2")))
(switchcase 2)
If you want something a lot closer to a switch case given you can return procedures.
(define (switch input cases)
(let ((lookup (assoc input cases)))
(if lookup
(cdr lookup)
(error "Undefined case on " input " in " cases))))
(define (this-switch c)
(let ((cases (list (cons 1 triple)
(cons 2 factorial))))
((switch c cases) c)))

How to improve this piece of code?

My solution to exercise 1.11 of SICP is:
(define (f n)
(if (< n 3)
n
(+ (f (- n 1)) (* 2 (f (- n 2))) (* 3 (f (- n 3))))
))
As expected, a evaluation such as (f 100) takes a long time. I was wondering if there was a way to improve this code (without foregoing the recursion), and/or take advantage of multi-core box. I am using 'mit-scheme'.
The exercise tells you to write two functions, one that computes f "by means of a recursive process", and another that computes f "by means of an iterative process". You did the recursive one. Since this function is very similar to the fib function given in the examples of the section you linked to, you should be able to figure this out by looking at the recursive and iterative examples of the fib function:
; Recursive
(define (fib n)
(cond ((= n 0) 0)
((= n 1) 1)
(else (+ (fib (- n 1))
(fib (- n 2))))))
; Iterative
(define (fib n)
(fib-iter 1 0 n))
(define (fib-iter a b count)
(if (= count 0)
b
(fib-iter (+ a b) a (- count 1))))
In this case you would define an f-iter function which would take a, b, and c arguments as well as a count argument.
Here is the f-iter function. Notice the similarity to fib-iter:
(define (f-iter a b c count)
(if (= count 0)
c
(f-iter (+ a (* 2 b) (* 3 c)) a b (- count 1))))
And through a little trial and error, I found that a, b, and c should be initialized to 2, 1, and 0 respectively, which also follows the pattern of the fib function initializing a and b to 1 and 0. So f looks like this:
(define (f n)
(f-iter 2 1 0 n))
Note: f-iter is still a recursive function but because of the way Scheme works, it runs as an iterative process and runs in O(n) time and O(1) space, unlike your code which is not only a recursive function but a recursive process. I believe this is what the author of Exercise 1.1 was looking for.
I'm not sure how best to code it in Scheme, but a common technique to improve speed on something like this would be to use memoization. In a nutshell, the idea is to cache the result of f(p) (possibly for every p seen, or possibly the last n values) so that next time you call f(p), the saved result is returned, rather than being recalculated. In general, the cache would be a map from a tuple (representing the input arguments) to the return type.
Well, if you ask me, think like a mathematician. I can't read scheme, but if you're coding a Fibonacci function, instead of defining it recursively, solve the recurrence and define it with a closed form. For the Fibonacci sequence, the closed form can be found here for example. That'll be MUCH faster.
edit: oops, didn't see that you said forgoing getting rid of the recursion. In that case, your options are much more limited.
See this article for a good tutorial on developing a fast Fibonacci function with functional programming. It uses Common LISP, which is slightly different from Scheme in some aspects, but you should be able to get by with it. Your implementation is equivalent to the bogo-fig function near the top of the file.
To put it another way:
To get tail recursion, the recursive call has to be the very last thing the procedure does.
Your recursive calls are embedded within the * and + expressions, so they are not tail calls (since the * and + are evaluated after the recursive call.)
Jeremy Ruten's version of f-iter is tail-recursive rather than iterative (i.e. it looks like a recursive procedure but is as efficient as the iterative equivalent.)
However you can make the iteration explicit:
(define (f n)
(let iter
((a 2) (b 1) (c 0) (count n))
(if (<= count 0)
c
(iter (+ a (* 2 b) (* 3 c)) a b (- count 1)))))
or
(define (f n)
(do
((a 2 (+ a (* 2 b) (* 3 c)))
(b 1 a)
(c 0 b)
(count n (- count 1)))
((<= count 0) c)))
That particular exercise can be solved by using tail recursion - instead of waiting for each recursive call to return (as is the case in the straightforward solution you present), you can accumulate the answer in a parameter, in such a way that the recursion behaves exactly the same as an iteration in terms of the space it consumes. For instance:
(define (f n)
(define (iter a b c count)
(if (zero? count)
c
(iter (+ a (* 2 b) (* 3 c))
a
b
(- count 1))))
(if (< n 3)
n
(iter 2 1 0 n)))

Resources