; longest sequence of consecutive odd integers

(define (isqrt n)
  (if (not (and (positive? n) (integer? n)))
      (error 'isqrt "must be positive integer")
      (let loop ((x n))
        (let ((y (quotient (+ x (quotient n x)) 2)))
          (if (< y x) (loop y) x)))))

(define (lscsi1 target)
  (let loop ((lo 1) (hi 1) (sum 1))
    ; (for-each display `(,lo " " ,hi " " ,sum #\newline))
    (cond ((< sum target) (loop lo (+ hi 2) (+ sum hi 2)))
          ((< target sum) (loop (+ lo 2) hi (- sum lo)))
          (else (values lo hi (+ (/ (- hi lo) 2) 1))))))

(define (lscsi2 target)
  (let loop ((n (isqrt target)))
    (let ((m (quotient target n)))
      (cond ((positive? (modulo target n))
              (loop (- n 1)))
            ((= (modulo n 2) (modulo m 2))
              (values (- m n -1) (+ m n -1) n))
            (else (loop (- n 1)))))))

(call-with-values
  (lambda () (lscsi1 160701))
  (lambda (lo hi len)
    (display lo) (newline)
    (display hi) (newline)
    (display len) (newline)))

(call-with-values
  (lambda () (lscsi2 160701))
  (lambda (lo hi len)
    (display lo) (newline)
    (display hi) (newline)
    (display len) (newline)))

(define (lscsi1 target)
  (let loop ((lo 1) (hi 1) (sum 1))
    (for-each display `(,lo " " ,hi " " ,sum #\newline))
    (cond ((< sum target) (loop lo (+ hi 2) (+ sum hi 2)))
          ((< target sum) (loop (+ lo 2) hi (- sum lo)))
          (else (values lo hi (+ (/ (- hi lo) 2) 1))))))

(call-with-values
  (lambda () (lscsi1 160700))
  (lambda (lo hi len)
    (display lo) (newline)
    (display hi) (newline)
    (display len) (newline)))