I've been trying to solve the seventh Euler Project problem. My program looks like this:
(define (add-prime c)
(define (smallest-divisor n) (find-divisor n 2))
(define (find-divisor n test-divisor)
(cond
((> (* test-divisor test-divisor) n) n)
((divides? test-divisor n) test-divisor)
(else
(find-divisor n (+ test-divisor 1)))))
(define (divides? a b) (= (remainder b a) 0))
(define (prime? n)
(= n (smallest-divisor n)))
(if (prime? (+ c 1))
(+ c 1)
(add-prime (+ c 1))))
(define (pv v c)
(if (= c (vector-length v))
v
(begin
(vector-set! v c
(add-prime (vector-ref v (- c 1))))
(pv v (+ c 1)))))
(let ((prime-vec (make-vector 10002)))
(vector-set! prime-vec 0 2)
(pv prime-vec 3)
(display v))
The output looks like this:
In procedure add-prime:
In procedure +: Wrong type argument in position 1: #<unspecified>
I'm very confused. By itself, the add-prime
procedure works correctly, it's just that when I combine it to create a vector containing 10,002 prime numbers, it returns this error.
You initialize your vector only at the address 0
(let ((prime-vec (make-vector 10002)))
(vector-set! prime-vec 0 2)
but then you go on filling it starting from the address 3
(pv prime-vec 3)
=
(let ((v prime-vec) (c 3))
....
(vector-set! v c
(add-prime (vector-ref v (- c 1))))
....
=
....
(vector-set! prime-vec 3
(add-prime (vector-ref prime-vec 2)))
....
but you haven't initialized the contents of the vector at the address 2
, yet.
Racket uses the value 0
for the uninitialized addresses evidently, but your implementation apparently isn't and instead has #<unspecified>
there, causing the error.
Start filling the vector from address 1
, instead of 3
, and it should fix the error.
As a side note, add-prime
is really next-prime
. Naming is important, good naming can reduce the cognitive load.