# Just Friends… in code golf

We already have challenges dealing with simulating vanilla Conway's Game of Life, Wireworld and rule 110, but so far none corresponding to a (specific) non-totalistic rule. So here is one.

In June 2000 David Bell described the Just Friends rule, which uses the same square grid and two states as regular Life but has the following transitions:

• A live cell remains live iff it has one or two live neighbours
• A dead cell becomes live iff it has two live neighbours and they are not vertically or horizontally adjacent

The birth restriction prevents the explosive behaviour that would otherwise be seen with birth-on-2-neighbours rules such as Seeds, and instead allows many interesting patterns. I've been searching for small oscillators of every period in this rule using apgsearch, and by that program alone I have found a stable reflector.

Given a Just Friends input pattern and number of generations, output the resulting pattern. The simulation grid, if bounded, must have size at least 40×40 and use either of the following boundary conditions:

• Wrap around like a torus

Pattern input and output may be in any reasonable format, such as binary matrices, lists of live cell positions and RLE.

This is ; fewest bytes wins.

## Test cases

These are in the form

input pattern
number of generations
output pattern.

....
.*..
.**.
....
1
....
.*..
.**.
....

......
..*...
..*...
.*....
......
......
......
12
......
......
......
....*.
....*.
...*..
......

.................
........*........
.................
......*.*........
.................
.**..............
.......**........
.................
.................
.................
.................
.................
.................
59
.................
.................
.................
.................
.........*.*..*..
..............*..
...........*.....
.................
.................
.................
.............*...
.............*...
.................

........................
...........*............
........................
......*....*.*..........
......*.................
.............*...*......
.....*.*...........**...
.................*......
........................
........................
...*.*..................
....................*.*.
.*.*....................
..................*.*...
........................
........................
......*.................
...**...........*.*.....
......*...*.............
.................*......
..........*.*....*......
........................
............*...........
........................
29
........................
............*...........
........................
..........*.*....*......
.................*......
......*...*.............
...**...........*.*.....
......*.................
........................
........................
..................*.*...
.*.*....................
....................*.*.
...*.*..................
........................
........................
.................*......
.....*.*...........**...
.............*...*......
......*.................
......*....*.*..........
........................
...........*............
........................

...............
.*.............
.*.***.........
..*...**.......
.....*..*......
..*...**.......
.*.***.........
.*.............
...............
15
...............
....*..........
....*.*****....
.....*.....**..
..........*..*.
.....*.....**..
....*.*****....
....*..........
...............

...........................
..........*.....*..........
..........*.....*..........
...........................
...........................
...........................
...........................
...........................
.*.......................*.
.*.........**.**.........*.
.*.......................*.
.*.........**.**.........*.
.*.......................*.
...........................
...........................
...........................
...........................
...........................
..........*.....*..........
..........*.....*..........
...........................
83
...........................
..........*.....*..........
..........*.....*..........
...........................
...........................
...........................
...........................
...........................
.*.......................*.
.*.........**.**.........*.
.*.......................*.
.*.........**.**.........*.
.*.......................*.
...........................
...........................
...........................
...........................
...........................
..........*.....*..........
..........*.....*..........
...........................

...........
..*........
..*......*.
....*....*.
.***.....*.
....*....*.
..*......*.
..*........
...........
21
...........
..*........
..*......*.
....*....*.
.***.....*.
....*....*.
..*......*.
..*........
...........

...............
...............
..**.**.*****..
..*.*.*.*****..
...***..**.**..
..*.*.*.*****..
..**.**.*****..
...............
...............
1
...............
....*..*.......
..*...*........
...............
.*.............
...............
..*...*........
....*..*.......
...............

• Mar 3 at 17:23

# JavaScript (ES11), 136 bytes

Expects (n)(binary_matrix) and returns another binary matrix.

n=>g=m=>n--?g(m.map((r,y)=>r.map((v,x)=>[p=c=t=0,...'12587630'].map(d=>t+=(c|=p&(p=m[y+~-(d/3)]?.[x+d%3-1]),d)&&~~p)|6>>t&(v|~t&!c)))):m


Attempt This Online!

### Method

In order to get the neighbors of the cell at $$\(x,y)\$$, we use $$\d\in\{0,1,2,3,5,6,7,8\}\$$ and do:

$$\big(x+(d \bmod 3)-1,y+\lfloor d/3\rfloor-1\big)$$

which maps $$\d\$$ to:

$$\begin{matrix}0&1&2\\3&&5\\6&7&8\end{matrix}$$

More specifically, we start with $$\d=0\$$ and go clockwise, ending with $$\d=0\$$ again. While doing so, we keep track of the number of live neighbors in $$\t\$$ and set $$\c=1\$$ as soon as we detect two consecutive live cells.

The top-left cell is processed twice so that all consecutive pairs are tested (for the flag $$\c\$$), but we make sure to update $$\t\$$ only once. The distinction between the two passes is made possible by using the falsy integer 0 the first time and the truthy character '0' the second time.

Using $$\t\in[0,8]\$$, $$\c\in\{0,1\}\$$ and the current value $$\v\in\{0,1\}\$$ of the cell, we compute the new state with:

//     .-----------------> the LSB is set iff t=1 or t=2
//     |      .----------> always true if the cell is live
//     |      |      .---> true if t is even and c was not set
//   __|_     |    __|__
//  /    \    |   /     \
6 >> t & (v | ~t & !c)


# Charcoal, 66 bytes

ＷＳ⊞υιυＦＮ«ＵＭυ⟦⟧ＦⅉＦＬθ«Ｊλκ⊞§υκ§.*⎇⁼*ＫＫ¬÷⊖№ＫＭ*²›⁼²№ＫＭ*№×²⪫ＫＭω**»⎚Ｅυ⪫κω


Try it online! Link is to verbose version of code. Takes input like the test cases except with a blank line between the pattern and number of generations. Explanation:

ＷＳ⊞υιυ


Read the pattern and write it to the canvas.

ＦＮ«


Repeat for each generation.

ＵＭυ⟦⟧


Start collecting the new pattern.

ＦⅉＦＬθ«Ｊλκ


For each cell...

⊞§υκ§.*⎇⁼*ＫＫ¬÷⊖№ＫＭ*²›⁼²№ＫＭ*№×²⪫ＫＭω**


... apply the generation rules to the cell.

»⎚Ｅυ⪫κω


Write the new pattern to the canvas.

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

<<Life
Last@CellularAutomaton[{RuleNumber@"12/2-a",2,{1,1}},##]&
`