import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
%reload_ext watermark
%watermark -v -m --iversions
Helpers¶
Define functions to draw the plots
def show_scatter(a):
plt.figure(figsize=(8,8))
plt.scatter(range(len(a)), a, s=10, c='black', marker=".")
plt.show()
def show_bitmatrix(a):
plt.figure(figsize=(8,8))
plt.imshow(a, cmap='Greys', interpolation='nearest')
plt.xticks([])
plt.yticks([])
plt.show()
Binary Representation¶
Binary plot on mathworld.wolfram.com
A binary plot of an integer sequence is a plot of the binary representations of successive terms where each term is represented as a sequence of bits with 1s colored black and 0s colored white. Then each representation is stacked to form a table where each entry represents a bit in the sequence. To make a binary plot of a sequence we need to convert each term of the sequence into its binary representation. Then we have to put this representation in a form which make us able to build the plot easily. The following function converts the sequence in a matrix where the element i-j represents is the bit j of the element i of the sequence:
def seq_to_bitmatrix(s):
# maximum number of bits used in this sequence
maxbit = len(bin(max(s)))
M = np.zeros((len(s),maxbit),dtype='uint8')
for i,e in enumerate(s):
bits = bin(e)[2:] # bin() -> 0b100, we drop 2 chars
for j,b in enumerate(bits):
M[i,maxbit-len(bits)+j] = int(b) # fill the matrix
return M
Positive integers¶
0, 1, 2, 3...
posint_a = list(range(50))
show_scatter(posint_a)
show_bitmatrix(seq_to_bitmatrix(posint_a).T)
Integer squares¶
0, 1, 4, 9, 16, 25...
sqint_a = [pow(n, 2) for n in range(50)]
show_scatter(sqint_a)
show_bitmatrix(seq_to_bitmatrix(sqint_a).T)
Integer square root¶
0, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3,
sqrtint_a = [int(np.sqrt(n)) for n in range(500)]
show_scatter(sqrtint_a[:50])
show_scatter(sqrtint_a)
show_bitmatrix(seq_to_bitmatrix(sqrtint_a[:50]).T)
Powers of 2¶
_ = [int(2**n) for n in range(1000)]
show_scatter(_)
s = [int(n*(n+1)/2) for n in range(100)]
show_scatter(s)
show_bitmatrix(seq_to_bitmatrix(s).T)
def gen_primes():
D = {}
q = 2
while True:
if q not in D:
yield q
D[q * q] = [q]
else:
for p in D[q]:
D.setdefault(p + q, []).append(p)
del D[q]
q += 1
f = gen_primes()
pa = [next(f) for i in range(100)]
show_scatter(pa)
show_bitmatrix(seq_to_bitmatrix(pa).T)
def fib():
x, y = 0, 1
while 1:
yield x
x, y = y, x+y
f = fib()
fib_a = [next(f) for i in range(200)]
show_scatter(fib_a)
show_bitmatrix(seq_to_bitmatrix(fib_a))
from numpy import prod;
def C(n, k):
return prod([(n-j)/(j+1) for j in range(k)])
res=1
for r in range(15):
print(*["{}".format('{:>5}'.format(int(C(r, i)))) for i in range(res)])
res+=1
from itertools import islice
def pascal():
row = [1]
while True:
yield row
row = [i+j for i,j in zip([0]+row, row+[0])]
for r in islice(pascal(),0,11):
print("{:^60}".format("".join(map(lambda n: "{:>5}".format(n), r))))
def C(n, k):
if k<0 or k>n:
return 0
res=1
for i in range(k):
res=res*(n-i)//(i+1)
return res
res=1
for r in range(11):
print(*["{}".format('{:>5}'.format(int(C(r, i)))) for i in range(res)])
res+=1
Concatenate lists to look at it as number sequence
_ = [int(C(i, j)) for i in range(15) for j in range(15) if int(C(i, j)) != 0]
show_scatter(_)
def stern_n(n):
return n if n<2 else stern_n(n/2) if n%2==0 else stern_n((n - 1)/2) + stern_n((n + 1)/2)
stern_a = [int(stern_n(i)) for i in range(5000)]
show_scatter(stern_a)
from math import gcd
ra = {}
for n in range(1000):
if n<=1:
ra[n]=1
elif gcd(int(ra[n-1]), n)==1:
ra[n]= int(ra[n-1]+n+1)
else:
ra[n] = int(ra[n-1]/gcd(int(ra[n-1]), n))
show_scatter(list(ra.values()))
hofs = {}
for n in range(10000):
if n<=2:
hofs[n] = 1
else:
hofs[n] = hofs[n-hofs[n-1]]+hofs[n-hofs[n-2]]
show_scatter(list(hofs.values()))
hofsconw = {}
for n in range(5000):
if n<=2:
hofsconw[n] = 1
else:
hofsconw[n] = hofsconw[hofsconw[n-1]]+hofsconw[n-hofsconw[n-1]]
show_scatter(list(hofsconw.values()))
hofsconwc = {}
for n in range(1000):
if n<=2:
hofsconwc[n] = 1
else:
hofsconwc[n] = hofsconwc[hofsconwc[n-1]]+hofsconwc[n-hofsconwc[n-2]-1]
show_scatter(list(hofsconwc.values()))
Langton's ant¶
Wikipedia, Langton's ant.
Let the starting square of Langton's ant have coordinates (0, 0), with ant looking in negative x-direction. a(n) is the x-coordinate of the ant after n moves.
0, 0, 1, 1, 0, 0, -1, -1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1...
Let the starting square of Langton's ant have coordinates (0, 0), with the ant looking in negative x-direction. a(n) is the y-coordinate of the ant after n moves.
0, 1, 1, 0, 0, -1, -1, 0, 0, -1, -1, -2, -2, -1, -1, 0, 0, -1, -1, -2...
def ant(n):
steps = [(1, 0), (0, 1), (-1, 0), (0, -1)]
black = set()
x = y = 0
position = [(x, y)]
direction = 2
for _ in range(n):
if (x, y) in black:
black.remove((x, y))
direction += 1
else:
black.add((x, y))
direction -= 1
(dx, dy) = steps[direction%4]
x += dx
y += dy
position.append((x, y))
return position
lang_x, lang_y = zip(*[ant_p for ant_p in ant(15000)])
show_scatter(lang_x)
show_scatter(lang_y)
plt.figure(figsize=(8,8))
plt.scatter(lang_x, lang_y, s=1, c='black', marker="p")
plt.show()
Comments
comments powered by Disqus