; fibonacci search
(define (filter pred? xs)
(let loop ((xs xs) (ys '()))
(cond ((null? xs) (reverse ys))
((pred? (car xs))
(loop (cdr xs) (cons (car xs) ys)))
(else (loop (cdr xs) ys)))))
(define (range . args)
(case (length args)
((1) (range 0 (car args) (if (negative? (car args)) -1 1)))
((2) (range (car args) (cadr args) (if (< (car args) (cadr args)) 1 -1)))
((3) (let ((le? (if (negative? (caddr args)) >= <=)))
(let loop ((x(car args)) (xs '()))
(if (le? (cadr args) x)
(reverse xs)
(loop (+ x (caddr args)) (cons x xs))))))
(else (error 'range "unrecognized arguments"))))
(define ps '#(2 3 5 7 11 13 17 19 23 29 31 37 41 43 47))
(let ((len (vector-length xs)))
(let loop ((lo 0) (hi (- len 1)))
(if (< hi lo) -1
(let ((mid (quotient (+ lo hi) 2)))
(cond ((lt? x (vector-ref xs mid))
(loop lo (- mid 1)))
((lt? (vector-ref xs mid) x)
(loop (+ mid 1) hi))
(else mid)))))))
(display "bsearch") (newline)
(display
(bsearch < 23 ps
)) (newline
) (display
(bsearch < 45 ps
)) (newline
) (display (filter (lambda (x) (not (negative? x)))
(map
(lambda
(p
) (bsearch < p ps
)) (range
50)))) (newline
)
(define fib ; (fib n) returns nth fibonacci number, n < 52
(let ((fibs (let loop ((k 50) (fibs (list 1 0)))
(if (zero? k) (list->vector (reverse fibs))
(loop (- k 1) (cons (+ (car fibs) (cadr fibs)) fibs))))))
(lambda (n) (vector-ref fibs n))))
(define (fsearch lt? x xs)
(let* ((len (vector-length xs))
(k (do ((k 0 (+ k 1)))
((<= len (fib k)) (- k 1)))))
(let loop ((lo 0) (hi (- len 1)) (k k))
(if (not (positive? k)) -1
(let ((mid (min (+ lo (fib (- k 1))) hi)))
(cond ((lt? x (vector-ref xs mid))
(loop lo mid (- k 2)))
((lt? (vector-ref xs mid) x)
(loop mid hi (- k 1)))
(else mid)))))))
(display "fsearch") (newline)
(display (fsearch < 23 ps)) (newline)
(display (fsearch < 45 ps)) (newline)
(display (filter (lambda (x) (not (negative? x)))
(map (lambda (p) (fsearch < p ps)) (range 50)))) (newline)
(define (gsearch lt? x xs)
(define (gsection lo hi)
(let
((phi
(/ (+ 1 (sqrt 5)) 2))) (+ (inexact->exact (round
(/ (- hi lo) phi))) lo)))
(let ((len (vector-length xs)))
(let loop ((lo 0) (hi (- len 1)))
(if (< hi lo) -1
(let ((mid (gsection lo hi)))
(cond ((lt? x (vector-ref xs mid))
(loop lo (- mid 1)))
((lt? (vector-ref xs mid) x)
(loop (+ mid 1) hi))
(else mid)))))))
(display "gsearch") (newline)
(display (gsearch < 23 ps)) (newline)
(display (gsearch < 45 ps)) (newline)
(display (filter (lambda (x) (not (negative? x)))
(map (lambda (p) (gsearch < p ps)) (range 50)))) (newline)