31
\$\begingroup\$

Background

Note: This configuration was co-found by one of our fellow code golf enthusiasts, Zgarb

A 29 year old conjecture by John Conway about the Game of Life was recently solved.

To quote Conway from the linked article:

Indeed, is there a Godlike still-life, one that can only have existed for all time (apart from things that don’t interfere with it)?

That is, a configuration in the game of life that could not have evolved but, if it exists, must have been part of the game's starting condition?

The answer is yes, such still-lifes do exist, and the first one discovered looks like this:

Primordial Still Life

Task

The challenge is simple: output this 22 by 28 primordial still-life as ascii text.

Fewest bytes wins.

Notes:

  • You can choose any characters you like to represent live and dead cells.
  • Trailing whitespace is allowed.
  • Allowed loophole: If you discover a different primordial still life, you may output that.

Here it is with x for dead and for live:

      xxxx  xxxx  xxxx  x   
   xx x  xx x  xx x  xx x   
   x xx  x xx  x xx  x xx   
xxxx  xxxx  xxxx  xxxx  xxx 
  x xx  x xx  x xx  x xx  x 
 x  xx x  xx x  xx x  xx x  
xxxx  xxxx  xxxx  xxxx  xxxx
x  xx x  xx x  xx x  xx x  x
x  x xx  x xx  x xx  x xx  x
xxxx  xxxx  xxxx  xxxx  xxxx
  x xx  x xx  x xx  x xx  x 
 x  xx x  xx x  xx x  xx x  
xxxx  xxxx  xxxx  xxxx  xxxx
x  xx x  xx x  xx x  xx x  x
x  x xx  x xx  x xx  x xx  x
xxxx  xxxx  xxxx  xxxx  xxxx
  x xx  x xx  x xx  x xx  x 
 x  xx x  xx x  xx x  xx x  
 xxx  xxxx  xxxx  xxxx  xxxx
   xx x  xx x  xx x  xx x   
   x xx  x xx  x xx  x xx   
   x  xxxx  xxxx  xxxx      

And here it is with 1 for dead and 0 for live:

0000001111001111001111001000
0001101001101001101001101000
0001011001011001011001011000
1111001111001111001111001110
0010110010110010110010110010
0100110100110100110100110100
1111001111001111001111001111
1001101001101001101001101001
1001011001011001011001011001
1111001111001111001111001111
0010110010110010110010110010
0100110100110100110100110100
1111001111001111001111001111
1001101001101001101001101001
1001011001011001011001011001
1111001111001111001111001111
0010110010110010110010110010
0100110100110100110100110100
0111001111001111001111001111
0001101001101001101001101000
0001011001011001011001011000
0001001111001111001111000000
\$\endgroup\$
17
  • 3
    \$\begingroup\$ An interesting potential loosening of the rules could be to allow any such "primordial", not just this specific one \$\endgroup\$ Jan 18, 2022 at 1:34
  • 3
    \$\begingroup\$ I think the white cells are live and black are dead (the opposite of what is written in the challenge); otherwise it isn't a valid still life in GoL. Doesn't affect the challenge itself, but still. \$\endgroup\$
    – Bubbler
    Jan 18, 2022 at 1:43
  • 6
    \$\begingroup\$ This configuration was co-found by one of our fellow code golf enthusiasts Zgarb \$\endgroup\$
    – Razetime
    Jan 18, 2022 at 3:08
  • 15
    \$\begingroup\$ @Razetime I'll verify that I'm indeed one of the discoverers. Thanks for the shout-out! \$\endgroup\$
    – Zgarb
    Jan 18, 2022 at 12:25
  • 8
    \$\begingroup\$ @null I'm curious, why is it a saddening discovery? \$\endgroup\$
    – justhalf
    Jan 18, 2022 at 20:08

12 Answers 12

13
\$\begingroup\$

Nibbles, 37 33 bytes

?, &" ";3
    ! = $ `. ;~ `/ $ `D -2 
                :;!$ `' \@:.\$\$
             `'<14>>^_$
      `. 5 ~/$~
      ~ >@$
   @$ ~
15a

That's 66 nibbles, each taking half a byte in the binary form.

This could probably be improved, and will definitely be beaten by the things that specialize in ascii art as it uses rotate which nibbles doesn't have as a built in. BTW the trivially binary encoded way is 82 bytes in nibbles (use `D -2 and reverse the result to deal with 0 prefixes).

Run it like this:

> nibbles life.nbl

      aaaa  aaaa  aaaa  a   
   aa a  aa a  aa a  aa a   
   a aa  a aa  a aa  a aa   
aaaa  aaaa  aaaa  aaaa  aaa 
  a aa  a aa  a aa  a aa  a 
 a  aa a  aa a  aa a  aa a  
aaaa  aaaa  aaaa  aaaa  aaaa
a  aa a  aa a  aa a  aa a  a
a  a aa  a aa  a aa  a aa  a
aaaa  aaaa  aaaa  aaaa  aaaa
  a aa  a aa  a aa  a aa  a 
 a  aa a  aa a  aa a  aa a  
aaaa  aaaa  aaaa  aaaa  aaaa
a  aa a  aa a  aa a  aa a  a
a  a aa  a aa  a aa  a aa  a
aaaa  aaaa  aaaa  aaaa  aaaa
  a aa  a aa  a aa  a aa  a 
 a  aa a  aa a  aa a  aa a  
aaaa  aaaa  aaaa  aaaa  aaaa
a  aa a  aa a  aa a  aa a  a
a  a aa  a aa  a aa  a aa  a
aaaa  aaaa  aaaa  aaaa  aaaa
  a aa  a aa  a aa  a aa  a 
 a  aa a  aa a  aa a  aa a  
 aaa  aaaa  aaaa  aaaa  aaaa
   aa a  aa a  aa a  aa a   
   a aa  a aa  a aa  a aa   
   a  aaaa  aaaa  aaaa      

How?

It starts with the basic building block of

# #
 ##
 #

which concatenated as bits is 346 or 15a in hex. This is extracted to space and 'a' with `D -2 and put into groups of 3 with `/ 3

It then rotates this clockwise with transpose of the reverse `'\ and appends the lines with ! <lhs> <rhs> :

Finally this is rotated 180 degrees by reversing it and each line.

This constructs the basic square that you can see in the image with the hairs going out.

a a  a
 aaaa 
 a  aa
aa  a 
 aaaa 
a  a a

This is then replicated 3 times x and y and truncated to the window (14). Then we remove 5,2,1 spaces (generated by iterating /2 starting from 5) from the front using a zip with a custom fn (drop). This is justified with &" " using a size of 3, but really any value <= 14 would work since it also checks the max size of any element. 3 is used because that value is saved and used in 3 other places (saving 1 nibble each in binary form).

      aaaa  aa
   aa a  aa a 
   a aa  a aa 
aaaa  aaaa  aa
  a aa  a aa  
 a  aa a  aa a
aaaa  aaaa  aa
a  aa a  aa a 
a  a aa  a aa 
aaaa  aaaa  aa
  a aa  a aa  
 a  aa a  aa a
aaaa  aaaa  aa
a  aa a  aa a 

The really cool thing is that the final product can also be constructed by a rotation of this. And so this rotation code is saved as a function using ;~. It is a bit awkward to call as it needs to know the return type by calling it on some function before it is finished being defined. But here we want to call it on the result of calling it, which can't be done. So instead I take the result and put it into an if statement on a list ?, it will be true and inside the true clause $ will be the value we want to call the function on. The <14>>^3 code was also repeated and had the same issue, but here I used iteration and took the 3rd element so that the code was applied twice.

Edit: Zgarb confirmed that the 28x28 version is also a still life (it is fully rotationally symmetric). This saved 2 bytes by not having to do <11 to trunctate during the final rotation. Thanks!

\$\endgroup\$
4
  • \$\begingroup\$ Excellent answer. \$\endgroup\$
    – Jonah
    Jan 18, 2022 at 3:55
  • \$\begingroup\$ "will definitely be beaten by the things that specialize in ascii art" you beat charcoal! \$\endgroup\$ Jan 18, 2022 at 13:56
  • \$\begingroup\$ A 28x28 square of this pattern (i.e. the same one as in the question, with similarly rounded corners, but 6 extra rows in the middle) indeed has the same property! \$\endgroup\$
    – Zgarb
    Jan 18, 2022 at 14:54
  • \$\begingroup\$ I like that your "basic building block" is a Game of Life glider :) \$\endgroup\$
    – Lynn
    Jan 20, 2022 at 14:25
11
\$\begingroup\$

Wolfram Language (Mathematica), 131 bytes

Uncompress@"1:eJxTTMoPCt7DxMBgAAaGQIBGAkVjDAyNwJIGhthIuLwBRAM6CZbHYjKMhOrHpR0qj9VqCEnAfEOwPG7tcHlcDiDG/JHufgOC5lOWfsDyWMwHAQA6Moq3"

Try it online!

Uses 1 for dead cells, 0 for living and background (grey) cells.

A boring answer using Mathematica's Uncompress built-in.


Wolfram Language (Mathematica) + my LifeFind package, 147 bytes

<<Life`
SeedRandom@1703
a=ArrayPad[SearchPattern[6,6,Agar->1>0][[1]],{{9,7},{9,13}},Periodic]
Do[a[[i,1;;7-2i]]=1;a=Reverse@a,4,{i,3}]
Print@@@a

Uses 0 for dead cells, 1 for living and background (grey) cells.

Spent some time to find the correct random seed...

I wrote this package to find interesting patterns in Conway's Game of Life and other cellular automata.

SearchPattern[6,6,Agar->1>0] tries to find a 6x6 stable agar. When the random seed is 1703, it finds the following pattern:

 ##   
#  ## 
#  # #
 ##   
  # ##
 #  ##

After that, the code pads the pattern periodically to a 22x28 array, and sets the background cells at the corners to 1 (this part takes so many bytes!), and then prints the result.

\$\endgroup\$
1
  • \$\begingroup\$ Deserves more upvotes. Can't you compress the "more than half of the bytes" though? \$\endgroup\$ Jan 18, 2022 at 6:01
6
\$\begingroup\$

Charcoal, 48 bytes

G↘³↓²↘²↓¹⁵↙³←²↙²←²¹↖³↑²↖²↑¹⁵↗³→²↗²”{“↧n⍘∨)¿UV·÷Σ

Try it online! Link is to verbose version of code. Works by defining a polygon that outlines the configuration and filling it with the 6×6 pattern. (The top left corner actually has coordinates (0, -24) but as the fill is 6×6 it comes to the same thing.)

I also tried a number of other approaches. Simply printing a compressed string took 63 bytes. Printing half of the string twice, rotating in between, took 61 bytes. Filling an array with the pattern and then deleting the corners took 54 bytes. Drawing a rectangle with the pattern and then deleting the corners took 49 bytes.

\$\endgroup\$
6
\$\begingroup\$

Excel, 137 89 characters, 171 bytes

Taylor Raine did their thing.

=BASE(UNICODE(MID("ó㏈ښᩨ֖ᙘ㳳㏎ବⲲፍഴ㳳㏏⚚ᩩ▖ᙙ㳳㏏ବⲲፍഴ㳳㏏⚚ᩩ▖ᙙ㳳㏏ବⲲፍഴᳳ㏏ښᩨ֖ᙘӳ㏀",SEQUENCE(22,2),1)),2,14)

There's a possibility the exact characters won't translate well from Excel to the browser, so here's the encoded string as list of Unicode codes instead (keeping in mind that some are two bytes wide):

243, 13256, 1690, 6760, 1430, 5720, 15603, 13262, 2860, 11442, 4941, 3380, 15603, 13263, 9882, 6761, 9622, 5721, 15603, 13263, 2860, 11442, 4941, 3380, 15603, 13263, 9882, 6761, 9622, 5721, 15603, 13263, 2860, 11442, 4941, 3380, 7411, 13263, 1690, 6760, 1430, 5720, 1267, 13248

The approach takes the (probably not optimized) approach of breaking the desired into chunks and storing those as Unicode characters. The function takes that string, converts each character to its binary equivalent, then breaks it into 2 columns of 14 bit chunks.


Let's start by shortening the formula. We'll refer to this whole mess as string:

"ó㏈ښᩨ֖ᙘ㳳㏎ବⲲፍഴ㳳㏏⚚ᩩ▖ᙙ㳳㏏ବⲲፍഴ㳳㏏⚚ᩩ▖ᙙ㳳㏏ବⲲፍഴᳳ㏏ښᩨ֖ᙘӳ㏀"

Now the formula looks like this:

=BASE(UNICODE(MID(string,SEQUENCE(22,2),1)),2,14)
  • SEQUENCE(22,2) creates an array 2 columns wide and 22 rows tall for 44 total items in the array. string is 44 characters long so that'll fit nicely. It counts over then down like this:
| 1 | 2 |
| 3 | 4 |
| 5 | 6 |
  • MID(string,SEQUENCE(~),1) pulls out each character from string one at a time.
  • UNICODE(MID(~)) converts those characters to their (decimal) unicode number.
  • BASE(UNICODE(~),2,14) converts those decimal numbers to their binary equivalent with each result padded with leading zeros so they're at least 14 bits long.

The end result is two columns of data as shown in the screenshot below. I also split out the results into individual cells and added conditional formatting to show the results visually. The formula is only in cell A1 and the output automatically spills into the range A1:B22.

Result


I don't know what kind of ritual I need to perform to summon Taylor Raine but I'm sure they can improve upon this bloated answer. I already tried using chunks longer than 16 bits but it starts breaking in weird ways.

\$\endgroup\$
3
  • 2
    \$\begingroup\$ I have been summoned! XD You can save a few bytes by defining b as Row(1:39) and using Concat() instead of TextJoin() - that should get you to 126 chars, 202 bytes \$\endgroup\$ Jan 19, 2022 at 4:21
  • 1
    \$\begingroup\$ I'll also note that the Unicode only takes input from the leftmost char in a string, there should be an equivalant solution to this where you have a different a encoded string, and use Unicode(Right(a,b)) in place of Unicode(Mid(a,b,9)). That solution may use characters with a lower byte count than the ones you have here so it may be worth a shot \$\endgroup\$ Jan 19, 2022 at 4:27
  • 1
    \$\begingroup\$ Actually - better yet, if you choose your length for base so that it evenly divides the number of binary chars - in this case, I chose 14 - , you can remove a lot of logic, and possibly even the Let command. Here is an approach that may work depending on what OP accepts as output (89 Char, 171 Bytes) - I'd vote for it being a valid Excel solution tho \$\endgroup\$ Jan 19, 2022 at 5:08
4
\$\begingroup\$

Vyxal, 87 bytes

»ƛUċ≬r¾□ƈ1K↵ẏǐṅȧꜝq6⟩λ∵†⇧↳∨¬ṫ«X¡„q∪[>±∩λxƒẊ[øȧẇ/hAh<∨T⅛⇧¥WnWU°⋎ƈ_S↳‡a∑⋏‡ø¨z≈cƛ÷a»₀Sτ22/⁋

Try it Online!

Naive base compression.

»...»        # Base-255 compressed integer
     ₀Sτ     # Decompress into base 22 with 1s and 0s
        22/⁋ # Split into 22 pieces and join on newlines
\$\endgroup\$
4
\$\begingroup\$

Jelly, 85 bytes

“¦÷fİȷ⁻ƒỌU,ɠṘµINọþọ^°56ß~+Œ:ḟyṘdạʠȷẇḌẆ[ŻṁỤ°8zẉݬ{ḋzỵḣuṄ}Ṗj|ĠỌ½Ɲœiḥd⁷ɦȮʋḢ/iÇØ#¤œ’Bs28Y

Try it online!

Boring compression approach, but hey, it beats Vyxal. Outputs 1 for dead and 0 for live.

How it works

“¦÷...#¤œ’Bs28Y - Main link.
“¦÷...#¤œ’      - Compressed base-250 number; 267895893890769127503254177532545466822034310678965401690230443467397769491824224432265750760013635073235874891500166493638274198855494319824095093907255178782140555126842877012017876031
          B     - Binary
           s28  - Split into chunks of size 28
              Y - Join by newlines

Fun fact, using base 2 is the shortest of all approaches in the form "large compressed number, to base, split"

\$\endgroup\$
4
\$\begingroup\$

05AB1E (legacy), 46 45 bytes

Ƶöb3ô4FDøí‚øJÂí«}¦22£€¦4F28£øíεN3‹i411NèFX0.;

Port of @DarrenSmith's Nibble answer, so make sure to upvote him as well!

Uses the legacy version of 05AB1E to save 2 bytes, since it can zip/transpose with lists of strings, whereas the new version requires a character-matrix instead.

Outputs as a list of lines, with 1/0 for dead/alive respectively.

Try it online (feel free to remove the footer to see the actual output).

Explanation:

Ƶö                  # Push compressed integer 346
  b                 # Convert it to binary: 101011010
   3ô               # Split it into parts of size 3: ["101","011","010"]
4F                  # Loop 4 times:
  D                 #  Duplicate the list of strings
   øí               #  Rotate it 90 degrees clockwise:
   ø                #   Zip/transpose; swapping rows/columns
    í               #   Reverse each inner string
     ‚              #  Pair it together with the original list of strings
      ø             #  Zip/transpose to create pairs of lines
       J            #  Join those inner pairs together to a single line
        Â           #  Bifurcate this list (short for Duplicate & Reverse copy)
         í          #  Reverse each line in the reversed copy
          «         #  Merge these lines to the list
 }                  # Close the loop
                    # (we now have a grid of 48x48 characters)
  ¦                 # Remove the first line
   22£              # Then keep just the first 22 lines
      €             # Map over each remaining line:
       ¦            #  Remove the first character
4F                  # Loop 4 times again:
  28£               #  Keep just (up to) the first 28 characters
  øí                #  Rotate 90 degrees clockwise again
    ε               #  Map over each line:
     N3‹i           #   If this is one of the first three lines:
         411Nè      #    Index the map-index into [4,1,1]
              F     #    Loop that many times:
               X0.; #     Replace the first 1 with a 0
                    # (after which the list of lines is output implicitly)

See this 05AB1E tip of mine (section How to compress large integers?) to understand why Ƶö is 346.

\$\endgroup\$
3
\$\begingroup\$

JavaScript (Node.js), 193 bytes

(x='xxxx  ',y='xx x  ',z='x xx  ',h=`      ${e=x+x+x}x   
 ${g='  '+y+y+y+y} 
 ${c='  '+z+z+z+z} 
${b=e+x+'xxx'} 
${c}x 
 x${g}
${b}x
x${g}x
x${c}x
${b}x
${c}x `)=>h+`
`+[...h].reverse().join``

Try it online!

Here we go...

A lot of variables, dollar signs, curly braces, single quotes, pluses, and a tiny reverse at the end.

\$\endgroup\$
3
\$\begingroup\$

Excel, 111 bytes

AO1 =IF(I1:AJ22,,INDEX(A1:F6,MOD(ROW(6:27),6)+1,MOD(COLUMN(F:AG),6)+1))

Link to Spreadsheet

A1:F6 contains the repeating pattern. I1:AJ22 contains a mask for blank cells. Takes advantage of the spreadsheet structure. The code is 67 bytes, pattern is 20 bytes, mask is 24 bytes for a total of 111 bytes.

Not as clever as @EngineerToast 's answer but it gets the job done.

\$\endgroup\$
2
\$\begingroup\$

JavaScript (ES6),  113  106 bytes

Outputs a string of 0's and 1's.

f=(n=616)=>--n&&((x=n>>8?615-n:n,y=x/28|0,x%=28)>=5>>y&x<24+y+!y&21703951>>x%6+y%6*45%71)+[`
`[n%28]]+f(n)

Try it online!

How?

We use the following formula to get the state of the cell of the \$6\times6\$ pattern at \$(x,y)\$:

21703951 >> x + y * 45 % 71

The cell is alive if the result is odd or dead if it's even.

Notes:

  • Because bitwise operations are limited to 32 bits, we cannot use a 36-bit bitmask.
  • The value of the shift is implicitly reduced modulo \$32\$ as per the ECMAScript specification.

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Ruby, 108 bytes

j=4
28.times{|i|printf"%022b
","O)YO24"[i%6].ord%64*266305&2**(23-k=j.abs)-2**k>>1-(i-4)%24/23
i%23<4&&j-=1}

Try it online!

Prints the pattern rotated 90 degrees (which per comments from OP is allowed because it's still primordial.)

The output is a binary matrix produced line by line as the bitwise AND of the following:

"O)YO24"[i%6].ord%64*266305

Four copies of the repeating pattern (the character encodes the bitmap, the %64 removes spurious bits to the left and the constant 266305 is 100000100000100001 in binary)

2**(23-k=j.abs)-2**k>>1-(i-4)%24/23

This is a mask consisting of a long string of 1's followed by a short string of 0's according to the formula 2**(23-k)-2**k.

As the pattern gets wider, k reduces from 4 to 0, stops reducing, then increases back to 4. This is done by varying j on the last line.

To ensure the spurious output in the 23rd and 24th bits (those on the left) are deleted, the mask must be shifted one place to the right. But to get the pinwheel effect this should not occur on the 4th and 28th row. This is achieved by >>1-(i-4)%24/23

\$\endgroup\$
0
\$\begingroup\$

Perl 5 + -p0513, 95 bytes

Outputs 0s and 1s, transliterated in the link.

$_=unpack"B*",'..<...h.Ye.<..'.',..$.M4..<...i.Ye.<..'x2 .',..$.M4s.<...h.Ye.<..';s/.{28}\K/./g

Try it online!

Explanation

unpacks the binary representation from characters (repeating the duplicated section in the middle using string repetition - x) before inserting newlines every 28 characters. Probably not optimal but, was do-able on mobile!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.