View Single Post
Old Feb 1st, 2008, 6:18 PM   #1
Sane
Programming Guru
 
Sane's Avatar
 
Join Date: Apr 2005
Location: Waterloo, Ontario
Posts: 1,885
Rep Power: 5 Sane will become famous soon enough
Send a message via MSN to Sane
Smile Conway's Game Of Life - Programming Challenge

You've all heard of the game of life right? If you haven't, head on over to ol' Wikipedia.

I stumbled across a very interesting, and difficult, programming problem.

Page 12, Origin of Life) http://cemc.math.uwaterloo.ca/ccc/2006/senior.pdf

The only solution I could think up was brute-force. This is due to the fact that there does not seem to be any logical way to find a board's previous setup. Each board only has one next generation, but every generation could have come from a large number of previous generations.

So instead of working backwards from a setup, I worked forwards for each setup. I generated every possible 5x4 grid, by identifying the set and unset bits in every number from 1 to 1048576 (2^(5x4)). For each setup, I computed the next generation, and stored the current generation in a list of possible previous generations for the next generation. Then finally, I ran a depth first search through the backpointers, to find the closest node that contained no backpointer.

Have any ideas for a better way to do it? I'd like to see what you guys and gals got.

C Syntax (Toggle Plain Text)
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4.  
  5. int w, h;
  6. int a, b, c;
  7. unsigned combs;
  8.  
  9. typedef struct self_life {
  10. struct self_life *next; // Linked list
  11. unsigned prev; // Link to last generation
  12. } t_life;
  13.  
  14. int grid[7][6] = {0};
  15. t_life *lives[1048576] = {NULL}; // 2^(4*5) = 1048576
  16. int chalk[1048576] = {0};
  17.  
  18. int merge(int x, int y) {
  19. if(!x) return y;
  20. if(!y) return x;
  21. return x < y ? x : y;
  22. }
  23.  
  24. int get_shortest(unsigned n) {
  25. int shortest = 0;
  26. if (chalk[n]) return 0;
  27. chalk[n] = 1;
  28.  
  29. t_life *life = lives[n];
  30. if (!life) return 1;
  31.  
  32. while (life) {
  33. shortest = merge(get_shortest(life->prev), shortest);
  34. life = life->next;
  35. }
  36. return (shortest) ? (shortest+1) : (0);
  37. }
  38.  
  39. unsigned nextgen() {
  40. unsigned comb = 0;
  41. int x, y, n;
  42. for(y=1;y<=h;y++) {
  43. for(x=1;x<=w;x++) {
  44. comb = (comb << 1);
  45. n = grid[x-1][y-1] + grid[x][y-1] + grid[x+1][y-1] +
  46. grid[x-1][y] + grid[x+1][y] +
  47. grid[x-1][y+1] + grid[x][y+1] + grid[x+1][y+1];
  48. if ( grid[x][y] && n<a) continue;
  49. else if ( grid[x][y] && n>b) continue;
  50. else if (!grid[x][y] && n>c) comb += 1;
  51. else comb += grid[x][y];
  52. }
  53. }
  54. return comb;
  55. }
  56.  
  57. void clean(t_life *node) {
  58. if(!node)return;
  59. clean(node->next);
  60. free(node);
  61. }
  62.  
  63. int main() {
  64.  
  65. unsigned n, t;
  66. int x, y;
  67. char l;
  68. t_life *next_life;
  69.  
  70. freopen("s5.in", "rt", stdin);
  71. // freopen("s5.out", "wt", stdout);
  72. scanf("%d %d %d %d %d\n", &h, &w, &a, &b, &c);
  73.  
  74. combs = pow(2, w*h);
  75. for(n=0;n<combs;n++) {
  76. t=n;
  77. for(y=h;y>0;y--) {
  78. for(x=w;x>0;x--) {
  79. grid[x][y] = (n & 1);
  80. n = (n >> 1);
  81. }
  82. }
  83. n=t;
  84.  
  85. t = nextgen();
  86. next_life = (t_life *)malloc(sizeof(t_life));
  87. next_life->prev = n;
  88. next_life->next = lives[t];
  89. lives[t] = next_life;
  90. }
  91.  
  92. n = 0;
  93. for(y=0;y<h;y++) {
  94. for(x=0;x<w;x++) {
  95. scanf("%c", &l);
  96. n = (n << 1);
  97. n += (l == '*');
  98. }
  99. scanf("\n");
  100. }
  101. printf("%d\n", get_shortest(n)-1);
  102.  
  103. for(n=0;n<combs;n++) clean(lives[n]);
  104. return 0;
  105.  
  106. }

Input File 1
4 5 2 3 2
.****
.****
.****
.****

Output File 1

Input File 2
4 5 2 3 2
**...
*...*
.*..*
**...

Output File 2

Input File 3
4 5 2 3 2
*..**
*....
**..*
.*.*.

Output File 3

Input File 4
3 4 3 4 3
.**.
....
.**.

Output File 4

Input File 5
3 2 2 3 2
**
*.
**

Output File 5
Sane is offline   Reply With Quote