[Keith Vetter] - 2024-02-15 I recently came across a https://www.youtube.com/watch?v=fwxjMKBMR7s%|%Youtube video%|% describing a clever algorithm by Dijkstra to compute all primes less than some number. It has the efficiency of the Sieve of Eratosthenes (see [Eratosthenes Sieve]) but uses much less memory. It doesn't need a huge array where we cross off multiples of primes. Instead it uses more of a dynamic programming approach with a simple list of duples called "''pool''". When we're considering if number N is prime or not, the list "''pool''" consists of prime/factor pair where prime is one of the primes we've found so far and factor is the smallest factor of that prime greater or equal to N. If N is smaller than all the factors, then it must be prime--and we need to add it to "''pool''". Otherwise it's composite--and we need to update "''pool''" so all factors are greater or equal to n+1. ====== proc FindPrimes {max} { set pool [list {2 4}] set primes [list 2] for {set k 3} {$k < $max} {incr k} { # if {$k % 10000 == 0} { puts "$k/$max" ; flush stdout} if {$k < [lindex $pool 0 1]} { lappend primes $k if {$k * $k <= $max} { lappend pool [list $k [expr {$k * $k}]] set pool [lsort -integer -index 1 $pool] } } else { for {set idx 0} {$idx < [llength $pool]} {incr idx} { lassign [lindex $pool $idx] n factor if {$factor > $k} break lset pool $idx 1 [expr {$factor + $n}] } set pool [lsort -integer -index 1 $pool] } } return $primes } set start [clock milliseconds] set all [FindPrimes 1000000] ; list set end [clock milliseconds] set duration_seconds [expr {($end - $start) / 1000.0}] puts "It took $duration_seconds to compute [llength $all] primes" ======