Nie taki przypadkowy spacer
Jestem na bardzo długim spacerze i nudzę się, więc decyduję się na spacer matematyczny.
Pierwszy obraz przedstawia pierwsze 500 kroków, a drugi obraz to moja ścieżka po 50000 krokach. Kolory służą głównie do celów wizualizacji.
Moja ścieżka nie jest przypadkowa, więc jak wybrałem ścieżkę? Daj mi znać, jeśli potrzebujesz wskazówek.
Odpowiedzi
Wygląda na to, że zaczynasz
rysowanie kropki dla $n=0$ w (1, 0)
i wtedy
przejść „na wschód” (w dodatnim kierunku x) i narysować kropkę dla każdego $n$
i
kiedy skręć w lewo o 90 ° $n$ jest liczbą pierwszą.
Glorfindel rozwiązał to w kilka minut, ale dla waszej rozrywki chciałbym pokazać „rozwiązanie” w postaci skryptu w Pythonie. Pobierz plik liczb pierwszych zhttps://primes.utm.edu/lists/small/millions/
Zwróć uwagę, że kod można zoptymalizować. Uaktualnia liczbę o 1 milion kroków w ciągu około minuty na moim komputerze.
(przepraszam, nie można zawinąć kodu w tagi spoilera)
# -*- 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()
I obraz około 1 miliona kroków ...
Edycja: Dla zabawy również obraz z kierunkami: E, NE, N, NW, W, SW, S, SE zamiast tylko E, N, W, S