Racket/Erastothenes: Skillnad mellan sidversioner

Från Täpp-Anders
Hoppa till navigeringHoppa till sök
Skapade sidan med '<pre> #lang racket ;;;;; ;; Erastothenes såll implementerad i Racket ;; Täpp-Anders Sikvall 2026-04-03 anders@sikvall.se ;;;;; (define (primes-between start stop) (cond [(> start stop) '()] [else ; Skapa en bool-vektor för intervallet [0..stop] (define sieve (make-vector (+ stop 1) #t)) ; 0 och 1 är inte primtal (vector-set! sieve 0 #f) (vector-set! sieve 1 #f) ; Såll: markera multiplar ; Går från 2 till (...'
Ingen redigeringssammanfattning
 
Rad 7: Rad 7:
;;;;;
;;;;;


;; Skapar en vektor där indexet motsvarar talet.
;; Om (vector-ref v n) är #t, så är n ett primtal.
(define (make-sieve limit)
  (define sieve (make-vector (add1 limit) #t))
 
  ;; 0 och 1 är aldrig primtal
  (when (>= limit 0) (vector-set! sieve 0 #f))
  (when (>= limit 1) (vector-set! sieve 1 #f))
 
  ;; Vi behöver bara gå upp till kvadratroten av limit
  (for ([p (in-range 2 (add1 (integer-sqrt limit)))])
    (when (vector-ref sieve p)
      ;; Markera alla multiplar av p som falska (starta vid p*p)
      (for ([multiple (in-range (* p p) (add1 limit) p)])
        (vector-set! sieve multiple #f))))
  sieve)
;; Returnerar en lista med alla primtal mellan start och stop
(define (primes-between start stop)
(define (primes-between start stop)
   (cond
   (if (> start stop)
    [(> start stop) '()]
      '() ;Returnerar tomt om start > stop
    [else
      (let ([is-prime? (make-sieve stop)])
    ; Skapa en bool-vektor för intervallet [0..stop]
        (for/list ([n (in-range (max start 2) (add1 stop))]
    (define sieve (make-vector (+ stop 1) #t))
                  #:when (vector-ref is-prime? n))
   
          n))))
    ; 0 och 1 är inte primtal
 
    (vector-set! sieve 0 #f)
 
    (vector-set! sieve 1 #f)
;; Testkörning
   
(primes-between 10 50)
    ; Såll: markera multiplar
    ; Går från 2 till (roten ur stop) +1
    ; inre vektorn går från i^2 till stop med steglängden i
    ; och markerar multiplarna av i genom hela vektorfältet
    (for ([i (in-range 2 (add1 (integer-sqrt stop)))])
      (when (vector-ref sieve i)
        (for ([j (in-range (* i i) (add1 stop) i)])
          (vector-set! sieve j #f))))
   
    ; Samla ihop primtal i intervallet [start, stop]
    (for/list ([i (in-range (max start 2) (add1 stop))]
                #:when (vector-ref sieve i))
      i)]))


; Exempel på användning:
(primes-between 100000 200000)  ; funkar snabbt även för stora tal
</pre>
</pre>

Nuvarande version från 5 april 2026 kl. 14.17

#lang racket

;;;;;
;; Erastothenes såll implementerad i Racket
;; Täpp-Anders Sikvall 2026-04-03 anders@sikvall.se
;;;;;


;; Skapar en vektor där indexet motsvarar talet.
;; Om (vector-ref v n) är #t, så är n ett primtal.

(define (make-sieve limit)
  (define sieve (make-vector (add1 limit) #t))
  
  ;; 0 och 1 är aldrig primtal
  (when (>= limit 0) (vector-set! sieve 0 #f))
  (when (>= limit 1) (vector-set! sieve 1 #f))
  
  ;; Vi behöver bara gå upp till kvadratroten av limit
  (for ([p (in-range 2 (add1 (integer-sqrt limit)))])
    (when (vector-ref sieve p)
      ;; Markera alla multiplar av p som falska (starta vid p*p)
      (for ([multiple (in-range (* p p) (add1 limit) p)])
        (vector-set! sieve multiple #f))))
  sieve)

;; Returnerar en lista med alla primtal mellan start och stop
(define (primes-between start stop)
  (if (> start stop)
      '() ;Returnerar tomt om start > stop
      (let ([is-prime? (make-sieve stop)])
        (for/list ([n (in-range (max start 2) (add1 stop))]
                   #:when (vector-ref is-prime? n))
          n))))


;; Testkörning
(primes-between 10 50)