How to resolve the algorithm The sieve of Sundaram step by step in the Amazing Hopper programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm The sieve of Sundaram step by step in the Amazing Hopper programming language

Table of Contents

Problem Statement

The sieve of Eratosthenes: you've been there; done that; have the T-shirt. The sieve of Eratosthenes was ancient history when Euclid was a schoolboy. You are ready for something less than 3000 years old. You are ready for The sieve of Sundaram. Starting with the ordered set of +ve integers, mark every third starting at 4 (4;7;10...). Step through the set and if the value is not marked output 2*n+1. So from 1 to 4 output 3 5 7. 4 is marked so skip for 5 and 6 output 11 and 13. 7 is marked, so no output but now also mark every fifth starting at 12 (12;17;22...) as per to 10 and now mark every seventh starting at 17 (17;24;31....) as per for every further third element (13;16;19...) mark every (9th;11th;13th;...) element. The output will be the ordered set of odd primes. Using your function find and output the first 100 and the millionth Sundaram prime. The faithless amongst you may compare the results with those generated by The sieve of Eratosthenes. Comment on the Sundaram Sieve In case casual readers and programmers read the above blurb and get the impression that something several thousand years newer must needs be better than the "old" Sieve of Eratosthenes (SoE), do note the only difference between the Sieve of Sundaram (SoS) and the odds-only SoE is that the SoS marks as composite/"culls" according to all odd "base" numbers as is quite clear in the above description of how to implement it and the above linked Wikipedia article (updated), and the SoE marks as composite/"culls" according to only the previously determined unmarked primes (which are all odd except for two, which is not used for the "odds-only" algorithm); the time complexity (which relates to the execution time) is therefore O(n log n) for the SoS and O(n log log n) for the SoE, which difference can make a huge difference to the time it takes to sieve as the ranges get larger. It takes about a billion "culls" to sieve odds-only to a billion for the SoE, whereas it takes about 2.28 billion "culls" to cull to the same range for the SoS, which implies that the SoS must be about this ratio slower for this range with the memory usage identical. Why would one choose the SoS over the SoE to save a single line of code at the cost of this much extra time? The Wren comparison at the bottom of this page makes that clear, as would implementing the same in any language.

Let's start with the solution:

Step by Step solution about How to resolve the algorithm The sieve of Sundaram step by step in the Amazing Hopper programming language

Source code in the amazing programming language

#include 

Main
   Set break   
   tiempo inicio = 0, tiempo final = 0
   
   nprimes=1000000, nmax=0
   Let ( nmax :=  Ceil( Mul( nprimes, Sub( Add(Log(nprimes), Log(Log(nprimes))), 0.9385) ) ) )
   k=0, Let( k := Div( Minus two 'nmax', 2) )

   a=0
   Set decimal '0'
   Seqspaced(3, {k} Mul by '2' Plus '1', {k} Mul by '2' Plus '1' Div into '2', a)
   Unset decimal
   
   i=1
   pos inicial sumando=2, pos ini factor = 2, factor factor = 2, suma = 6
   sumando = 0, factor = 0
   end subloop=0

   Tic( tiempo inicio )
   Loop
      
     /* calculo las secuencias para las posiciones; ocupa la memoria creada para la primera secuencia,
        es mucho, pero si lo hago con ciclos, el loop termina dentro de 6 minutos :D */
      Let ( end subloop := {k} Minus 'i', {i} Mul by '2' Plus '1', Div it )
      Sequence( pos inicial sumando, 1, end subloop, sumando )
      Sequence( pos ini factor, factor factor, end subloop, factor )

      Let ( sumando := Add( sumando, factor) )
      Set range 'sumando', Set '0', Put 'a'  // pongo ceros en las posiciones calculadas
      Clr range
     
     /* recalculo índices para nuevas posiciones */ 
      pos inicial sumando += 2  // 2,4,6,8...
      pos ini factor += suma    // 2, 8, 18, 32
      suma += 4                 // 10, 14, 18
      factor factor += 2        // 2,4,6,8 

      ++i
   While ( Less equal ( Mul( Mul( Plus one (i),i ),2), k ) )
   Toc( tiempo inicio, tiempo final )

  /* Visualización de los primeros 100 primos. Esto podría hacerlo con ciclos,
     como lo hace la versión de "C", pero me gusta disparar moscas con un rifle */
   Cls
   ta=0, Compact 'a', Move to 'a'       // elimino los ceros = compacto array
   [1:100] Get 'a', Move to 'ta', Redim (ta, 10, 10)
   Tok sep ("\t"), Print table 'ta' 
   Clr interval, Clear 'ta'
  
  /* imprimo el primo número "nprimes" */
   Print( nprimes, " th Sundaram prime is ", [ nprimes ] Get 'a', "\n" )
   Printnl( "Time = ", tiempo final, " segs" )
End

#include 

Main
   tiempo inicio = 0, tiempo final = 0
   nprimes=1000000, 

   nmax=0
   Let ( nmax :=  Ceil( Mul( nprimes, Sub( Add(Log(nprimes), Log(Log(nprimes))), 0.9385) ) ) )
   k=0
   Let( k := Div( Minus two 'nmax', 2) )
   
   a=0
   Set decimal '0'
   Seqspaced(3, {k} Mul by '2' Plus '1', {k} Mul by '2' Plus '1' Div into '2', a)
   Unset decimal

   pos inicial sumando=2
   pos ini factor = 2, suma = 6
   end subloop=0
   i=1

   Tic( tiempo inicio )
   Loop
      
      Let ( end subloop := 'k' Minus 'i'; 'i' Mul by '2' Plus '1', Div it )

      Get sequence( pos inicial sumando, 1, end subloop )
      Get sequence( pos ini factor, pos inicial sumando, end subloop )
      ---Add it---

      Get range  // usa el rango desde el stack. Se espera que el rango sea una variable,
                 // por lo que no se quitará desde la memoria hasta un kill (Forget en Jambo)
      Set '0', Put 'a'
      --- Forget ---     // para quitar el rango desde el stack.

      pos inicial sumando += 2  // 2,4,6,8...
      pos ini factor += suma    // 2, 8, 18, 32
      suma += 4                 // 10, 14, 18
      ++i
   While ( Less equal ( Mul( Mul( Plus one (i),i ),2), k ) )
   
   Toc( tiempo inicio, tiempo final )
   Clr range
   
  /* Visualización */
   Cls
   ta=0, [1:100] Move positives from 'a' Into 'ta'
         Redim (ta, 10, 10)
   Tok sep ("\t"), Print table 'ta' 
   Clr interval, Clear 'ta'
  
  /* imprimo el primo número "nprimes" */
   Setdecimal(0)
   Print( nprimes, " th Sundaram prime is ", [ nprimes ] Get positives from 'a' , "\n" )   
   Printnl( "Time = ", tiempo final, " segs" )
End

  

You may also check:How to resolve the algorithm Man or boy test step by step in the Pascal programming language
You may also check:How to resolve the algorithm Loops/Downward for step by step in the SSEM programming language
You may also check:How to resolve the algorithm Strip whitespace from a string/Top and tail step by step in the Stata programming language
You may also check:How to resolve the algorithm Smallest number k such that k+2^m is composite for all m less than k step by step in the Java programming language
You may also check:How to resolve the algorithm Polymorphic copy step by step in the Swift programming language