20
$\begingroup$

I'm out for a very long walk, and I’m bored, so I decide to walk in a mathematical way.

The first image shows the first 500 steps, and the second image is my path after 50000 steps. The colors are mostly for visualization purposes.

My path is not random, so how did I select my path? Please let me know if you need hints.

500 steps 50000 steps

$\endgroup$
5
  • 1
    $\begingroup$ mm such a great thing, as a hint, and as long as u have the tool, can u add one up to a million just for eye candy pleasure, lol $\endgroup$ – MolbOrg Jan 17 at 19:40
  • $\begingroup$ I’ll post the python code tomorrow. It has to be changed a bit to go beyond 100,000 steps. $\endgroup$ – Stefan Jan 17 at 19:49
  • $\begingroup$ i think it'd be nice if the second image had equal x and y scale $\endgroup$ – somebody Jan 18 at 9:26
  • 1
    $\begingroup$ This reminded me of this: oeis.org/A268463 $\endgroup$ – Dmitry Kamenetsky Jan 19 at 1:26
  • $\begingroup$ Someone else had a very similar idea: math.stackexchange.com/questions/2072308/… $\endgroup$ – Stefan Jan 19 at 5:45
20
$\begingroup$

It looks like you start

drawing a dot for $n=0$ at (1, 0)

and then

process to walk 'eastwards' (in the positive x direction) and draw a dot for each $n$

and

make a 90° turn left when $n$ is prime.

$\endgroup$
2
  • $\begingroup$ Nice. This is the correct answer. $\endgroup$ – Stefan Jan 17 at 19:14
  • $\begingroup$ The solution reminds me of this great question $\endgroup$ – justhalf Jan 18 at 6:24
4
$\begingroup$

Glorfindel solved this in a few minutes, but for your entertainment I would like to show the "solution" as a Python script. Download the prime number file from https://primes.utm.edu/lists/small/millions/

Note that the code could be optimized. It updates the figure for 1 million steps in about a minute on my pc.

(sorry, can't wrap the code in spoiler tags)

# -*- coding: utf-8 -*-
import os

#Use seperate window for plot (when run from Spyder)
if any('SPYDER' in name for name in os.environ):
    from IPython import get_ipython
    get_ipython().run_line_magic('matplotlib', 'qt')

import numpy as np
import matplotlib.pyplot as plt

def fib(n):
    #iterator for Fibonacci sequence
    a, b = 1, 1
    for _ in range(n):
        yield a
        a, b = b, a + b
        
def annot(plist, index, ymax):
   x=plist[index][1]
   y=plist[index][2]
   p=plist[index][0]        
   plt.annotate(str(p),xy=(x,y),xytext=(x+10,y+ymax//10), 
             arrowprops=dict(arrowstyle= '->', color='blue',lw=0.5)  ) 

def readPrimes():
    # read prime  number sequence from file
    #fileName = 'primes-to-100k.txt' ## from https://www.mathsisfun.com/numbers/prime-number-lists.html
    fileName = 'primes1.txt' ## from https://primes.utm.edu/lists/small/millions/
    with open(fileName) as f:
        #skip header
        for i in range(3):
            _ =f.readline()
        strPrimes=f.read().split() 
        
        return np.array([int(p) for p in strPrimes])
    return None


def sequenceSnake(N=1000, D=4, sequence =None):
    if sequence is None:
        primes=np.array(readPrimes())
        sequence=primes
    
    def isInSequence(n):
       index=np.searchsorted(sequence,n)
       return n==sequence[index]
    
    def getCoords4(pos, dir):
       x=pos[0]
       y=pos[1]
       if dir==0:
          return x+1,y
       if dir==1:
          return x,y+1
       if dir==2:
          return x-1,y
       if dir==3:
         return x,y-1
    
    def getCoords8(pos, dir):
       x=pos[0]
       y=pos[1]
       if dir==0:
          return x+1,y
       if dir==1:
          return x+1,y+1
       if dir==2:
          return x,y+1
       if dir==3:
          return x-1,y+1
       if dir==4:
          return x-1,y
       if dir==5:
          return x-1,y-1
       if dir==6:
          return x,y-1
       if dir==7:
          return x+1,y-1
    
    dir=0
    x,y=(0,0)
    p=1
    
    ymax=0
    xlist=[]
    ylist=[]
    clist=[]
    plist=[]
    for i in range(0,N):
        if D==4: 
            x,y=getCoords4((x,y),dir)
        else:
            x,y=getCoords8((x,y),dir)
        if i >= sequence[-1]:
           print("warning: out of range, i="+str(i))
           break
        if isInSequence(i):
           p=i
           plist.append((p,x,y))
           dir=(dir+1)%D
        #print(i, dir)
        if np.abs(y)>ymax:
           ymax=np.abs(y)
        clist.append(p)
        xlist.append(x)
        ylist.append(y)
        
    return xlist, ylist, clist,plist,ymax


#
showAnnotate=False    
showFirstAndLastPrime=True
drawLine=False
n=10000
seqType=0
seq=None # default is prime number sequence.

#different sequences to test
if seqType==1:
    #fibonacci sequence
    seq=np.array(list(fib(1000)))
elif seqType==2:
    #square sequence
    seq=np.arange(1000)**2
elif seqType==3:
    #cumulative random sequence
    seq=np.random.randint(10, size=10000)
    seq=np.cumsum(seq)

    
xlist, ylist, clist,plist, ymax = sequenceSnake(N=n, D=4, sequence=seq)

if drawLine:
    plt.plot(xlist,ylist, 'k-')

plt.scatter(xlist, ylist,  marker='.', c=clist, cmap=plt.cm.prism)
#

if showAnnotate:
   for i,item in enumerate(plist):
       if i%100== 0:
           annot(plist,i, ymax)
        
        
if showFirstAndLastPrime: 
    annot(plist,0, ymax)
    annot(plist,-1, ymax)
      

plt.show()
          

And a picture of about 1 million steps... Primes up to 1 mio.

Edit: For fun, also an image with directions:E, NE, N, NW, W, SW, S, SE instead of only E, N, W, S enter image description here

$\endgroup$
1
  • $\begingroup$ Note on the differences in appearances of the images in the question and here: the images in the question were made on an iPad/pythonista, and these where made on a Windows pc/Spyder. Furthermore, I decided to remove the lines for the 1 mio steps case. $\endgroup$ – Stefan Jan 18 at 18:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.