Check for a prime number using recursive helper function - recursion

I am trying to check if a number is prime using recursion. I was required to use a recursive helper function, but I am not sure how I should implement it.
I think I know the algorithm, but I've never tried to use a recursive helper function in Racket. This is my current thoughts:
See if n is divisible by i = 2
Set i = i + 1
If i^2 <= n continue.
If no values of i evenly divided n, then it must be prime.
This is what I have so far...
(define (is_prime n)
(if (<= n 1)
#f
(if (= (modulo n 2) 0)
#f
)
What would be a good approach using a recursive helper function??
Thanks!

Using a helper simply means that you should split your program in smaller parts, and possibly encapsulate loops with extra parameters in separate procedures - and in Scheme loops are frequently implemented via recursive calls. One (naïve) way to implement the is_prime procedure would be:
(define (is_prime n)
(cond ((<= n 1) #f)
((= n 2) #t)
((= (modulo n 2) 0) #f)
(else (check 3 n))))
; recursive helper
(define (check i n)
(cond ((> (* i i) n) #t)
((= (modulo n i) 0) #f)
(else (check (+ i 2) n))))
There are many ways to implement this procedure, and many possible optimizations; the above should be enough get you started.

(define (isPrimeHelper x k)
(if (= x k) #t
(if (= (remainder x k) 0) #f
(isPrimeHelper x (+ k 1)))))
(define ( isPrime x )
(cond
(( = x 0 ) #f)
(( = x 1 ) #f)
(( = x 2 ) #t)
( else (isPrimeHelper x 2 ) )))
I prefer this version.

Related

How to implement optional arguments in CHICKEN?

I'm new to CHICKEN and Scheme. In my quest to understanding tail recursion, I wrote:
(define (recsum x) (recsum-tail x 0))
(define (recsum-tail x accum)
(if (= x 0)
accum
(recsum-tail (- x 1) (+ x accum))))
This does what I expect it to. However, this seems a little repetitive; having an optional argument should make this neater. So I tried:
(define (recsum x . y)
(let ((accum (car y)))
(if (= x 0)
accum
(recsum (- x 1) (+ x accum)))))
However, in CHICKEN (and maybe in other scheme implementations), car cannot be used against ():
Error: (car) bad argument type: ()
Is there another way to implement optional function arguments, specifically in CHICKEN 5?
I think you're looking for a named let, not for optional procedure arguments. It's a simple way to define a helper procedure with (possibly) extra parameters that you can initialize as required:
(define (recsum x)
(let recsum-tail ((x x) (accum 0))
(if (= x 0)
accum
(recsum-tail (- x 1) (+ x accum)))))
Of course, we can also implement it with varargs - but I don't think this looks as elegant:
(define (recsum x . y)
(let ((accum (if (null? y) 0 (car y))))
(if (= x 0)
accum
(recsum (- x 1) (+ x accum)))))
Either way, it works as expected:
(recsum 10)
=> 55
Chicken has optional arguments. You can do it like this:
(define (sum n #!optional (acc 0))
(if (= n 0)
acc
(sum (- n 1) (+ acc n))))
However I will vote against using this as it is non standard Scheme. Chicken say they support SRFI-89: Optional positional and named parameters, but it seems it's an earlier version and the egg needs to be redone. Anyway when it is re-applied this should work:
;;chicken-install srfi-89 # install the egg
(use srfi-89) ; imports the egg
(define (sum n (acc 0))
(if (= n 0)
acc
(sum (- n 1) (+ acc n))))
Also your idea of using rest arguments work. However keep in mind that the procedure then will build a pair on the heap for each iteration:
(define (sum n . acc-lst)
(define acc
(if (null? acc-lst)
0
(car acc-lst)))
(if (= n 0)
acc
(sum (- n 1) (+ acc n))))
All of these leak internal information. Sometimes it's part of the public contract to have an optional parameter, but in this case it is to avoid writing a few more lines. Usually you don't want someone to pass a second argument and you should keep the internals private. The better way would be to use named let and keep the public contract as is.
(define (sum n)
(let loop ((n n) (acc 0))
(if (= n 0)
acc
(loop (- n 1) (+ acc n))))

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

Digits of a number in Racket are in random order

I decided to write a function that given a number will return a list containing the digits in that number, my attempt is:
(define (rev-digits n)
(if (= n 0)
'()
(cons (modulo n 10) (digits (quotient n 10)))))
(define (digits n)
(reverse (rev-digits n)))
The fact is, I need the digits to be in proper order, but the function returns, for example:
> (digits 1234567890)
'(9 7 5 3 1 2 4 6 8 0)
In seemingly random order... can you help me getting a more ordinated output?
rev-digits needs to call itself, not digits.
(define (rev-digits n)
(if (= n 0)
'()
(cons (modulo n 10) (rev-digits (quotient n 10)))))
(define (digits n)
(reverse (rev-digits n)))
should work.
It's worth noting that your "random" output was not in fact random; rather the digits were "bouncing" back and forth from the start to the end of the list. Which makes sense, because you were effectively switching back and forth between a "normal" and reversed version of your digits function.
The answer given by #JayKominek is spot-on and fixes the error in your code. To complement it, here's an alternative implementation:
(define (rev-digits n)
(let loop ((n n) (acc '()))
(if (< n 10)
(cons n acc)
(loop (quotient n 10) (cons (modulo n 10) acc)))))
The advantages of the above code are:
It's tail recursive and hence more efficient
It correctly handles the edge case when n is zero (your code returns an empty list)
It doesn't require a helper procedure, thanks to the use of a named let
It builds the list in the correct order, there's no need to reverse it at the end
A simple solution:
#lang racket
(define (digits n)
(for/list ([c (number->string n)])
(- (char->integer c) (char->integer #\0))))

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)))))

Scheme - fibonacci series with nested lambda

Inspired this post .
I trying to implement a fibonacci series with nested lambda -
(( (lambda (x) (x x)) ;; evaluate x on x
((lambda (fibo-gen)) ;; fibo-gen get another func as arg
(lambda (N it second first)
(cond ;; here the body of the above func ..
((= N 1) 1)
((= N 1) 1)
((= N it) (+ second first))
(else (fibo-gen (+ it 1) (+ second first) (second)))
)
)
)
)
5 1 1 1)
It's prompts r5rs:body: no expression in body in: (r5rs:body)
By my examination each function has a "body" here , so what I did wrong ?
Note that the implementation I trying to do here is iterative mode which avoid re-calculate previous series ..
Edit :
Another mode which also works -
(( (lambda (x) (x x)) ;; evaluate x on x
(lambda (fibo-gen) ;; fibo-gen body use another lambda ..
(lambda (N it second first)
(cond ;; here the body of the above func ..
((= N 1) 1)
((= N 2) 1)
((= N it) second)
(else ((fibo-gen fibo-gen) N (+ it 1) (+ second first) second))
)
)
)
)
5 1 1 1)
=> 8
Well, this is quite a contrived way to calculate fibonacci, but nevertheless possible:
(((lambda (x) (x x))
(lambda (fib-gen)
(lambda (it second first)
(if (zero? it)
first
((fib-gen fib-gen) (sub1 it) (+ first second) second)))))
10 1 0) ; here n = 10
=> 55
If you're aiming for a general way for writing a recursive function without using define, first implement the Y-Combinator:
(define (Y X)
((lambda (proc) (proc proc))
(lambda (proc)
(X (lambda args
(apply (proc proc) args))))))
With this, you can write anonymous recursive procedures with a variable number of arguments, for example:
((Y
(lambda (fib-gen)
(lambda (it second first)
(if (zero? it)
first
(fib-gen (sub1 it) (+ first second) second)))))
10 1 0) ; here n = 10
=> 55
(lambda (fibo-gen))
in the second line has no body.

Resources