1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- ;; Summation of primes
- ;; Problem 10
- ;; The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.
- ;; Find the sum of all the primes below two million.
- (import
- (except (rnrs base)
- let-values
- map)
- (only (guile)
- lambda* λ)
- (ice-9 futures)
- (lib rabin-miller-test)
- (lib naive-prime-test))
- (define even?
- (λ (num)
- (= (remainder num 2) 0)))
- (define next
- (λ (num)
- (cond
- [(even? num) (+ num 1)]
- [else (+ num 2)])))
- (define sum-of-primes
- (λ (start limit)
- (let loop ([num start]
- [acc 0]
- [primes-count 1])
- (cond
- [(> num limit)
- (display (simple-format #f "number of primes: ~a\n" primes-count))
- acc]
- [(prime? num)
- (loop (next num)
- (+ acc num)
- (+ primes-count 1))]
- [else
- (loop (next num)
- acc
- primes-count)]))))
- (define make-segment
- (λ (start end)
- (cons start end)))
- (define segment-start
- (λ (seg)
- (car seg)))
- (define segment-end
- (λ (seg)
- (cdr seg)))
- (define segment
- (λ (start end segment-count)
- "Make segments of equal size, except for rounding to whole numbers, which might result in slightly more "
- (let ([segment-size
- (ceiling
- (/ (- end start)
- segment-count))])
- (let loop ([pos start])
- (cond
- [(>= (+ pos segment-size) end)
- (list (make-segment pos end))]
- [else
- (cons (make-segment pos (+ pos segment-size))
- (loop (next (+ pos segment-size))))])))))
- (let* ([start 2]
- [limit (- (* 2 (expt 10 6)) 1)]
- [cores-count 32]
- [segments (segment start limit cores-count)])
- (let ([futures
- (map (λ (seg)
- (future
- (sum-of-primes (segment-start seg)
- (segment-end seg))))
- segments)])
- (apply + (map touch futures))))
|