Scheme code for fermat's Factorization -
i trying learn scheme implementing few algorithms.
fermatfactor(n): // n should odd ← ceil(sqrt(n)) b2 ← a*a - n while b2 isn't square: ← + 1 // equivalently: b2 ← b2 + 2*a + 1 b2 ← a*a - n // ← + 1 endwhile return - sqrt(b2) // or + sqrt(b2)
i trying implement above algorithm in scheme. stuck on while loop. appreciated. thanks
rather using while
loop, in scheme, use recursion. scheme has tail recursion, recursion performant looping constructs in other languages.
specifically, in case, use called "named let", makes creating inline recursion easy. direct translation of above code scheme result in this:
(define (fermat-factor n) (let* ((a (ceiling (sqrt n))) (b (- (* a) n))) (let loop () (cond ((not (integer? (sqrt b))) (set! (+ 1)) (set! b (- (* a) n)) (loop)))) (- (sqrt b))))
this isn't idiomatic, though, since uses mutation (the calls set!
), entirely unnecessary in algorithm. more idiomatic approach this:
(define (fermat-factor* n) (let* ((a0 (ceiling (sqrt n))) (b0 (- (* a0 a0) n))) (let loop ((a a0) (b b0)) (if (integer? (sqrt b)) (- (sqrt b)) (loop (+ 1) (- (* a) n))))))
(the usage of initial let*
necessary because named let not permit sequential bindings in style of let*
, , let*
not support named let pattern.)