计划中的euler#7计划

时间:2011-06-22 12:39:46

标签: scheme racket

这是一个问题:

  

通过列出前六个素数   数字:2,3,5,7,11和13,我们   可以看出第6个素数是13。

     

第10001个素数是多少?

这是我的解决方案:

#lang racket

(define (search-limit num)
  (+ (floor (sqrt num)) 1))

(define (search-list num)
  (stream->list (in-range 2 (search-limit num))))

(define (divided? num x)
  (= (remainder num x) 0))

(define (list-of-dividers num)
  (filter (lambda (x)
            (divided? num x))         
       (search-list num)))

(define (prime? num)
  (= (length (list-of-dividers num)) 0))

(define (problem_7 current_prime primes counter)
  (cond
    [(< primes 10001)
     (cond
       [(prime? counter) (problem_7 counter (+ primes 1) (+ counter 1))]
       [else (problem_7 current_prime primes (+ counter 1))])]
    [else current_prime]))

(problem_7 0 0 0)

它有效,但工作缓慢。我相信有更好的解决方案 你能给我更多的方案解决方案吗?

2 个答案:

答案 0 :(得分:2)

我是按照以下方式完成的,在我的电脑上花了不到1秒钟(你的版本需要大约12.5秒):

#lang racket

(define (divides? n div)
  (= (remainder n div) 0))

(define (prime? n)
  (prime-helper n 2))

(define (prime-helper n start)
  (cond ((> start (sqrt n)) #t)
        ((divides? n start) #f)
        (else (prime-helper n (+ 1 start)))))

(define (prob7_helper n count)
  (cond ((= 10001 count) (- n 1))
        ((prime? n) (prob7_helper (+ 1 n) (+ 1 count)))
        (else (prob7_helper (+ 1 n) count))))

(define (prob7) (prob7_helper 2 0))

(prob7)

(prime? n)肯定有更快的实现,但这对我有用。

答案 1 :(得分:1)

复合数总是使用较小的素数作为除数;素数从来没有一个较小的素数作为除数。由于你按顺序生成素数,你可以通过使你的素数测试尝试将候选者除以较小的素数列表来利用这个事实。 (顺便提一下,这是Eratosthenes方法的一种变体。)