sandpiles.jl 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. #!/usr/bin/julia
  2. # Simulate the toppling of sandpiles.
  3. # See also:
  4. # https://en.wikipedia.org/wiki/Abelian_sandpile_model
  5. # https://www.youtube.com/watch?v=1MtEUErz7Gg -- ‎Sandpiles - Numberphile
  6. # https://www.youtube.com/watch?v=diGjw5tghYU -- ‎Coding Challenge #107: Sandpiles (by Daniel Shiffman)
  7. using Images
  8. function topple(plane, nextplane, width, height)
  9. for y in 1:height, x in 1:width
  10. pile = plane[y,x]
  11. if (pile < 4)
  12. nextplane[y,x] = pile
  13. end
  14. end
  15. for y in 2:height-1, x in 2:width-1
  16. pile = plane[y,x]
  17. if (pile >= 4)
  18. nextplane[y, x] += pile - 4
  19. nextplane[y - 1, x] += 1
  20. nextplane[y + 1, x] += 1
  21. nextplane[y, x - 1] += 1
  22. nextplane[y, x + 1] += 1
  23. end
  24. end
  25. return nextplane
  26. end
  27. function contains_four(plane, width, height)
  28. for y in 1:height, x in 1:width
  29. if (plane[y,x] >= 4)
  30. return true
  31. end
  32. end
  33. return false
  34. end
  35. function sandpiles()
  36. w, h = 240, 240
  37. plane = zeros(Int64, h, w)
  38. plane[div(h,2), div(w,2)] = 10^5
  39. while (contains_four(plane, w, h))
  40. nextplane = zeros(Int64, h, w)
  41. plane = topple(plane, nextplane, w, h)
  42. end
  43. colors = [
  44. RGB{Float64}(0, 0, 0),
  45. RGB{Float64}(0, 0, 255),
  46. RGB{Float64}(0, 255, 0),
  47. RGB{Float64}(255, 255, 255),
  48. ]
  49. background = RGB{Float64}(0, 0, 0)
  50. img = zeros(RGB{Float64}, h, w)
  51. for y in 1:h, x in 1:w
  52. pile = plane[y,x]
  53. col = background
  54. if (pile <= 3)
  55. col = colors[pile+1]
  56. end
  57. img[y,x] = col
  58. end
  59. img = map(clamp01nan, img)
  60. return img
  61. end
  62. img = sandpiles()
  63. println("Saving image...")
  64. save("sandpiles.png", img)