简体   繁体   中英

Scheme Recursive Function

Can someone give me an explanation as to how the following function works recursively. I can understand simpler recursive examples, but I don't understand how (smooth n (- k 1)) gives the value desired under the or statement here.

(define (divides a b)
  (= (modulo b a) 0))

(define (smooth n k)
  (and (>= k 2)
       (or (divides k n)
           (smooth n (- k 1)))))

(define (isprime p)
  (if (< p 2)
      #f
      (not (smooth p (floor (sqrt p))))))

I wrote an isprime function that doesn't use 1 as a prime number, but I still don't quite understand how the above function works/how it works with this example.

Perhaps it'll be easier to understand if we rewrite smooth as follows - it's a completely equivalent form, but makes use of cond instead of and , or :

(define (smooth n k)
  (cond ((< k 2)
         #f)
        ((divides k n)
         #t)
        (else
         (smooth n (- k 1)))))

Basically, the procedure is stating that:

  • if k is less than 2, then n is not "smooth"
  • if k divides exactly n , then n is "smooth"
  • otherwise, subtract 1 from k and keep trying

In other words: if n has any divisor besides itself and 1, we say it's "smooth". Clearly, it's easy to write a procedure that tests if a number is prime, in terms of its "smoothness" - a number is prime if it's greater than 2 and it's not smooth (meaning: it doesn't have a divisor besides itself and 1 ). And this post explains why we only have to test the divisors up to the square root of a number to determine if it's prime.

It is easier to understand if you try to write down each call. For example:

(smooth 5 4)
    (smooth 5 3)
        (smooth 5 2)


(define (smooth 5 3)
   (and (>= 4 2)
        (or (divides 3 5)
            (smooth 5 (- 3 1)))))

(define (smooth 5 2)
   (and (>= 2 2)
        (or (divides 2 5)
            (smooth 5 (- 2 1)))))

(define (smooth 5 1)
   (and (>= 2 1) # This returns false
        #t))

(define (smooth 5 2)
   (and #f #t))

(define (smooth 5 3)
   (and #t #f))

(define (smooth 5 4)
   (and #t #f))

#f

smooth nk is true if n has a divisor between 2 and k .

It is just equivalent to a loop actually :

for i from k to 2 :
    if i divides n, return True

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM