elementary_cellular_automaton_generalized.sf 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. #!/usr/bin/ruby
  2. # Daniel "Trizen" Șuteu
  3. # Date: 16 October 2019
  4. # https://github.com/trizen
  5. # Generalization of the elementary cellular automaton, by using `n` color-states and looking at `k` neighbors left-to-right.
  6. # For example, a value of `n = 3` and `k = 2` uses three different color-states and looks at 2 neighbors to the left and 2 neighbors to the right.
  7. # See also:
  8. # https://en.wikipedia.org/wiki/Cellular_automaton
  9. # https://en.wikipedia.org/wiki/Elementary_cellular_automaton
  10. # https://rosettacode.org/wiki/Elementary_cellular_automaton
  11. # YouTube lectures:
  12. # https://www.youtube.com/watch?v=S3tYzCPuVsA
  13. # https://www.youtube.com/watch?v=pGGIE5uhPRQ
  14. func automaton(n, k, callback, rule=120, iter=50, cells=[1]) {
  15. var states = @(^n).variations_with_repetition(2*k + 1)
  16. var digits = rule.digits(n)
  17. var lookup = Array()
  18. for i,s in (states.kv) {
  19. lookup[s.digits2num(n)] = digits[i]\\0
  20. }
  21. var padding = ((iter-cells.len)/2 -> of(0))
  22. cells = [padding..., cells..., padding...]
  23. var len = cells.len
  24. var neighbors_range = @(-k .. k)
  25. (iter/2).times {
  26. callback(cells)
  27. cells[] = lookup[
  28. cells.range.map { |i|
  29. neighbors_range.map {|j| cells[(i+j) % len] }.digits2num(n)
  30. }...
  31. ]
  32. }
  33. return cells
  34. }
  35. var chars = [' ', '*', '.', '#']
  36. say "\n=> 2x1 Automaton"
  37. automaton(2, 1, rule: 90, callback: {|row|
  38. say row.map { chars[_] }.join
  39. })
  40. say "\n=> 3x1 Automaton"
  41. automaton(3, 1, rule: 843693805713, callback: {|row|
  42. say row.map { chars[_] }.join
  43. })
  44. say "\n=> 3x2 Automaton"
  45. automaton(3, 2, rule: 590193390821886729275563552433397050190, iter: 80, callback: {|row|
  46. say row.map { chars[_] }.join
  47. })