; strassen's factoring algorithm

(define (iroot k n)
  (let ((k-1 (- k 1)))
    (let loop ((u n) (s (+ n 1)))
      (if (<= s u) s
        (loop (quotient (+ (* k-1 u) (quotient n (expt u k-1))) k) u)))))

(define (strassen n)
  (call-with-current-continuation
    (lambda (return)
      (let ((c (iroot 4 n)))
        (do ((i 0 (+ i 1))) ((= i c) #f)
          (let* ((jmin (+ 1 (* i c))) (jmax (+ jmin c -1)))
            (do ((j jmin (+ j 1)) (f 1 (modulo (* f j) n)))
                ((< jmax j) (let ((g (gcd f n)))
                              (when (< 1 g) (return g)))))))))))

(display (strassen 13290059)) (newline)
(display (strassen 11111111111111111)) (newline)
(display (strassen 2071723)) (newline)