Produce this square snowflake.
XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX
XX X X X X X X X X X X X X X X XX
X XXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXX X
XX X X X X X X X X X X X X XX
X X XXX XXXX XXXX XXXX XXXX XXXX XXXX XXX X X
XXX XX X X X X X X X X X X X X X X X X X X XX XXX
X X XXXX XXX XXX XXXXX XXX XXX XXXXX XXX XXX XXXX X X
XX X X X X X X XX
X X X XXX XXX XXX XXXX XXXX XXX XXX XXX X X X
XXX XXX XX X X X X X X X X X X X X XX XXX XXX
X X X X XXXX XXXXX XXX XXX XXX XXX XXXXX XXXX X X X X
XXXXX XX X X X X X X X X X X XX XXXXX
X X X X X XXX XXXX XXXXX XXXXX XXXX XXX X X X X X
XXXX XX XXX XX X X X X X X X X X X X X XX XXX XX XXXX
X X X XXXX XXX XX XXXX XXXX XX XXX XXXX X X X
XX XX
X X X X XXX XXX XXX XXX XXX XXX XXX XXX X X X X
XXXX XX XXX XXX XX X X X X X X XX XXX XXX XX XXXX
X X X X X X X XXXX XXXXX XXXXX XXXX X X X X X X X
XXXXX XXXXX XX X X X X XX XXXXX XXXXX
X X X X X X X X XXX XXXX XXXX XXX X X X X X X X X
XXX XXX XXXX XX XXX XX X X X X X X XX XXX XX XXXX XXX XXX
X X X X X X XXXX XXX XXX XXXX X X X X X X
XXXXX XXX XX XX XXX XXXXX
X X X X X X X X X XXX XXX XXX XXX X X X X X X X X X
XXX XXXX XXXX XXX XXX XX X X XX XXX XXX XXXX XXXX XXX
X X X X X X X X X XXXX XXXX X X X X X X X X X
XXXXX XXXXX XXXXX XX XX XXXXX XXXXX XXXXX
X X X X X X X X X X XXX XXX X X X X X X X X X X
XXXX XXX XXX XX XXXX XX XXX XX XX XXX XX XXXX XX XXX XXX XXXX
X X X X XXX X X X X
XXX
X X X X XXX X X X X
XXXX XXX XXX XX XXXX XX XXX XX XX XXX XX XXXX XX XXX XXX XXXX
X X X X X X X X X X XXX XXX X X X X X X X X X X
XXXXX XXXXX XXXXX XX XX XXXXX XXXXX XXXXX
X X X X X X X X X XXXX XXXX X X X X X X X X X
XXX XXXX XXXX XXX XXX XX X X XX XXX XXX XXXX XXXX XXX
X X X X X X X X X XXX XXX XXX XXX X X X X X X X X X
XXXXX XXX XX XX XXX XXXXX
X X X X X X XXXX XXX XXX XXXX X X X X X X
XXX XXX XXXX XX XXX XX X X X X X X XX XXX XX XXXX XXX XXX
X X X X X X X X XXX XXXX XXXX XXX X X X X X X X X
XXXXX XXXXX XX X X X X XX XXXXX XXXXX
X X X X X X X XXXX XXXXX XXXXX XXXX X X X X X X X
XXXX XX XXX XXX XX X X X X X X XX XXX XXX XX XXXX
X X X X XXX XXX XXX XXX XXX XXX XXX XXX X X X X
XX XX
X X X XXXX XXX XX XXXX XXXX XX XXX XXXX X X X
XXXX XX XXX XX X X X X X X X X X X X X XX XXX XX XXXX
X X X X X XXX XXXX XXXXX XXXXX XXXX XXX X X X X X
XXXXX XX X X X X X X X X X X XX XXXXX
X X X X XXXX XXXXX XXX XXX XXX XXX XXXXX XXXX X X X X
XXX XXX XX X X X X X X X X X X X X XX XXX XXX
X X X XXX XXX XXX XXXX XXXX XXX XXX XXX X X X
XX X X X X X X XX
X X XXXX XXX XXX XXXXX XXX XXX XXXXX XXX XXX XXXX X X
XXX XX X X X X X X X X X X X X X X X X X X XX XXX
X X XXX XXXX XXXX XXXX XXXX XXXX XXXX XXX X X
XX X X X X X X X X X X X X XX
X XXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXX X
XX X X X X X X X X X X X X X X XX
XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX
TIO link, and a more square spaced-out version.
How it's made
You start with a initial crystal (cell) at the center. Then, a new crystal is formed simultaneously at each empty space that touches exactly one existing crystal, looking at the 8 cells orthogonally or diagonally adjacent to it. Crystals remain indefinitely. Here is the snowflake after 3 steps, marking the crystals added at each step.
333 333
32 23
3 111 3
101
3 111 3
32 23
333 333
We continue this for 31 steps, making a 63-by-63 snowflake with 1833 crystals.
This process is the Life-like (totalistic) cellular automaton B1/S012345678, also known as H-trees or Christmas Life.
Output
Output or print in any 2D array format with two distinct entries for crystal and empty space, or anything that displays as such. The grid must by exactly 63 by 63, that is having no wasted margin. It's fine to have trailing spaces for non-crystals or jagged arrays truncated to the last crystal in each row. A trailing newline is also OK.
Bit representations are not valid unless they display with two distinct symbols for the bits by default.
I also posted this challenge on Anarchy Golf. It requires a strict output format of the ASCII art above of X's and spaces.
17 Answers 17
MATL, (削除) 21 (削除ここまで) 19 bytes
l31:"TTYat3Y6Z+1=Y|
Explanation
l % Push 1 (this is the initial ×ばつ1 array)
31:" % Do 31 times
TTYa % Extend with a frame of zeros in 2D
t % Duplicate
3Y6 % Push [1 1 1; 1 0 1; 1 1 1] (8-neighbourhood; predefined literal)
Z+ % 2D convolution, maintaining size. This gives the number of active
% neighbours for each cell
1= % Equal to 1? Element-wise
Y| % Logical OR
% End (implicit)
% Display (implicit)
-
2\$\begingroup\$ @Downvoter: any suggestion for improvement? What problem do you find with my answer? \$\endgroup\$Luis Mendo– Luis Mendo2020年05月13日 22:00:37 +00:00Commented May 13, 2020 at 22:00
-
2\$\begingroup\$ Someone's just jealous ;) \$\endgroup\$Patrick Roberts– Patrick Roberts2020年05月14日 14:41:32 +00:00Commented May 14, 2020 at 14:41
APL (Dyalog Unicode), (削除) 31 (削除ここまで) (削除) 29 (削除ここまで) 27 bytes
(⊢∨1={≢⍸⍵}⌺3 3)×ばつ⍨32=⍳63
-4 bytes thanks to @ngn.
A full program that prints a boolean matrix.
How it works
(⊢∨1={≢⍸⍵}⌺3 3)×ばつ⍨32=⍳63
32=⍳63 ⍝ A 63-length vector whose center element is 1
⍝ and the rest is 0
×ばつ⍨ ⍝ Outer product self by ×ばつ, giving initial state of CA
( )⍣≡ ⍝ Run the cellular automaton until it stabilizes...
{≢⍸⍵}⌺3 3 ⍝ Count ones in 3-by-3 subgrids
1= ⍝ Test if the ×ばつ3 subgrid has exactly one alive cell
⊢∨ ⍝ or the cell is already alive
-
\$\begingroup\$ This is very nice. \$\endgroup\$Jonah– Jonah2020年05月12日 02:05:53 +00:00Commented May 12, 2020 at 2:05
-
1\$\begingroup\$
¯63↑32↑1->32=⍳63\$\endgroup\$ngn– ngn2020年05月12日 02:10:41 +00:00Commented May 12, 2020 at 2:10 -
\$\begingroup\$
{5⌷⍵∨1=+/⍵}∘,⌺3 3->(⊢∨1={+/,⍵}⌺3 3)\$\endgroup\$ngn– ngn2020年05月12日 02:18:32 +00:00Commented May 12, 2020 at 2:18 -
\$\begingroup\$
+/,⍵(in mine) ->≢⍸⍵\$\endgroup\$ngn– ngn2020年05月12日 02:27:04 +00:00Commented May 12, 2020 at 2:27
Python 2 with scipy, 105 bytes
from scipy.signal import*
A=[1],
K=1,1,1
exec"A=convolve2d(A,[K,(1,9,1),K]);A=(A>8)+(A==1)+0;"*31
print A
Use convolution to grow the array. The convolution kernel used is:
[[1, 1, 1]
[1, 9, 1]
[1, 1, 1]]
and the criteria for living cell is:
c >= 9 or c==1
aka when the cell is already living or when there is exactly 1 neighbor.
Note that NumPy by default only prints a summary of a large array, like so:
[[1 1 1 ... 1 1 1]
[1 1 0 ... 0 1 1]
[1 0 1 ... 1 0 1]
...
[1 0 1 ... 1 0 1]
[1 1 0 ... 0 1 1]
[1 1 1 ... 1 1 1]]
Thus, I have to call numpy.set_printoptions to force Numpy to prints the entire array. This part is not included in the byte count, since I dont't think it's relevant to the actual problem.
This 114 bytes function returns the array instead of printing it out, thus circumventing the print option problem.
-
1\$\begingroup\$ This truncated printing is fine, since it's the default numpy way to render arrays. I added "with scipy" to the header as per the convention that's it being installed is akin to a language version, as I expressed here. \$\endgroup\$xnor– xnor2020年05月12日 01:36:08 +00:00Commented May 12, 2020 at 1:36
-
1\$\begingroup\$ The
exec * 31trick is amazing ! \$\endgroup\$Ciprian Tomoiagă– Ciprian Tomoiagă2020年05月13日 22:11:23 +00:00Commented May 13, 2020 at 22:11 -
\$\begingroup\$ You might be interested in trying the anarchy version of this challenge that I posted \$\endgroup\$xnor– xnor2020年05月20日 09:15:40 +00:00Commented May 20, 2020 at 9:15
-
\$\begingroup\$ @xnor Thanks, I'll take a look. I've never done anarchy golf before, but it seems like the output is more restrictive. I might have to try a different approach. \$\endgroup\$Surculose Sputum– Surculose Sputum2020年05月21日 01:34:26 +00:00Commented May 21, 2020 at 1:34
J, 38 34 bytes
3 3(1 e.+/,4&{)@,;._3^:31*/~0=i:62
-3 bytes thanks to ngn
-1 byte thanks to Bubbler
Core ideas taken from Bubbler's elegant APL answer -- be sure to upvote him.
This was an experiment to see how close I could get using J, which lack's APL diamond operator and so is at a disadvantage.
Instead, J has SubArrays, which requires you to manually add the padding of zeros. I opted here to add all the padding at once, up front: a 125 x 125 matix of zeros with a 1 in the center.
After each iteration, we'll lose 2 from our dimension, so after 31 iterations we'll be down to 63 x 63, which is what we need.
-
\$\begingroup\$
7812=i.,~125->*/~0=i:62\$\endgroup\$ngn– ngn2020年05月12日 04:07:57 +00:00Commented May 12, 2020 at 4:07 -
\$\begingroup\$ Ofc! Thanks @ngn. \$\endgroup\$Jonah– Jonah2020年05月12日 04:17:52 +00:00Commented May 12, 2020 at 4:17
-
\$\begingroup\$ You can remove the
]between^:31and*/~. \$\endgroup\$Bubbler– Bubbler2020年05月12日 04:18:56 +00:00Commented May 12, 2020 at 4:18 -
\$\begingroup\$ Was just making that change as you commented :) \$\endgroup\$Jonah– Jonah2020年05月12日 04:22:32 +00:00Commented May 12, 2020 at 4:22
-
1
JavaScript (ES6), (削除) 149 138 136 (削除ここまで) 135 bytes
Returns a binary matrix.
f=k=>k>31?m:f(-~k,m=(k?m:a=[...Array(63)]).map((r=a,y)=>r.map((v,x)=>k?v|!~(g=d=>d--&&g(d)-~~(m[y+~-(d/3)]||0)[x-1+d%3])(9):x*y==961)))
Commented
The same map() loops are used to initialize the 63x63 binary matrix m[] and to recursively update it. Doing a separate initialization of m[] before entering the recursion would cost more bytes.
f = k => // f is a recursive function taking a counter k
k > 31 ? // if k is greater than 31:
m // stop recursion and return m[]
: // else:
f( // do a recursive call:
-~k, // increment k
m = ( // update m[]
k ? m // if this is not the first iteration, use m[]
: a = [...Array(63)] // otherwise, use a vector a[] of 63 entries
).map((r = a, y) => // for each row r[] at position y, using a[]
// as a fallback for the first iteration:
r.map((v, x) => // for each value v at position x:
k ? // if this is not the first iteration:
v | !~( // if v is already set, let it set
g = d => // or use the result of the recursive
// function g taking a direction d
d-- && // decrement d; stop if it's zero
g(d) - // recursive call
~~( // subtract 1 if the cell at ...
m[y + ~-(d / 3)] // ... y + dy ...
|| 0 //
)[x - 1 + d % 3] // ... and x + dx is set
)(9) // initial call to g with d = 9
: // else (first iteration):
x * y == 961 // set the cell iff x = y = 31 (because 31
// is prime, it's safe to test xy = 312)
) // end of inner map()
) // end of outer map()
) // end of recursive call
T-SQL, (削除) 330 (削除ここまで) (削除) 266 (削除ここまで) 232 bytes
This takes a long time to execute(reason: must be something wrong with the question).
-22 Bytes thanks to @RossPresser
SELECT top 3969' 'z,IDENTITY(INT,0,1)i,63x
INTO t FROM sys.messages
WHILE @@ROWCOUNT>0UPDATE
t SET z=1WHERE(SELECT SUM(1*z)FROM t x
WHERE(t.i/x-i/x)/2=0and(t.i%x-i%x)/2=0)=1or i=1984and''=z
SELECT string_agg(z,'')FROM t GROUP BY i/x
This will execute in Microsoft SQL Server 2017 or higher. Try it online on dbfiddle.uk; link is set to use markdown for output so you can see the whole snowflake.
Before execute press ctrl-t for output to text instead of grid. This takes 60 seconds to execute on my computer.
-
1\$\begingroup\$ Long time no "see". Thanks for the edit Ross. \$\endgroup\$t-clausen.dk– t-clausen.dk2020年05月12日 17:55:22 +00:00Commented May 12, 2020 at 17:55
-
\$\begingroup\$ I fully intend to try to golf this when I get time :) \$\endgroup\$Ross Presser– Ross Presser2020年05月12日 19:41:48 +00:00Commented May 12, 2020 at 19:41
-
\$\begingroup\$ @RossPresser I took another look and realized i could save some bytes. I would love if you found some additional golfing. Performance is better now \$\endgroup\$t-clausen.dk– t-clausen.dk2020年05月13日 08:13:40 +00:00Commented May 13, 2020 at 8:13
-
\$\begingroup\$ golfed out 22 bytes by using SELECT INTO instead of CREATE TABLE/INSERT. Might have killed the performance :) Also fixed dbfiddle link to latest. \$\endgroup\$Ross Presser– Ross Presser2020年05月15日 16:58:03 +00:00Commented May 15, 2020 at 16:58
-
1\$\begingroup\$ @t-clausen-dk this is my current golf \$\endgroup\$Ross Presser– Ross Presser2020年05月19日 14:32:41 +00:00Commented May 19, 2020 at 14:32
Python 2, 125 bytes
s="%64c"%10
exec's*=63;s="".join(s[n][(s[n+3967:][:191]*3)[::64].strip()=="X":n!=2015]or"X"for n in range(4032));'*32
print s
This answer is by user "clock" based on hallvabo's solution, on the Anarchy Golf version of this challenge that I submitted. Note that output there is strict and is required to be exactly the picture of X's and spaces to STDOUT via a full program, with only an allowance for a trailing newline.
The most interesting part of this answer, in my opinion, is the concise construction (s[n+3967:][:191]*3)[::64] after s*=63 to get the nine neighbors of the cell counting itself in a flat newline-joined string representing the grid. To check if there's exactly one X among them, .strip() is called to get rid of whitespace on either side, and the result is checked to equal just "X".
It's interesting how simulating the steps on the string representation of the output directly (rather than an array of bits) not only saves on doing a conversion to characters later but also allows string-specific methods to be used in a golfy way.
Another neat trick, borrowed from hallvabo, is "%64c"%10 used to initialize s to 63 spaces followed by a newline for a line of the initial empty grid. Using the %c format, which converts an ASCII value to a character, is shorter than " "*63+"\n" or "%64s"%"\n".
Wolfram Language (Mathematica) + my LifeFind package, 47 bytes
<<Life`
Last@CA[{{1}},31,Rule->"B1/S01234568"]&
There isn't any living cell with 7 living neighbors in the first 31 steps, so I can golf the rule by 1 byte: B1/S012345678 -> B1/S01234568.
Charcoal, (削除) 38 (削除ここまで) 37 bytes
J31¦31XF32«UMKAXF63F63«Jκλ›=NoKMX1=KKX
Try it online! Link is to verbose version of code. Explanation:
J31¦31X
Output the X in the centre of the square.
F32«
Grow the snowflake 31 times. (The last loop is just used for its side-effect of replacing the -s with Xs.)
UMKAX
Change all the -s to Xs.
F63F63«
Iterate over the square.
Jκλ
Jump to each position in the square.
›=NoKMX1=KKX
If the cell does not yet have an X but it has one neighbouring X then print a -.
05AB1E, 31 bytes
1 ̧ ̧31F0δ.ø¬0* ̧.øD2Fε0.øü3O}ø}Θ~
05AB1E and matrices are not a good combination.. :/
Outputs as a 63x63 matrix of 0s and 1s for spaces and crystals respectively.
Try it online. (The footer is to pretty-print it, feel free to remove it to see the actual result.)
Explanation:
1 ̧ ̧ # Start with a matrix containing 1: [[1]]
31F # Loop 31 times:
0δ.ø # Surround each row with leading and trailing 0
# i.e. [[1,1,1],[1,1,1],[1,1,1]] → [[0,1,1,1,0],[0,1,1,1,0],[0,1,1,1,0]]
¬ # Take the first row (without popping the matrix)
# → [0,1,1,1,0]
0* # Multiply each value by 0
# → [0,0,0,0,0]
̧ # Wrap it into a list
# → [[0,0,0,0,0]]
.ø # And surround the matrix with that row of 0s
# i.e. [[0,0,0,0,0],[0,1,1,1,0],[0,1,1,1,0],[0,1,1,1,0],[0,0,0,0,0]]
D # Duplicate it
2F # Loop 2 times:
ε # Map each row to:
0.ø # Surround the row with leading and trailing 0
# i.e. [0,1,1,1,0] → [0,0,1,1,1,0,0]
ü3 # Create overlapping triplets
# → [[0,0,1],[0,1,1],[1,1,1],[1,1,0],[1,0,0]]
O # Sum each triplet
# → [1,2,3,2,1]
}ø # After the map: transpose/zip; swapping rows/columns
# i.e. [[0,0,0,0,0],[1,2,3,2,1],[1,2,3,2,1],[1,2,3,2,1],[0,0,0,0,0]]
# → [[0,1,1,1,0],[0,2,2,2,0],[0,3,3,3,0],[0,2,2,2,0],[0,1,1,1,0]]
}Θ # After the inner loop: check for each whether it's 1 (1 if 1; 0 otherwise)
# i.e. [[1,2,3,2,1],[2,4,6,4,2],[3,6,9,6,3],[2,4,6,4,2],[1,2,3,2,1]]
# → [[1,0,0,0,1],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[1,0,0,0,1]]
~ # Take the bitwise-OR of the values at the same positions in the matrices
# → [[1,0,0,0,1],[0,1,1,1,0],[0,1,1,1,0],[0,1,1,1,0],[1,0,0,0,1]]
# (after the loop, the resulting matrix is output implicitly)
Jelly, (削除) 41 (削除ここまで) 34 bytes
ı*Ɱ5I;$Ṗ+)×ばつ1ıWÇṛ¡’ÆiḞŒṬ
-7 because to nobody's surprise there's two shorter ways to get \32ドル+32i\$ than " ‘Æị, the symmetry of the neighborhood lets +Ɲ golf to I, we can trade two ¤s and a € for ) and $, ẹ exists, œ| is overkill, and selfing ċⱮ is outright superfluous
This is an absolute mess that could probably be outdone easily by someone with any clue as to how to mimic others' convolution-based approach. Outputs a two-dimensional list of ones and zeros, which are conveniently translated to the example's Xs and spaces by the testing footer provided.
ı*Ɱ5I;$Ṗ+)FċⱮẹ1ịƲ; Monadic helper link: grow a list of complex numbers
) For each number:
ı*Ɱ5 raise the imaginary unit 1j to each power from 1 to 5,
I;$ prepend the differences between its adjacent elements,
Ṗ remove the extra 1j,
+ and add each to the number.
F Flatten the resulting list of lists,
ịƲ take the elements at indices
ẹ1 which are indices of 1 in
ċⱮ the list of how many times each element occurs,
; and append the original lis×ばつ1ıWÇṛ¡’ÆiḞŒṬ Niladic main link: generate the snowflake
32 Set the argument to 32,
×ばつ1ı then multiply it by 1+1j
W and wrap it in a singleton list.
Ç ¡ Grow that a number of times equal to
ṛ ’ the argument minus 1.
ÆiḞ Convert the complex numbers to pairs of integers,
ŒṬ and interpret the pairs as coordinates of 1s in a 2D array.
PHP, 206 bytes
for($a[][]=1;++$n<32;){$b=$a;for($i=$n;$i>=-$n;$i--)for($j=$n;$j>=-$n;$j--){$a[$i][$j]=$a[$i][$j]&1;$c=0;for($k=2;--$k>-2;)for($l=2;--$l>-2;)if($k|$l)$c+=$b[$i+$k][$j+$l];1!=$c?:$a[$i][$j]=1;}}var_dump($a);
Well I'm getting used to horrible PHP answers :D don't blame the language, there are libs for matrixes.. displays an unordered array of 1 and 0, but with proper keys. change the first loop value (32) to generate any size snowflake..
24 bytes could have been saved by removing $a[$i][$j]=$a[$i][$j]&1; if we only needed the truthy values.
Python 2, (削除) 146 (削除ここまで) 130 bytes
Prints a 2d-list of booleans.
R=range(63)
for i in R:m=[[i>0==(x*y-961)*0**m[y][x]*~-sum(sum(k[x+x%~x:x+2])for k in m[y+y%~y:y+2])for x in R]for y in R]
print m
-
\$\begingroup\$ Nice trick with the
x%~x. How did you come up with that? \$\endgroup\$xnor– xnor2020年05月13日 05:53:14 +00:00Commented May 13, 2020 at 5:53 -
\$\begingroup\$ @xnor I didn't like the
x+(x>0), so I tried to find something better.x-1+1%-~xwould work, so I tried a few more arguments to%. If I hadn't arrived atx+x%~xby hand, I would have bruteforced it. \$\endgroup\$ovs– ovs2020年05月13日 06:39:53 +00:00Commented May 13, 2020 at 6:39 -
\$\begingroup\$ @xnor did a brute force search now, turns out
-2%-~xand0-2%~aboth work at the same length. \$\endgroup\$ovs– ovs2020年05月13日 08:07:43 +00:00Commented May 13, 2020 at 8:07 -
\$\begingroup\$ You might be interested in trying the anarchy version of this challenge that I posted \$\endgroup\$xnor– xnor2020年05月20日 09:15:53 +00:00Commented May 20, 2020 at 9:15
R, (削除) 144 (削除ここまで) (削除) 122 (削除ここまで) 118 bytes
m=matrix(!-2112:2112,65)
for(k in 1:31){l=m;for(i in 67:4159)if(sum(l[i+-3:5%/%3+-1:1*65][-5])==1)m[i]=1}
m[2:64,2:64]
My first code golf attempt (except for secret ones that I never dared to post...), so nothing really clever going on, I'm afraid...
Edit 1: -4 bytes to remove useless variable definition
Edit 2: thanks to Giuseppe: -18 bytes!
Edit 3: thanks again to Giuseppe: -4 more bytes
-
1\$\begingroup\$ Nice work! Some suggestions. \$\endgroup\$Giuseppe– Giuseppe2020年05月14日 14:32:23 +00:00Commented May 14, 2020 at 14:32
-
\$\begingroup\$ Thankyou! I've edited-in your suggestions, with acknowledgement. Very much appreciated! \$\endgroup\$Dominic van Essen– Dominic van Essen2020年05月14日 15:17:23 +00:00Commented May 14, 2020 at 15:17
-
1
-
\$\begingroup\$ Thankyou again Giuseppe. Especially for (implicitly) pointing-out my beginner's errors (useless '>1'...)... editing-in again now... \$\endgroup\$Dominic van Essen– Dominic van Essen2020年05月14日 19:46:23 +00:00Commented May 14, 2020 at 19:46
-
\$\begingroup\$ You've come a long way since this answer :-) \$\endgroup\$Giuseppe– Giuseppe2022年01月05日 14:51:06 +00:00Commented Jan 5, 2022 at 14:51
Java (JDK), 243 bytes
v->{int N=63,K=N*N,g[][]=new int[N][N],w[]=new int[K],i=31,x,c,y;for(g[i][i]=1;i-->0;){for(x=K;x-->0;w[x]=c==1?x+1:0)for(c=0,y=K;y-->0;)if(g[y%N][y/N]>0&(Math.abs(x%N-y%N)|Math.abs(x/N-y/N))<2)c++;for(int z:w)if(z-->0)g[z%N][z/N]=1;}return g;}
Explanations
Basically, the algorithm is to fill two grids by consecutive merges to keep the data from being changed at runtime. For each square, we check if there are neighbours set (using a second full loop instead of a smaller 1-square distance to avoid byte-costly constraints). If there's exactly one neighbour, the square is added to the writing (to-be-merged) grid. Then when all the computation is done, the writing-grid is merged to the main grid. When all the 31 loops are done, the resulting grid is returned.
v->{
int N=63,
K=N*N,
g[][]=new int[N][N], // the grid and return-value, we read from it
w[]=new int[K], // the temp array to write in
i=31, // the main iterator to expand the snowflakes
x,c,y; // x the position being tested, c the count of neighbours, y the neighbour candidates
for( g[i][i]=1; // Init the snowflake in its center
i-->0; // Expand the snowflake 31 times
){
for( x=K; // init x to match all the positions
x-->0; // For each position
w[x]=c==1?x+1:0 // If the counter is exactly 1,
// set x as a position that's not empty.
// and store x+1 instead of 1 or x to ease the merge operation
// and leave 0 as a default value
)
for(c=0,y=K;y-->0;) // Reset the count and loop through all squares again
if( g[y%N][y/N]>0 // if y is set
&( Math.abs(x%N-y%N) // and if x and y are neighbours
|Math.abs(x/N-y/N))<2
)
c++; // Then increase the neighbour-count.
for(int z:w) // For each value to be merged
if(z-->0) // which is +1'd and non default
g[z%N][z/N]=1; // Then place it in the grid.
}
return g; // Return the grid
}
-
\$\begingroup\$
c==1?x+1:0andif(z-->0)can bec==1?x:-1andif(z>=0)for -2. \$\endgroup\$Kevin Cruijssen– Kevin Cruijssen2020年05月14日 13:14:10 +00:00Commented May 14, 2020 at 13:14 -
\$\begingroup\$ Building on @KevinCruijssen 235 bytes \$\endgroup\$ceilingcat– ceilingcat2022年12月01日 16:17:04 +00:00Commented Dec 1, 2022 at 16:17
C (gcc), (削除) 207 (削除ここまで) (削除) 206 (削除ここまで) 192 bytes
-1 -14 bytes thanks to ceilingcat!
#define F(x)for(x=64;--x;
#define z M[r][c]
M[65][65]={[32][32]=32},r,c,i=32,x;main(s){for(;--i;)F(r))F(c)z=s-!z?z:i)for(s=0,x=-9;x++;)s+=M[x/3-~r][x%3-~c]>i;F(r)puts(""))F(c))putchar(33-!z);}
To avoid having to use two tables (one for current iteration and one for the next), each new crystal is written using the current iteration number, instead of just using 1. This allows for ignoring any crystals from the current iteration when counting neighbours.
A lot of the counting is done backwards for golfing reasons, including the iteration number, which is why we seed the table with 32 in the middle.
The table is made too large so as to have padding, allowing us to count neighbours without having to care about edge-cases.
A more elegant solution is bound to exist. This many loops is hardly ever a good sign.
#define F(x)for(x=64;--x; To make recurring loops more compact.
Goes from 63 down to 1, to skip padding in table.
M[65][65]={[32][32]=32}, Make padded table seeded with first crystal.
r,c,i=32,x,y;main(s){ Misc variables; i holds iteration.
for(;--i;)F(r))F(c) Loop through table for each iteration.
s==!M[r][c]?M[r][c]=i:0) Update current cell according to neighbour count
found in loop below. We only update if cell is empty
(M[r][c] == 0) and if s == 1, combined as shown.
for(s=0,x=r-2;x++<=r;) Go through 3x3 grid with current cell in center.
for(y=c-2;y++<=c;)
s+=M[x][y]>i; If a cell contains a crystal NOT from current gen,
increase our neighbour count.
F(r)puts(""))F(c)) Output loop
putchar(33-!M[r][c]);} Make any non-zero cell a exclamation mark; space otherwise
-
\$\begingroup\$ @ceilingcat Neat one. For some reason I abandonded that avenue too early. \$\endgroup\$gastropner– gastropner2020年05月15日 20:19:07 +00:00Commented May 15, 2020 at 20:19
JavaScript (V8), 465 bytes
[w=1414812756,269488144,357569872,285212944,22304e3,286265616,353718608,69648,1414856704,269553680,357650768,17830160,1426150656,286327056,1364280656,0,w,1343229968,1162876240,83886352,1146377472,1414533392,1078284624,327680,1078219860,1414811664,1145062736,89392384,1141130324,1427395664,1073758277,5].map(e=>(Array(32).fill().map(l=>(c.push(1&e?"X":" "),e>>=1),c=[]),c.slice(1).reverse``.concat(c)),o=e=>console.log(e.join``)||e).map(o).reverse``.slice(1).map(o);
Explore related questions
See similar questions with these tags.
0and1, displayed with spaces in betwee \$\endgroup\$