Talk:Abelian sandpile model: Difference between revisions

From Rosetta Code
Content added Content deleted
(How to optimize ?)
 
Line 19: Line 19:
011
011
rotated 3 times by 90° around the origin.</pre>
rotated 3 times by 90° around the origin.</pre>

== A more readable Python solution. ==

This solution is more interactive, as it can also be used in imports on a Python console; plus, it is more readable.
<lang python>
def make_area(x, y):
global area
area = [[0]*x for _ in range(y)]
return area

def make_sandpile(loc, height):
global area
loc=list(n-1 for n in loc)
x, y = loc

try: area[y][x]+=height
except IndexError: pass
def run():
global area
while any([any([pile>=4 for pile in group]) for group in area]):
for y_index, group in enumerate(area):
y = y_index+1

for x_index, height in enumerate(group):
x = x_index+1

if height < 4: continue

else:
make_sandpile((x-1, y), 1)
make_sandpile((x+1, y), 1)
make_sandpile((x, y-1), 1)
make_sandpile((x, y+1), 1)
make_sandpile((x, y), -4)

def show_area():
global area
display = [' '.join([str(item) for item in group]) for group in area]
[print(i) for i in display]


if __name__ == '__main__':
area = make_area(10, 10)
print('\nBefore:')
show_area()
make_sandpile((5, 5), 64); run()
print('\nAfter:')
show_area()
</lang>

Revision as of 23:34, 14 January 2020

optimizations ?

the figures are 8xtimes symmetric like drawing a circle. But how to calculate the generating triangle. See 16->

00100
02120
11011
02120
00100

the origin is the starting point of the sandpile.
is rotated and mirrored of
X20
011
mirrored at main diagonal
100
120
011
rotated 3 times by 90° around the origin.

A more readable Python solution.

This solution is more interactive, as it can also be used in imports on a Python console; plus, it is more readable. <lang python> def make_area(x, y): global area area = [[0]*x for _ in range(y)] return area

def make_sandpile(loc, height): global area loc=list(n-1 for n in loc) x, y = loc

try: area[y][x]+=height except IndexError: pass

def run(): global area while any([any([pile>=4 for pile in group]) for group in area]): for y_index, group in enumerate(area): y = y_index+1

for x_index, height in enumerate(group): x = x_index+1

if height < 4: continue

else: make_sandpile((x-1, y), 1) make_sandpile((x+1, y), 1) make_sandpile((x, y-1), 1) make_sandpile((x, y+1), 1) make_sandpile((x, y), -4)

def show_area(): global area display = [' '.join([str(item) for item in group]) for group in area] [print(i) for i in display]


if __name__ == '__main__': area = make_area(10, 10) print('\nBefore:') show_area() make_sandpile((5, 5), 64); run() print('\nAfter:') show_area() </lang>