12 Minor correction.
source | link
  • A(i,b,e) is “∀i∈[b,e).”, B(b,e) is “∀r∈[b,e).∀c∈[b,e).”

  • Observe that after n generations, the board is 2n + 1 square.

  • Because of the symmetry of the board, this only needs to simulate the lower right quadrant, so we allocate an n + 1 square matrix with 1 row & column of padding for the later neighbour lookup (so n + 2).

  • Allocating with calloc lets us simultaneously multiply the width by the height and clear the board to 0 (empty).

  • When looking up a cell by its coordinates (C and D), it uses the absolute value of the row and column (W) to automatically mirror the coordinates.

  • The board is stored as an array of pairs of integers representing the current and previous generations. The integers in question are char so we can avoid sizeof.

  • The generation looked up most frequently (by the neighbour test) is the past generation, so it’s placed at index 0 in the pair so it can be accessed with *.

  • At each generation (g), the current generation is copied over the previous generation using a B loop, then the new generation is generated from the old.

  • Each cell is represented using 0 for empty, 1 for awake, and 162 for sleeping. Counting neighbours was originally a calculation of the number of bits set in the low 4 bits of the cell when the 4 neighbours are shifted & OR’d together as flags (N), butusing 16 for sleeping. But with the observation that an odd number of neighbours is equivalent to exactly 1 neighbour, we can save several characters just using a mask with 1.

  • At the end, the board is printed in full by iterating over the lower right quadrant using the same absolute value coordinate trick, minus padding so we don’t print the outer padding on the board. This is also why the B loop includes an opening curly bracket, because we have the extra newline statement in the outer loop.

  • The ASCII codes conveniently map 0+32 (empty) to a space, 2+32 (sleeping) to ", and 1+32 (awake) to !.

  • A(i,b,e) is “∀i∈[b,e).”, B(b,e) is “∀r∈[b,e).∀c∈[b,e).”

  • Observe that after n generations, the board is 2n + 1 square.

  • Because of the symmetry of the board, this only needs to simulate the lower right quadrant, so we allocate an n + 1 square matrix with 1 row & column of padding for the later neighbour lookup (so n + 2).

  • Allocating with calloc lets us simultaneously multiply the width by the height and clear the board to 0 (empty).

  • When looking up a cell by its coordinates (C and D), it uses the absolute value of the row and column (W) to automatically mirror the coordinates.

  • The board is stored as an array of pairs of integers representing the current and previous generations. The integers in question are char so we can avoid sizeof.

  • The generation looked up most frequently (by the neighbour test) is the past generation, so it’s placed at index 0 in the pair so it can be accessed with *.

  • At each generation (g), the current generation is copied over the previous generation using a B loop, then the new generation is generated from the old.

  • Each cell is represented using 0 for empty, 1 for awake, and 16 for sleeping. Counting neighbours was originally a calculation of the number of bits set in the low 4 bits of the cell when the 4 neighbours are shifted & OR’d together as flags (N), but with the observation that an odd number of neighbours is equivalent to exactly 1 neighbour, we can save several characters using a mask with 1.

  • At the end, the board is printed in full by iterating over the lower right quadrant using the same absolute value coordinate trick, minus padding so we don’t print the outer padding on the board. This is also why the B loop includes an opening curly bracket, because we have the extra newline statement in the outer loop.

  • The ASCII codes conveniently map 0+32 (empty) to a space, 2+32 (sleeping) to ", and 1+32 (awake) to !.

  • A(i,b,e) is “∀i∈[b,e).”, B(b,e) is “∀r∈[b,e).∀c∈[b,e).”

  • Observe that after n generations, the board is 2n + 1 square.

  • Because of the symmetry of the board, this only needs to simulate the lower right quadrant, so we allocate an n + 1 square matrix with 1 row & column of padding for the later neighbour lookup (so n + 2).

  • Allocating with calloc lets us simultaneously multiply the width by the height and clear the board to 0 (empty).

  • When looking up a cell by its coordinates (C and D), it uses the absolute value of the row and column (W) to automatically mirror the coordinates.

  • The board is stored as an array of pairs of integers representing the current and previous generations. The integers in question are char so we can avoid sizeof.

  • The generation looked up most frequently (by the neighbour test) is the past generation, so it’s placed at index 0 in the pair so it can be accessed with *.

  • At each generation (g), the current generation is copied over the previous generation using a B loop, then the new generation is generated from the old.

  • Each cell is represented using 0 for empty, 1 for awake, and 2 for sleeping. Counting neighbours was originally a calculation of the number of bits set in the low 4 bits of the cell when the 4 neighbours are shifted & OR’d together as flags (N), using 16 for sleeping. But with the observation that an odd number of neighbours is equivalent to exactly 1 neighbour, we can save several characters just using a mask with 1.

  • At the end, the board is printed in full by iterating over the lower right quadrant using the same absolute value coordinate trick, minus padding so we don’t print the outer padding on the board. This is also why the B loop includes an opening curly bracket, because we have the extra newline statement in the outer loop.

  • The ASCII codes conveniently map 0+32 (empty) to a space, 2+32 (sleeping) to ", and 1+32 (awake) to !.

11 deleted 1 character in body
source | link
  • A(i,b,e) is “∀i∈[b,e).”, B(b,e) is “∀r∈[b,e).∀c∈[b,e).”

  • Observe that after n generations, the board is 2n + 1 square.

  • Because of the symmetry of the board, this only needs to simulate the lower right quadrant, so we allocate an n + 1 square matrix with 1 row & column of padding for the later neighbour lookup (so n + 2).

  • Allocating with calloc lets us simultaneously multiply the width by the height and clear the board to 0 (empty).

  • When looking up a cell by its coordinates (C and D), it uses the absolute value of the row and column (W) to automatically mirror the coordinates.

  • The board is stored as an array of pairs of integers representing the current and previous generations. The integers in question are char so we can avoid sizeof.

  • The generation looked up most frequently (by the neighbour test) is the past generation, so it’s placed at index 0 in the pair so it can be accessed with *.

  • At each generation (g), the current generation is copied over the previous generation using a B loop, then the new generation is generated from the old.

  • Each cell is represented using 0 for empty, 1 for awake, and 16 for sleeping. Counting neighbours was originally a calculation of the number of bits set in the low 4 bits of the cell when the 4 neighbours are shifted & OR’d together as flags (N), but with the observation that an odd number of neighbours is equivalent to exactly 1 neighbour, we can save several characters using a mask with 1.

  • At the end, the board is printed in full by iterating over the lower right quadrant using the same absolute value coordinate trick, minus padding so we don’t print the outer padding on the board. This is also why the B loop includes an opening curly bracket, because we have the extra newline statement in the outer loop.

  • The ASCII codes conveniently map 0+32 (empty) to a space, 16+322+32 (sleeping) to 0", and 1+32 (awake) to !.

  • A(i,b,e) is “∀i∈[b,e).”, B(b,e) is “∀r∈[b,e).∀c∈[b,e).”

  • Observe that after n generations, the board is 2n + 1 square.

  • Because of the symmetry of the board, this only needs to simulate the lower right quadrant, so we allocate an n + 1 square matrix with 1 row & column of padding for the later neighbour lookup (so n + 2).

  • Allocating with calloc lets us simultaneously multiply the width by the height and clear the board to 0 (empty).

  • When looking up a cell by its coordinates (C and D), it uses the absolute value of the row and column (W) to automatically mirror the coordinates.

  • The board is stored as an array of pairs of integers representing the current and previous generations. The integers in question are char so we can avoid sizeof.

  • The generation looked up most frequently (by the neighbour test) is the past generation, so it’s placed at index 0 in the pair so it can be accessed with *.

  • At each generation (g), the current generation is copied over the previous generation using a B loop, then the new generation is generated from the old.

  • Each cell is represented using 0 for empty, 1 for awake, and 16 for sleeping. Counting neighbours was originally a calculation of the number of bits set in the low 4 bits of the cell when the 4 neighbours are shifted & OR’d together as flags (N), but with the observation that an odd number of neighbours is equivalent to exactly 1 neighbour, we can save several characters using a mask with 1.

  • At the end, the board is printed in full by iterating over the lower right quadrant using the same absolute value coordinate trick, minus padding so we don’t print the outer padding on the board. This is also why the B loop includes an opening curly bracket, because we have the extra newline statement in the outer loop.

  • The ASCII codes conveniently map 0+32 (empty) to a space, 16+32 (sleeping) to 0, and 1+32 (awake) to !.

  • A(i,b,e) is “∀i∈[b,e).”, B(b,e) is “∀r∈[b,e).∀c∈[b,e).”

  • Observe that after n generations, the board is 2n + 1 square.

  • Because of the symmetry of the board, this only needs to simulate the lower right quadrant, so we allocate an n + 1 square matrix with 1 row & column of padding for the later neighbour lookup (so n + 2).

  • Allocating with calloc lets us simultaneously multiply the width by the height and clear the board to 0 (empty).

  • When looking up a cell by its coordinates (C and D), it uses the absolute value of the row and column (W) to automatically mirror the coordinates.

  • The board is stored as an array of pairs of integers representing the current and previous generations. The integers in question are char so we can avoid sizeof.

  • The generation looked up most frequently (by the neighbour test) is the past generation, so it’s placed at index 0 in the pair so it can be accessed with *.

  • At each generation (g), the current generation is copied over the previous generation using a B loop, then the new generation is generated from the old.

  • Each cell is represented using 0 for empty, 1 for awake, and 16 for sleeping. Counting neighbours was originally a calculation of the number of bits set in the low 4 bits of the cell when the 4 neighbours are shifted & OR’d together as flags (N), but with the observation that an odd number of neighbours is equivalent to exactly 1 neighbour, we can save several characters using a mask with 1.

  • At the end, the board is printed in full by iterating over the lower right quadrant using the same absolute value coordinate trick, minus padding so we don’t print the outer padding on the board. This is also why the B loop includes an opening curly bracket, because we have the extra newline statement in the outer loop.

  • The ASCII codes conveniently map 0+32 (empty) to a space, 2+32 (sleeping) to ", and 1+32 (awake) to !.

10 deleted 7 characters in body
source | link

C, 360 354 343 320319

#define A(i,b,e)for(int i=b;i<e;++i)
#define B(b,e)A(r,b,e){A(c,b,e)
#define W(n)(n<0?-(n):n)
#define C(r,c)b[W(r)*s+W(c)]
#define D C(r,c)

q(n){char N,s=n+2,(*b)[2]=calloc(s,2*
s2*s);C(0,0) 
[1]=1;A(g,0,n+1){B(0,s)*D=D[
1];*D=D[1];}B(0,g+2){N=(*C 
(r-1,c)+*C(r+1,c)+*
C+*C(r,c-1)+*C(r,c+1))&1;D[1]=! 
*D?N2:2;N;}}
 }B(2-s,s-1)putchar(*D+32);puts("");}}

Newlines after non-#define lines are just for presentation here, so they’re not counted. I included a wrapper function, so it’s −6 (314313) if the function isn’t counted and you assume n comes from elsewhere. q(10) outputs:

C, 360 354 343 320

#define A(i,b,e)for(int i=b;i<e;++i)
#define B(b,e)A(r,b,e){A(c,b,e)
#define W(n)(n<0?-(n):n)
#define C(r,c)b[W(r)*s+W(c)]
#define D C(r,c)

q(n){char N,s=n+2,(*b)[2]=calloc(s,2*
s);C(0,0)[1]=1;A(g,0,n+1){B(0,s)*D=D[
1];}B(0,g+2){N=(*C(r-1,c)+*C(r+1,c)+*
C(r,c-1)+*C(r,c+1))&1;D[1]=!*D?N:2;}}
 }B(2-s,s-1)putchar(*D+32);puts("");}}

Newlines after non-#define lines are just for presentation here, so they’re not counted. I included a wrapper function, so it’s −6 (314) if the function isn’t counted and you assume n comes from elsewhere. q(10) outputs:

C, 360 354 343 319

#define A(i,b,e)for(int i=b;i<e;++i)
#define B(b,e)A(r,b,e){A(c,b,e)
#define W(n)(n<0?-(n):n)
#define C(r,c)b[W(r)*s+W(c)]
#define D C(r,c)

q(n){char N,s=n+2,(*b)[2]=calloc(s,2*s);C(0,0) 
[1]=1;A(g,0,n+1){B(0,s)*D=D[1];}B(0,g+2){N=(*C 
(r-1,c)+*C(r+1,c)+*C(r,c-1)+*C(r,c+1))&1;D[1]= 
*D?2:N;}}}B(2-s,s-1)putchar(*D+32);puts("");}}

Newlines after non-#define lines are just for presentation here, so they’re not counted. I included a wrapper function, so it’s −6 (313) if the function isn’t counted and you assume n comes from elsewhere. q(10) outputs:

9 added 155 characters in body
source | link
8 Use odd-awake = 1-awake insight from Mathematica answer.
source | link
7 Use odd-awake = 1-awake insight from Mathematica answer.
source | link
6 Explain type choice.
source | link
5 Remove regrets.
source | link
4 Add more description.
source | link
3 Incorporate more suggestions.
source | link
2 Saved a few characters per suggestions.
source | link
1
source | link