1 rem ***  ulam spiral  ***
2 rem  a memory demo for thoreau basic
3 rem
4 rem  sieves nn integers in one array, then walks a square
5 rem  spiral outward from the centre of the screen, plotting
6 rem  only the primes. the diagonal streaks are real: stanislaw
7 rem  ulam noticed them on a notepad during a dull lecture, 1963.
8 rem
9 rem  line 30 sets the sieve size. gw-basic had a 64kb
10 rem  workspace in total, so this array is roughly 250 times
11 rem  the size of the entire machine it is compatible with.

20 cls
25 sw=gramaxx:sh=gramaxy
30 nn=2000000
35 dim p(nn)

40 rem --- sieve of eratosthenes (no sqr needed) ---
45 print "sieving";nn;"integers ..."
50 i=2
55 if i*i>nn then goto 80
60 if p(i)=1 then goto 75
65 for j=i*i to nn step i
70 p(j)=1:next j
75 i=i+1:goto 55

80 rem --- count them ---
85 pc=0
90 for i=2 to nn
95 if p(i)=0 then pc=pc+1
100 next i

105 rem --- spiral setup ---
110 rem  side is the screen height, so a centred square of
115 rem  sh*sh numbers fits exactly with no clipping needed.
120 sd=sh
125 nm=sd*sd
130 cx=int(sw/2):cy=int(sh/2)
135 x=cx:y=cy
140 dx=1:dy=0
145 sl=1:sn=0
150 nu=1

155 rem === walk the spiral ===
160 for k=1 to sl
165 if nu<2 then goto 200
170 if p(nu)=1 then goto 200
175 aa=nu/nm*6.2832
180 r=128+127*cos(aa)
185 g=128+127*cos(aa+2.0944)
190 b=128+127*cos(aa+4.1888)
195 line (x,y)-(x,y),r,g,b
200 x=x+dx:y=y+dy
205 nu=nu+1
210 if nu>nm then goto 250
215 next k

220 rem --- turn left 90 degrees ---
225 td=dx:dx=dy:dy=-td
230 sn=sn+1
235 if sn mod 2=0 then sl=sl+1
240 goto 160

250 rem --- done ---
255 print pc;"primes below";nn
260 print "spiral shows the first";nm
265 end
