Guest User

Untitled

a guest
Dec 10th, 2018
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.67 KB | None | 0 0
  1. #include <unordered_set>
  2. #include <iostream>
  3. #include <vector>
  4. #include <functional>
  5. #include <array>
  6. #include <iterator>
  7. #include <cstddef>
  8. #include <algorithm>
  9. #include <utility>
  10.  
  11. using Cell = std::pair<int, int>;
  12.  
  13. namespace std {
  14. template<>
  15. struct hash<Cell> {
  16. std::size_t operator()(const Cell& cell) const {
  17. const std::hash<int> hasher;
  18. return hasher(cell.first) & hasher(cell.second);
  19. }
  20. };
  21. }
  22.  
  23. std::ostream& operator<<(std::ostream& out, const Cell& cell) {
  24. out << '(' << cell.first << ',' << cell.second << ')';
  25. return out;
  26. }
  27.  
  28. class Life {
  29. public:
  30. template<typename InputIt>
  31. Life(InputIt begin, InputIt end);
  32.  
  33. void tick();
  34. friend std::ostream& operator<<(std::ostream& out, const Life& life);
  35.  
  36. private:
  37. std::unordered_set<Cell> grid;
  38. std::array<Cell, 8> neighbors_of(const Cell& cell) const;
  39. int n_alive_neighbors(const std::array<Cell, 8>& neighbors) const;
  40. };
  41.  
  42. template<typename InputIt>
  43. Life::Life(InputIt begin, InputIt end)
  44. : grid(begin, end) {}
  45.  
  46. void Life::tick() {
  47. std::vector<Cell> to_die;
  48. std::vector<Cell> to_create;
  49. std::vector<Cell> all_neighbors;
  50.  
  51. // find cells that will die
  52. std::copy_if(grid.begin(), grid.end(), std::back_inserter(to_die),
  53. [&](const auto& cell){
  54. const auto neighbors = neighbors_of(cell);
  55. const auto alive_neighbors = n_alive_neighbors(neighbors);
  56. return alive_neighbors < 2 || alive_neighbors > 3;
  57. });
  58.  
  59. // collect neighbors of all cells
  60. std::for_each(grid.begin(), grid.end(),
  61. [&](const auto& cell){
  62. const auto neighbors = neighbors_of(cell);
  63. std::copy(neighbors.begin(), neighbors.end(), std::back_inserter(all_neighbors));
  64. });
  65.  
  66. // find cells that will be created
  67. std::copy_if(all_neighbors.begin(), all_neighbors.end(), std::back_inserter(to_create),
  68. [&](const auto& cell) {
  69. if (grid.find(cell) != grid.end()) return false;
  70. const auto neighbors = neighbors_of(cell);
  71. const auto alive_neighbors = n_alive_neighbors(neighbors);
  72. return alive_neighbors == 3;
  73. });
  74.  
  75. // kill cells
  76. std::for_each(to_die.begin(), to_die.end(), [&](const auto& cell){ grid.erase(cell); });
  77. // reproduce cells
  78. grid.insert(to_create.begin(), to_create.end());
  79. }
  80.  
  81. std::array<Cell, 8> Life::neighbors_of(const Cell& cell) const {
  82. return { Cell(cell.first - 1, cell.second + 1),
  83. Cell(cell.first, cell.second + 1),
  84. Cell(cell.first + 1, cell.second + 1),
  85. Cell(cell.first + 1, cell.second),
  86. Cell(cell.first + 1, cell.second - 1),
  87. Cell(cell.first, cell.second - 1),
  88. Cell(cell.first - 1, cell.second - 1),
  89. Cell(cell.first - 1, cell.second) };
  90. }
  91.  
  92. int Life::n_alive_neighbors(const std::array<Cell, 8>& neighbors) const {
  93. return std::count_if(neighbors.begin(), neighbors.end(),
  94. [&](const auto& cell){ return grid.find(cell) != grid.end(); });
  95. }
  96.  
  97. std::ostream& operator<<(std::ostream& out, const Life& life) {
  98. if (life.grid.empty()) return out;
  99. out << *life.grid.begin();
  100. std::for_each(std::next(life.grid.begin()), life.grid.end(),
  101. [&](const auto& cell){
  102. out << 'n' << cell;
  103. });
  104. return out;
  105. }
  106.  
  107. int main() {
  108. std::array<Cell, 3> blinker {Cell(-1, 0), Cell(0, 0), Cell(1, 0)};
  109. std::array<Cell, 6> toad {Cell(0, 0), Cell(1, 0), Cell(2, 0),
  110. Cell(1, 1), Cell(2, 1), Cell(3, 1)};
  111.  
  112. Life life(toad.begin(), toad.end());
  113.  
  114. std::cout << life << 'n';
  115. for (int i = 0; i < 6; ++i) {
  116. life.tick();
  117. std::cout << 'n' << life << 'n';
  118. }
  119. }
Add Comment
Please, Sign In to add comment