# AoCG2021 Leftover: HexaGoL

This challenge is one of the two challenges which were planned for Advent of Code Golf 2021, but didn't fit into the 25-day schedule.

Related to AoC2020 Day 24, Part 2.

Given a binary configuration on a hexagonal grid, output the next generation of Hexagonal Game of Life using AoC rules:

• A living cell survives if it has one or two living neighbors. Otherwise, it turns into a dead cell.
• A dead cell becomes alive if it has exactly two living neighbors. Otherwise, it does not change.

A hexagonal grid can be input and output in any sensible 2D or 3D representation. The input grid has a shape of a regular hexagon. You can choose how to handle the borders: either expand it by one layer, or keep the input size. You can choose the values of alive and dead cells, but they must be consistent across input and output.

You may choose the two distinct values for the alive and dead cells in the input and output, and you may use the value for "dead" or the third value for the necessary padding.

Standard rules apply. The shortest code in bytes wins.

## Example I/O

An input representing the following grid

  . . .
* . . *
* . * * *
* * * .
* . .


could be skewed to the right, giving

    . . .
* . . *
* . * * *
* * * .
* . .


or, as a Python 2D array using 0 and 1 (with zero padding),

[[0, 0, 0, 0, 0],
[0, 1, 0, 0, 1],
[1, 0, 1, 1, 1],
[1, 1, 1, 0, 0],
[1, 0, 0, 0, 0]]


The expected output for this input, if expanding by one layer, is

   . . . .
. . . . .
* * * . * *
. * . . . * .
* . . . . .
* * . . .
. . . .


or, in the same representation,

[[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 0, 1, 1],
[0, 1, 0, 0, 0, 1, 0],
[1, 0, 0, 0, 0, 0, 0],
[1, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0]]


As written above, you're free to choose to not expand the borders, in which case the result would be

  . . .
* * . *
* . . . *
. . . .
* . .
[[0, 0, 0, 0, 0],
[0, 1, 1, 0, 1],
[1, 0, 0, 0, 1],
[0, 0, 0, 0, 0],
[1, 0, 0, 0, 0]]


Example code is here.

• The rule is B2/S12H. Dec 28, 2021 at 1:08
• May I expand the border but remove the surrounding zeroes? Dec 28, 2021 at 1:27
• @alephalpha I'd say no, because the hexagonal region of interest may become unclear when the array representation is cropped. Dec 28, 2021 at 1:40

# Wolfram Language (Mathematica), 73 bytes

CellularAutomaton[{56,{2,{{0,2,2},{2,1,2},{2,2,0}}},{1,1}},#~ArrayPad~1]&


Try it online!

Takes a 2D array (skewed to the right) as input.

# Wolfram Language (Mathematica) + my LifeFind package, 71 bytes

<<Life


Sorry, no TIO for this one.

Takes a 2D array (skewed to the left) as input.

There is a convenient CA function in this package, but it automatically removes the surrounding zeroes.

The main purpose of this package is to find interesting patterns in cellular automata. Here are something I found:

A period 2 oscillator:

. *       * .
* . .  => . . *
. *       * .

A period 3 oscillator:

. * .      * . *      . * .
* . . * => . . . . => * * * *
. * .      * . *      . * .

Another period 3 oscillator:

* . *        . * .        * . *
. . . .      * . . *      . * * .
* . . . * => . . . . . => * * . * *
. . . .      * . . *      . * * .
* . *        . * .        * . *

A period 4 oscillator:

* . *            . * .            * . *            * . *
. . . .          * . . *          . * * .          . * * .
* . . . *        . . . . .        * . . . *        . * * * .
. . . . . .      * . . . . *      . . . . . .      . * . . * .
* . . . . . * => . . . . . . . => * * . . . * * => * * * . * * *
. . . . . .      * . . . . *      . * . . * .      . * * * * .
* . * . *        . * . * .        * . . . *        * . . . *

A period 4 spaceship:

. * . * . . . . .      . . . * . . . . .      . . * . * . . . .      . . * . * . . . .
. . . * * * . . .      . . * . . * . . .      . . . * * * * . .      . . . . . . * . .
. . . * * . . . .      . . . . . * . . .      . . * . * * . . .      . . . . . . * . .
. . * . . . . . .      . * * . . . . . .      . * * * . . . . .      * . . * . . . . .
. * . * . . . . .      . * . * . . . . .      * * . . * . . . .      . . . . * . . . .
. . * * * * . . .      . . . . . * . . .      . * . . * * * . .      . . . . . . * . .
. * * * * . . . .      * . . . . * . . .      * * . . * * . . .      . . . * . . * . .
. * * . . . . * .      . * . . . . * * .      . * . . . . . . *      . . . . * . . * *
. . . * . . * . .      * . . . * * * * .      * . * . * . . * .      * . . . * * * * *
. * * . . * . . .      . * * * * . * . .      . . . . * . * . .      . . . * * . . * .
. * . . . . . . .      * * * . . . . . .      . . . . . . . . .      . . . . . . . . .
. . . . . . . . .  =>  . * * . . . . . .  =>  . . . . . . . . .  =>  . . . . . . . . .
. * . . . . . . .      * * * . . . . . .      . . . . . . . . .      . . . . . . . . .
. * * . . * . . .      . * * * * . * . .      . . . . * . * . .      . . . * * . . * .
. . . * . . * . .      * . . . * * * * .      * . * . * . . * .      * . . . * * * * *
. * * . . . . * .      . * . . . . * * .      . * . . . . . . *      . . . . * . . * *
. * * * * . . . .      * . . . . * . . .      * * . . * * . . .      . . . * . . * . .
. . * * * * . . .      . . . . . * . . .      . * . . * * * . .      . . . . . . * . .
. * . * . . . . .      . * . * . . . . .      * * . . * . . . .      . . . . * . . . .
. . * . . . . . .      . * * . . . . . .      . * * * . . . . .      * . . * . . . . .
. . . * * . . . .      . . . . . * . . .      . . * . * * . . .      . . . . . . * . .
. . . * * * . . .      . . * . . * . . .      . . . * * * * . .      . . . . . . * . .
. * . * . . . . .      . . . * . . . . .      . . * . * . . . .      . . * . * . . . .


# JavaScript, 86 bytes

a=>a.map((r,y)=>r.map((c,x)=>((g=i=>i&&~~a[(i/3|0)+y-1]?.[i%3+x-1]+g(i-1))(7)&~c)==2))


Try it online! (TIO link use ||{} instead of ?. which is not supported on older NodeJS.)

Input boolean matrix with holes as padding. Output in same format.

# APL(Dyalog Unicode), 33 bytes SBCS

({+/1↓¯1↓,⍵}⌺3 3∊¨2+0,¨⊢)(⌽0,⍉)⍣4


Try it on APLgolf!

A partially tacit function that takes a 2D grid of booleans (0s and 1s) skewed to the right, and returns the next step with one cell expanded.

GoL body is mostly from the APLcart entry, modified to make sure the region to be considered is hexagonal, the rules (2/12 instead of 3/23) are encoded correctly, and the entire grid is padded before running the GoL calculation. Padding is easier than not padding here, because otherwise we need to make sure the cells outside the valid hexagonal region are zero.

The hexagonal region trick is what I came up with when AoC2020 day 24 was ongoing. The orientation of the entire grid is part of the trick; this works by looking at a 3x3 square sub-grid and removing the top left and bottom right cells from consideration. This is easier than the other orientation because it suffices to flatten the array and drop the first and the last element in this case, instead of manual reshape or indexing.

. o o
o O o  =>  . o o o O o o o .
o o .

• I think 8↑ should work instead of ¯1↓.
– ovs
Feb 25, 2022 at 9:44

# Charcoal, 50 bytes

⊞υωＷＳ⊞υιＥΦυκ⭆ι⎇⁼λ λ§.*›²↔⁻⁴⁻⊗№⭆³✂⁺  §υ⁺κνμ⁺⁵μ¹*⁼λ*


Try it online! Link is to verbose version of code. Takes input as a list of newline-terminated strings. Explanation:

⊞υω


Push a dummy entry to the predefined empty list to prevent wrapping between the top and bottom.

ＷＳ⊞υι


Input the grid.

ＥΦυκ⭆ι


Map over the grid, excluding the dummy entry.

⎇⁼λ λ


Leave spaces as-is.

§.*›²↔⁻⁴


Output . or * depending on the number of live neighbours. There are three cases which result in a *; live with one live neighbour, dead with two live neighbours, and live with two live neighbours. When you add the liveness of the cell to double the number of neighbours, these three cases are the only cases to map to 3, 4 and 5, therefore the absolute difference from 4 must be less than 2 to output a *.

⁻⊗№⭆³✂⁺  §υ⁺κνμ⁺⁵μ¹*⁼λ*


Count the neighbours by extracting a 3×5 rectangle from the grid centred on the current cell. (Two spaces are prefixed to the grid to avoid negative slice offsets.) Since this already includes the liveness of the current cell, it needs to be subtracted from the double count to produce the value in the range 3-5` from above.