Talk:Abelian sandpile model: Difference between revisions
(→A more readable Python solution.: new section) |
BlackHorse (talk | contribs) (→Incorrect .PPM File created by C code.: new section) |
||
(7 intermediate revisions by 2 users not shown) | |||
Line 24: | Line 24: | ||
This solution is more interactive, as it can also be used in imports on a Python console; plus, it is more readable. |
This solution is more interactive, as it can also be used in imports on a Python console; plus, it is more readable. |
||
<lang python> |
<lang python> |
||
from os import system, name |
|||
from time import sleep |
|||
def clear(): |
|||
if name == 'nt': |
|||
_ = system('cls') |
|||
else: _ = system('clear') |
|||
def exit(): |
|||
import sys |
|||
clear() |
|||
sys.exit() |
|||
def make_area(x, y): |
def make_area(x, y): |
||
global area |
|||
area = [[0]*x for _ in range(y)] |
area = [[0]*x for _ in range(y)] |
||
return area |
return area |
||
def make_sandpile(loc, height): |
def make_sandpile(area, loc, height): |
||
global area |
|||
loc=list(n-1 for n in loc) |
loc=list(n-1 for n in loc) |
||
x, y = loc |
x, y = loc |
||
Line 37: | Line 48: | ||
except IndexError: pass |
except IndexError: pass |
||
def run(): |
def run(area, by_frame=False): |
||
def run_frame(): |
|||
global area |
|||
while any([any([pile>=4 for pile in group]) for group in area]): |
|||
for y_index, group in enumerate(area): |
for y_index, group in enumerate(area): |
||
y = y_index+1 |
y = y_index+1 |
||
Line 49: | Line 59: | ||
else: |
else: |
||
make_sandpile((x |
make_sandpile(area, (x+1, y), 1) |
||
make_sandpile((x |
make_sandpile(area, (x, y+1), 1) |
||
make_sandpile((x, y-1), 1) |
|||
make_sandpile((x, y+1), 1) |
|||
make_sandpile((x, y), -4) |
|||
if x_index-1 >= 0: |
|||
def show_area(): |
|||
make_sandpile(area, (x-1, y), 1) |
|||
global area |
|||
if y_index-1 >= 0: |
|||
display = [' '.join([str(item) for item in group]) for group in area] |
|||
make_sandpile(area, (x, y-1), 1) |
|||
[print(i) for i in display] |
|||
make_sandpile(area, (x, y), -4) |
|||
while any([any([pile>=4 for pile in group]) for group in area]): |
|||
if by_frame: |
|||
clear() |
|||
run_frame() |
|||
if by_frame: |
|||
show_area(area); sleep(.05) |
|||
def show_area(area): |
|||
display = [' '.join([str(item) if item else ' ' for item in group]) |
|||
for group in area] |
|||
[print(i) for i in display] |
|||
clear() |
|||
if __name__ == '__main__': |
if __name__ == '__main__': |
||
area = make_area(10, 10) |
area = make_area(10, 10) |
||
print('\nBefore:') |
print('\nBefore:') |
||
show_area() |
show_area(area) |
||
make_sandpile((5, 5), 64); run() |
make_sandpile(area, (5, 5), 64); run(area) |
||
print('\nAfter:') |
print('\nAfter:') |
||
show_area() |
show_area(area) |
||
</lang> |
</lang> |
||
Output: |
|||
<lang> |
|||
Before: |
|||
0 0 0 0 0 0 0 0 0 0 |
|||
0 0 0 0 0 0 0 0 0 0 |
|||
0 0 0 0 0 0 0 0 0 0 |
|||
0 0 0 0 0 0 0 0 0 0 |
|||
0 0 0 0 0 0 0 0 0 0 |
|||
0 0 0 0 0 0 0 0 0 0 |
|||
0 0 0 0 0 0 0 0 0 0 |
|||
0 0 0 0 0 0 0 0 0 0 |
|||
0 0 0 0 0 0 0 0 0 0 |
|||
0 0 0 0 0 0 0 0 0 0 |
|||
After: |
|||
0 0 0 0 0 0 0 0 0 0 |
|||
0 0 0 1 2 1 0 0 0 0 |
|||
0 0 2 2 2 2 2 0 0 0 |
|||
0 1 2 2 2 2 2 1 0 0 |
|||
0 2 2 2 0 2 2 2 0 0 |
|||
0 1 2 2 2 2 2 1 0 0 |
|||
0 0 2 2 2 2 2 0 0 0 |
|||
0 0 0 1 2 1 0 0 0 0 |
|||
0 0 0 0 0 0 0 0 0 0 |
|||
0 0 0 0 0 0 0 0 0 0 |
|||
</lang> |
|||
> You can just add your Python draft as an additional variant. As the Rosetta Code landing page puts it: 'to aid a person with a grounding in one approach to a problem in learning another'. The goal is to provide comparative insight rather than to construct any claim to exclusive canonicity [[User:Hout|Hout]] ([[User talk:Hout|talk]]) 21:53, 15 January 2020 (UTC) |
|||
Thanks for the information, I have added my code underneath the original. |
|||
== Incorrect .PPM File created by C code. == |
|||
The current C code uses directly code directly copied from ppm Bitmap Writing page. |
|||
This consequently leads to a useless .ppm image created. |
|||
The following lines of code need to be replaced: |
|||
for(i=0;i<sandPileEdge;i++){ |
|||
:for(j=0;j<sandPileEdge;j++){ |
|||
::colour[0] = (sandPile[i][j] + i)%256; |
|||
::colour[1] = (sandPile[i][j] + j)%256; |
|||
::colour[2] = (sandPile[i][j] + i*j)%256; |
|||
:;fwrite(colour,1,3,fp); |
|||
:} |
|||
} |
|||
with these to get an image similar in style to the images on the wikipedia page, however any different combination of RGB values will serve. |
|||
for(i=0;i<sandPileEdge;i++){ |
|||
:for(j=0;j<sandPileEdge;j++){ |
|||
::if (sandPile[i][j] == 0){ |
|||
:::colour[0] = 0; |
|||
:::colour[1] = 0; |
|||
:::colour[2] = 0; |
|||
::} else if (sandPile[i][j] == 1){ |
|||
:::colour[0] = 0; |
|||
:::colour[1] = 255; |
|||
:::colour[2] = 0; |
|||
::} else if (sandPile[i][j] == 2){ |
|||
:::colour[0] = 255; |
|||
:::colour[1] = 0; |
|||
:::colour[2] = 255; |
|||
::} else if (sandPile[i][j] == 3){ |
|||
:::colour[0] = 255; |
|||
:::colour[1] = 215; |
|||
:::colour[2] = 0; |
|||
::}; |
|||
::fwrite(colour,1,3,fp); |
|||
:}; |
|||
}; |
|||
[[User:BlackHorse|BlackHorse]] ([[User talk:BlackHorse|talk]]) |
Latest revision as of 09:19, 27 May 2023
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> from os import system, name from time import sleep
def clear(): if name == 'nt': _ = system('cls') else: _ = system('clear')
def exit(): import sys clear() sys.exit()
def make_area(x, y): area = [[0]*x for _ in range(y)] return area
def make_sandpile(area, loc, height): loc=list(n-1 for n in loc) x, y = loc
try: area[y][x]+=height except IndexError: pass
def run(area, by_frame=False): def run_frame(): 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(area, (x+1, y), 1) make_sandpile(area, (x, y+1), 1)
if x_index-1 >= 0: make_sandpile(area, (x-1, y), 1) if y_index-1 >= 0: make_sandpile(area, (x, y-1), 1)
make_sandpile(area, (x, y), -4)
while any([any([pile>=4 for pile in group]) for group in area]): if by_frame: clear() run_frame() if by_frame: show_area(area); sleep(.05)
def show_area(area): display = [' '.join([str(item) if item else ' ' for item in group]) for group in area] [print(i) for i in display]
clear() if __name__ == '__main__': area = make_area(10, 10) print('\nBefore:') show_area(area) make_sandpile(area, (5, 5), 64); run(area) print('\nAfter:') show_area(area) </lang>
Output: <lang> Before: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
After: 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1 0 0 0 0 0 0 2 2 2 2 2 0 0 0 0 1 2 2 2 2 2 1 0 0 0 2 2 2 0 2 2 2 0 0 0 1 2 2 2 2 2 1 0 0 0 0 2 2 2 2 2 0 0 0 0 0 0 1 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 </lang>
> You can just add your Python draft as an additional variant. As the Rosetta Code landing page puts it: 'to aid a person with a grounding in one approach to a problem in learning another'. The goal is to provide comparative insight rather than to construct any claim to exclusive canonicity Hout (talk) 21:53, 15 January 2020 (UTC)
Thanks for the information, I have added my code underneath the original.
Incorrect .PPM File created by C code.
The current C code uses directly code directly copied from ppm Bitmap Writing page. This consequently leads to a useless .ppm image created.
The following lines of code need to be replaced:
for(i=0;i<sandPileEdge;i++){
- for(j=0;j<sandPileEdge;j++){
- colour[0] = (sandPile[i][j] + i)%256;
- colour[1] = (sandPile[i][j] + j)%256;
- colour[2] = (sandPile[i][j] + i*j)%256;
- fwrite(colour,1,3,fp);
- }
}
with these to get an image similar in style to the images on the wikipedia page, however any different combination of RGB values will serve.
for(i=0;i<sandPileEdge;i++){
- for(j=0;j<sandPileEdge;j++){
- if (sandPile[i][j] == 0){
- colour[0] = 0;
- colour[1] = 0;
- colour[2] = 0;
- } else if (sandPile[i][j] == 1){
- colour[0] = 0;
- colour[1] = 255;
- colour[2] = 0;
- } else if (sandPile[i][j] == 2){
- colour[0] = 255;
- colour[1] = 0;
- colour[2] = 255;
- } else if (sandPile[i][j] == 3){
- colour[0] = 255;
- colour[1] = 215;
- colour[2] = 0;
- };
- fwrite(colour,1,3,fp);
- if (sandPile[i][j] == 0){
- };
};