Search code examples
schemelispprimes

scheme wrong-type-argument in attempted solution to Euler Project problem 7


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.


Solution

  • 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.