Guest User

Untitled

a guest
Aug 15th, 2018
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.69 KB | None | 0 0
  1. use std::fmt;
  2. use std::collections::HashSet;
  3.  
  4. enum Rule {
  5. Death,
  6. Birth,
  7. Live
  8. }
  9.  
  10. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
  11. struct Cell {
  12. x: i32,
  13. y: i32
  14. }
  15.  
  16. impl Cell {
  17. fn new(x: i32, y: i32) -> Self {
  18. Self { x, y }
  19. }
  20.  
  21. fn neighbors(&self) -> [Cell; 8] {
  22. [
  23. Cell::new(self.x - 1, self.y - 1),
  24. Cell::new(self.x - 1, self.y + 0),
  25. Cell::new(self.x - 1, self.y + 1),
  26. Cell::new(self.x + 0, self.y - 1),
  27. Cell::new(self.x + 0, self.y + 1),
  28. Cell::new(self.x + 1, self.y - 1),
  29. Cell::new(self.x + 1, self.y + 0),
  30. Cell::new(self.x + 1, self.y + 1),
  31. ]
  32. }
  33. }
  34.  
  35. #[derive(Clone)]
  36. struct LifeState {
  37. cells: HashSet<Cell>
  38. }
  39.  
  40. impl LifeState {
  41. fn new() -> Self {
  42. Self { cells: HashSet::new() }
  43. }
  44.  
  45. fn set_alive(&self, cell: Cell) -> Self {
  46. let mut updated = self.cells.clone();
  47. updated.insert(cell);
  48. Self { cells: updated }
  49. }
  50.  
  51. fn iterate(&self, rules: &[Rule; 9]) -> Self {
  52. fn update_cell(old_state: &LifeState, new_state: &LifeState, cell: Cell, rules: &[Rule; 9]) -> LifeState {
  53. if new_state.cells.contains(&cell) {
  54. new_state.clone()
  55. } else {
  56. let alive_count = cell.neighbors().iter().filter(|cell| old_state.cells.contains(cell)).count();
  57. match rules[alive_count] {
  58. Rule::Death => new_state.clone(),
  59. Rule::Live => if old_state.cells.contains(&cell) { new_state.set_alive(cell) } else { new_state.clone() },
  60. Rule::Birth => new_state.set_alive(cell),
  61. }
  62. }
  63. }
  64.  
  65. self.cells.iter()
  66. .flat_map(|&cell| cell.neighbors().to_vec().into_iter().chain(vec![cell]).collect::<Vec<_>>())
  67. .fold(LifeState::new(), |new_state, cell|
  68. update_cell(self, &new_state, cell, rules)
  69. )
  70. }
  71. }
  72.  
  73. impl fmt::Display for LifeState {
  74. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  75. if self.cells.is_empty() {
  76. return write!(f, "");
  77. }
  78.  
  79. struct Border {
  80. left: i32,
  81. top: i32,
  82. right: i32,
  83. bottom: i32,
  84. }
  85.  
  86. let mut iter = self.cells.iter().map(|it| Border {
  87. left: it.x, right: it.x,
  88. top: it.y, bottom: it.y,
  89. });
  90. let start = iter.next().unwrap();
  91.  
  92. let border = iter.fold(start, |acc, border|
  93. Border {
  94. left: acc.left.min(border.left), right: acc.right.max(border.right),
  95. top: acc.top.min(border.top), bottom: acc.bottom.max(border.bottom),
  96. }
  97. );
  98.  
  99. (border.top..=border.bottom).for_each(|row| {
  100. (border.left..=border.right).for_each(|col| {
  101. if self.cells.contains(&Cell::new(col, row)) {
  102. write!(f, "X").unwrap();
  103. } else {
  104. write!(f, " ").unwrap();
  105. }
  106. });
  107. write!(f, "\n").unwrap();
  108. });
  109. write!(f, "\n")
  110. }
  111. }
  112.  
  113. fn main() {
  114. let rules = [
  115. Rule::Death, Rule::Death,
  116. Rule::Live,
  117. Rule::Birth,
  118. Rule::Death, Rule::Death, Rule::Death, Rule::Death, Rule::Death,
  119. ];
  120. let glider = LifeState::new()
  121. .set_alive(Cell::new(0, 0))
  122. .set_alive(Cell::new(1, 0))
  123. .set_alive(Cell::new(2, 0))
  124. .set_alive(Cell::new(2, -1))
  125. .set_alive(Cell::new(1, -2));
  126.  
  127. println!("{}", glider);
  128.  
  129. (0..100).fold(glider, |acc, _| {
  130. println!("-------------------------------------------");
  131. let next = acc.iterate(&rules);
  132. println!("{}", next);
  133. next
  134. });
  135. }
Add Comment
Please, Sign In to add comment