racket/collects/tests/mzscheme/benchmarks/shootout/nsievebits.ss
2006-07-27 19:32:22 +00:00

67 lines
2.0 KiB
Scheme

#!/usr/bin/mzscheme -qu
;;; The Great Computer Language Shootout
;;; http://shootout.alioth.debian.org/
;;
;; Adapted from CMUCL code by Dima Dorfman; bit-vector stuff by Alex Shinn;
;; cobbled together by felix, converted to MzScheme by Brent Fulgham
;; Note: Requires MzScheme 299+
(module nsievebits mzscheme
(define (make-bit-vector size)
(let* ((len (quotient (+ size 7) 8))
(res (make-bytes len #b11111111)))
(let ((off (remainder size 8)))
(unless (zero? off)
(bytes-set! res (- len 1) (- (arithmetic-shift 1 off) 1))))
res))
(define (bit-vector-ref vec i)
(let ((byte (arithmetic-shift i -3))
(off (bitwise-and i #x7)))
(and (< byte (bytes-length vec))
(not (zero? (bitwise-and (bytes-ref vec byte)
(arithmetic-shift 1 off)))))))
(define (bit-vector-set! vec i x)
(let ((byte (arithmetic-shift i -3))
(off (bitwise-and i #x7)))
(let ((val (bytes-ref vec byte))
(mask (arithmetic-shift 1 off)))
(bytes-set! vec
byte
(if x
(bitwise-ior val mask)
(bitwise-and val (bitwise-not mask)))))))
(define (nsievebits m)
(let ((a (make-bit-vector m)))
(define (clear i)
(do ([j (+ i i) (+ j i)])
((>= j m))
(bit-vector-set! a j #f) ) )
(let ([c 0])
(do ([i 2 (add1 i)])
((>= i m) c)
(when (bit-vector-ref a i)
(clear i)
(set! c (add1 c)) ) ) ) ) )
(define (string-pad s n)
(string-append (make-string (- n (string-length s)) #\space)
s))
(define (test n)
(let ((m (* 10000 (arithmetic-shift 1 n))))
(printf "Primes up to ~a ~a~%"
(string-pad (number->string m) 8)
(string-pad (number->string (nsievebits m)) 8))))
(define (main args)
(let ([n (string->number (vector-ref args 0))])
(when (>= n 0) (test n))
(when (>= n 1) (test (- n 1)))
(when (>= n 2) (test (- n 2)))))
(main (current-command-line-arguments)))