Recursive call from Condition Branch - recursion

I'm starting to get to grips with Lisp and I'm trying to write a procedure to approximate pi using the Leibniz formula at the moment; I think I'm close but I'm not sure how to proceed. The current behavior is that it makes the first calculation correctly but then the program terminates and displays the number '1'. I'm unsure if I can call a defined function recursively like this,
;;; R5RS
(define (pi-get n)
(pi 0 1 n 0))
(define (pi sum a n count)
;;; if n == 0, 0
(if (= n 0) 0)
;;; if count % 2 == 1, + ... else -, if count == n, sum
(cond ((< count n)
(cond ((= (modulo count 2) 1)
(pi (+ sum (pi-calc (+ 2 a))) (+ a 2) n (+ count 1)))
(pi
(- sum (pi-calc (+ 2 a))) (+ a 2) n (+ count 1))))))
(define (pi-calc a)
(/ 1.0 a))
Apologies if this is a little unreadable, I'm just learning Lisp a few weeks now and I'm not sure what normal formatting would be for the language. I've added a few comments to hopefully help.

As Sylwester mentioned it turned out to be a mistake on my part with syntax.
;;; R5RS
(define (pi-get n)
(pi 1 1 n 0))
(define (pi sum a n count)
(if (= n 0) 0)
(cond ((< count n)
(cond ((= (modulo count 2) 1)
(pi (+ sum (pi-calc (+ 2 a))) (+ a 2) n (+ count 1)))
((= (modulo count 2) 0)
(pi (- sum (pi-calc (+ 2 a))) (+ a 2) n (+ count 1))))
(display (* 4 sum)) (newline))))
(define (pi-calc a)
(/ 1.0 a))

Related

What is the required recursive function(s) in Scheme programming language to compute the following series?

what is the required recursive function(s) in Scheme programming language to compute the following series?? Explanation needed
1^2/2^1 + 3^4/4^3 + 5^6/6^5 + 7^8/8^7 + 9^10/10^9
So, well, what does each term look like? It's n^(n+1)/(n+1)^n. And you want to stop when you reach 10 (so if n > 10, stop). So write a function of a single argument, n, which either:
returns 0 if n > 10;
adds n^(n+1)/(n+1)^n to the result of calling itself on n + 2.
Then this function with argument 1 will compute what you want. Going backwards may be easier:
return 0 if n < 1;
add n^(n+1)/(n+1)^n to the result of calling itself on n - 2;
then the function with argument 10 is what you want.
Or you could do this which is more entertaining:
(define s
(λ (l)
((λ (c i a)
(if (> i l)
a
(c c
(+ i 2)
(+ a (/ (expt i (+ i 1))
(expt (+ i 1) i))))))
(λ (c i a)
(if (> i l)
a
(c c
(+ i 2)
(+ a (/ (expt i (+ i 1))
(expt (+ i 1) i))))))
1 0)))
But I don't recommend it.
//power function
(define (power a b)
(if (zero? b) //base case
1
(* a (power a (- b 1))))) //or return power of a,b
// sum function for series
(define (sum n)
(if (< n 3) //base case
0.5
(+ (/ (power (- n 1) n) (power n (- n 1))) (sum (- n 2 )) ))) //recursion call
>(sum 10) // call sum function here .

recursion in counting the ocurrences of a number

I have found a problem that it says it should be solved by using recursion. The question is that given a certain number it should count the number of 8s that are present in it, but if two 8s are one next to another it should be counted as double. For example:
48 should return 1
4881 should return 4
8818 should return 5
I have made the following program in Scheme:
(define (count n)
(if (= n 0)
0
(begin
(if (= (remainder n 100) 88)
2
(begin
(if (= (remainder n 10) 8)
1
0))
)
(+ (count (quotient n 10))))))
The problem is that everytime I run it returns 0, what am I missing? I do not want to use lists or set! for using an auxiliar variable. Any help?
You have to keep iterating whenever you find a match, and the sums don't seem right. Also, instead of nesting ifs it's better to use cond, like this:
(define (count n)
(cond ((= n 0) 0)
((= (remainder n 100) 88)
(+ 4 (count (quotient n 100))))
((= (remainder n 10) 8)
(+ 1 (count (quotient n 10))))
(else
(+ (count (quotient n 10))))))
It works with your examples:
(count 48)
=> 1
(count 4881)
=> 4
(count 8818)
=> 5
It would be better to count scans of 8s in a helper and keep a current number of hits and a total tally for previous scans.
(define (funny-eights n)
(define (aux n cur total)
(cond ((= (remainder n 10) 8)
(aux (quotient n 10) (+ cur 1) total))
((> cur 1)
(aux (quotient n 10) 0 (+ total (* 2 cur))))
((= cur 1)
(aux (quotient n 10) 0 (+ total cur)))
((> n 0)
(aux (quotient n 10) 0 total))
(else
total)))
(aux n 0 0))
(funny-eights 488838288) ; ==> 11 or 3*2 + 1 + 2*2

Rewrite code to be with less procedures in Scheme

I wrote a program, that given two numbers that specify a range, should return the number (count) of numbers in that range that represented in octal form consist of a number of identical digits. For example 72->111 meets this criteria, because all the digits are the same. Examples of output:
(hw11 1 8) -> 7,(hw11 1 9) -> 8,(hw11 1 18) -> 9,(hw11 1 65) -> 14, and so on...
My problem is that to be correct my program must define only 2 procedures, and at the moment I have much more than that and have no idea how to make them less. So any help with rewriting the code is welcomed :). The code is below:
(define (count-digits n)
(if (<= n 0)
0
(+ 1 (count-digits (quotient n 10)))))
(define (toOct n)
(define (helper n octNumber i)
(if(<= n 0)
octNumber
(helper (quotient n 8)
(+ octNumber
(* (expt 10 i)
(remainder n 8)))
(+ i 1))))
(helper n 0 0))
(define (samedigits n)
(define (helper n i)
(if (<= n 0)
#t
(if (not (remainder n 10) i))
#f
(helper (quotient n 10) i))))
(helper n (remainder n 10))
)
(define (hw11 a b)
(define (helper a x count)
(if (> a x)
count
(if (samedigits (toOct x))
(helper a (- x 1) (+ count 1))
(helper a (- x 1) count))))
(helper a b 0))
You probably have restrictions and you didn't state which Scheme implementation you're using; the following is an example that has been tested on Racket and Guile:
(define (hw11 a b)
(define (iter i count)
(if (<= i b)
(let* ((octal (string->list (number->string i 8)))
(allc1 (make-list (length octal) (car octal))))
(iter (+ i 1) (if (equal? octal allc1) (+ count 1) count)))
count))
(iter a 0))
Testing:
> (hw11 1 8)
7
> (hw11 1 9)
8
> (hw11 1 18)
9
> (hw11 1 65)
14

Can't seem to get this function to work in scheme

Here is what I have done so far:
(define sumOdd
(lambda(n)
(cond((> n 0)1)
((odd? n) (* (sumOdd n (-(* 2 n) 1)
output would look something like this:
(sumOdd 1) ==> 1
(sumOdd 4) ==> 1 + 3 + 5 + 7 ==> 16
(sumOdd 5) ==> 1 + 3 + 5 + 7 + 9 ==> 25
This is what I am trying to get it to do: find the sum of the first N odd positive integers
I can not think of a way to only add the odd numbers.
To elaborate further on the sum-odds problem, you might solve it in terms of more abstract procedures that in combination accumulates the desired answer. This isn't necessarily the easiest solution, but it is interesting and captures some more general patterns that are common when processing list structures:
; the list of integers from n to m
(define (make-numbers n m)
(if (= n m) (list n) ; the sequence m..m is (m)
(cons n ; accumulate n to
(make-numbers (+ n 1) m)))) ; the sequence n+1..m
; the list of items satisfying predicate
(define (filter pred lst)
(if (null? lst) '() ; nothing filtered is nothing
(if (pred (car lst)) ; (car lst) is satisfactory
(cons (car lst) ; accumulate item (car lst)
(filter pred (cdr lst))) ; to the filtering of rest
(filter pred (cdr lst))))) ; skip item (car lst)
; the result of combining list items with procedure
(define (build-value proc base lst)
(if (null? lst) base ; building nothing is the base
(proc (car lst) ; apply procedure to (car lst)
(build-value proc base (cdr lst))))) ; and to the building of rest
; the sum of n first odds
(define (sum-odds n)
(if (negative? n) #f ; negatives aren't defined
(build-value + ; build values with +
0 ; build with 0 in base case
(filter odd? ; filter out even numbers
(make-numbers 1 n))))) ; make numbers 1..n
Hope this answer was interesting and not too confusing.
Let's think about a couple of cases:
1) What should (sumOdd 5) return? Well, it should return 5 + 3 + 1 = 9.
2) What should (sumOdd 6) return? Well, that also returns 5 + 3 + 1 = 9.
Now, we can write this algorithm a lot of ways, but here's one way I've decided to think about it:
We're going to write a recursive function, starting at n, and counting down. If n is odd, we want to add n to our running total, and then count down by 2. Why am I counting down by 2? Because if n is odd, n - 2 is also odd. Otherwise, if n is even, I do not want to add anything. I want to make sure that I keep recursing, however, so that I get to an odd number. How do I get to the next odd number, counting down from an even number? I subtract 1. And I do this, counting down until n is <= 0. I do not want to add anything to my running total then, so I return 0. Here is what that algorithm looks like:
(define sumOdd
(lambda (n)
(cond ((<= n 0) 0)
((odd? n) (+ n (sumOdd (- n 2))))
(else (sumOdd (- n 1))))))
If it helps you, here is a more explicit example of a slightly different algorithm:
(define sumOdd
(lambda (n)
(cond ((<= n 0) 0)
((odd? n) (+ n (sumOdd (- n 1))))
((even? n) (+ 0 (sumOdd (- n 1))))))) ; note that (even? n) can be replaced by `else' (if its not odd, it is even), and that (+ 0 ..) can also be left out
EDIT:
I see that the problem has changed just a bit. To sum the first N positive odd integers, there are a couple of options.
First option: Math!
(define sumOdd (lambda (n) (* n n)))
Second option: Recursion. There are lots of ways to accomplish this. You could generate a list of 2*n and use the procedures above, for example.
You need to have 2 variables, one which keep counter of how many odd numbers are still to be added and another to hold the current odd number which gets increment by 2 after being used in addition:
(define (sum-odd n)
(define (proc current start)
(if (= current 0)
0
(+ start (proc (- current 1) (+ start 2)) )))
(proc n 1))
Here is a nice tail recursive implementation:
(define (sumOdd n)
(let summing ((total 0) (count 0) (next 1))
(cond ((= count n) total)
((odd? next) (summing (+ total next)
(+ count 1)
(+ next 1)))
(else (summing total count (+ next 1))))))
Even shorter tail-recursive version:
(define (sumOdd n)
(let loop ((sum 0) (n n) (val 1))
(if (= n 0)
sum
(loop (+ sum val) (- n 1) (+ val 2)))))

Recursing in a lambda function

I have the following 2 functions that I wish to combine into one:
(defun fib (n)
(if (= n 0) 0 (fib-r n 0 1)))
(defun fib-r (n a b)
(if (= n 1) b (fib-r (- n 1) b (+ a b))))
I would like to have just one function, so I tried something like this:
(defun fib (n)
(let ((f0 (lambda (n) (if (= n 0) 0 (funcall f1 n 0 1))))
(f1 (lambda (a b n) (if (= n 1) b (funcall f1 (- n 1) b (+ a b))))))
(funcall f0 n)))
however this is not working. The exact error is *** - IF: variable F1 has no value
I'm a beginner as far as LISP goes, so I'd appreciate a clear answer to the following question: how do you write a recursive lambda function in lisp?
Thanks.
LET conceptually binds the variables at the same time, using the same enclosing environment to evaluate the expressions. Use LABELS instead, that also binds the symbols f0 and f1 in the function namespace:
(defun fib (n)
(labels ((f0 (n) (if (= n 0) 0 (f1 n 0 1)))
(f1 (a b n) (if (= n 1) b (f1 (- n 1) b (+ a b)))))
(f0 n)))
You can use Graham's alambda as an alternative to labels:
(defun fib (n)
(funcall (alambda (n a b)
(cond ((= n 0) 0)
((= n 1) b)
(t (self (- n 1) b (+ a b)))))
n 0 1))
Or... you could look at the problem a bit differently: Use Norvig's defun-memo macro (automatic memoization), and a non-tail-recursive version of fib, to define a fib function that doesn't even need a helper function, more directly expresses the mathematical description of the fib sequence, and (I think) is at least as efficient as the tail recursive version, and after multiple calls, becomes even more efficient than the tail-recursive version.
(defun-memo fib (n)
(cond ((= n 0) 0)
((= n 1) 1)
(t (+ (fib (- n 1))
(fib (- n 2))))))
You can try something like this as well
(defun fib-r (n &optional (a 0) (b 1) )
(cond
((= n 0) 0)
((= n 1) b)
(T (fib-r (- n 1) b (+ a b)))))
Pros: You don't have to build a wrapper function. Cond constructt takes care of if-then-elseif scenarios. You call this on REPL as (fib-r 10) => 55
Cons: If user supplies values to a and b, and if these values are not 0 and 1, you wont get correct answer

Resources