formations/python-perfs/examples/sandpile1.py

45 lines
1.1 KiB
Python

import sys
# Can handle 10k sand grains in 2s.
def show_terrain(terrain):
width = len(terrain)
for x in range(width):
for y in range(width):
print(" ·●⬤#"[min(4, terrain[x][y])], end="")
print()
def apply_gravity(terrain):
"""
$ python -m pyperf timeit --fast -s 'from examples.sandpile1 import main' 'main(10_000, False)'
...........
Mean +- std dev: 11.1 sec +- 0.2 sec
"""
width = len(terrain)
did_someting = False
for x in range(width):
for y in range(width):
if terrain[x][y] >= 4:
terrain[x][y] -= 4
terrain[x - 1][y] += 1
terrain[x + 1][y] += 1
terrain[x][y + 1] += 1
terrain[x][y - 1] += 1
did_someting = True
return did_someting
def main(height, show=True):
width = int(height ** .5) + 1
terrain = [[0] * width for _ in range(width)]
terrain[width // 2][width // 2] = height
while apply_gravity(terrain):
pass
if show:
show_terrain(terrain)
if __name__ == "__main__":
main(int(sys.argv[1]))