Skip to main content
Removed a lot of unnecessary text and improved my submission.
Source Link
NotBaal
  • 161
  • 1
  • 6

Java (OpenJDK 8) - 400 388 388367 bytes

EDIT: As per Zacharý's comment, the code I submitted doesn't really form a working program/functionSecond and (silly me I know :Pprobably). With that in mind, I set out Final Edit: Managed to fix thisgolf an extra 21 bytes after finding these (imo) goldmines - turns out, using a lambda expression, I not only fix that requirement, I also manageddefinitely recommend new people to shave 42 bytes off the resultread these - and funny enough, I ended up 'solving' the problem noted in the P.S. by myself(especially if you're going to try some of these challenges using Java).

Resulting code (probably going to end up golfing even more if I find out how to shorten those double nested for loops...):

u->{int w=u.length,h=u[0].length,x,y,i,j,n;ArrayList<Point>r=newn;Stack<Point>r=new ArrayList<Point>Stack<Point>();while;for(true;;){for(Point c:r)u[c.x][c.y]=1;r.clear();for(x=0;x<w;++x){for(y=0;y<h;++y){boolean o=u[x][y]==1;n=oo=u[x][y]>0;n=o?-1:0;for(i=-2;++i<2;)for(j=-2;++j<2;)if(u[(w+x+i)%w][(h+y+j)%h]==1%h]>0)++n;if(o&n>1&n<4|!o&n==3)r.add(new Point(x,y));System.out.print(u[x][y]);}System.out.printlnu[x][y]+(y>h-2?"\n":""));}for(int[]t:u)Arrays.fill(t,0);}}

Try it online!Try it online!

However I had a few issues because the code was suddently giving out weird and different results for both stable and non-stable patterns. Luckily I solved that at the cost of 30 bytes - which still brings me under the 400 byte mark (the added code will be marked accordingly in the explanation below).

Golfed:

Try it online! (don't actually use this - see below why) See edit above for tio link.

/*
 * Explanation of each variable's usage:
 * w=height* of array
 * h=width* of array
 * x=y* coord of point in array
 * y=x* coord of point in array
 * i and j are counters for calculating the neighbours around a point in the array
 * n=neighbour counter
 * r=temporary array to store the cells from the current generation
 * u=the 2d array used for all the calculations (parameter from lambda expression)
 * c=temporary variable used to help populate the 2d array
 * o=boolean variable that stores the value of whether the cell is alive or not
 */
u-> // start of lambda statement with u as parameter (no need for brackets as it's only one parameter being passed)
{
    int w=u.length,h=u[0].length,x,y,i,j,n; // defines all the necessary integer variables;
    ArrayList<Point>r=newStack<Point>r=new ArrayList<Point>Stack<Point>(); // same with the only array list needed (note how I only use two data structures);
    whilefor(true;;) // notice how this is still an infinite loop but using a for loop;
    {
        for(Point c:r)u[c.x][c.y]=1; //for every point in the "previous" generation, add that to the 2D array as a live (evil?) cell;
        r.clear(); // clears the array list to be populated later on
        for(x=0;x<w;++x) // a pair of nested for loops to iterate over every cell of the 2D array;
        {
            for(y=0;y<h;++y)
            {
                // sets o to be the presence of a live cell at (x,y) then uses said value in initialising the neighbour counter;
                boolean o=u[x][y]==1;n=oo=u[x][y]>1;n=o?-1:0;
                for(i=-2;++i<2;) // another pair of nested for loops - this one iterates over a 3x3 grid around *each* cell of the 2D array;
                {                // this includes wrap-around (note the modulus sign in the if statement below);
                    for(j=-2;++j<2;)
                    {
                        if(u[(w+x+i)%w][(h+y+j)%h]==1%h]>0)++n; // this is where the first interesting thing lies - the bit which makes wrap-around a reality;
                    }
                }
                if(o&n>1&n<4|!o&n==3)r.add(new Point(x,y)); // this is the second interesting bit of my code - perhaps more so as I use bitwise operators to calculate the number of neighbours (x,y) has;
                                                            // (since I'm technically dealing with 0s and 1s, it's not a total misuse of them imo);
                System.out.print(u[x][y]u[x][y]+(y>h-2?"\n":""));
            } // a penalty of around 40that bytesextra forpart outputtingof the result - this can be further increased toprint improvestatement readabilityadds -a seenewline below;
if we reached the end of the current 'line';
    System.out.println();
        }
        // this is the line of code added to fix the weird behaviour;}
        // since the information about the new generation is now in the array list, this array can be emptied out, ready to receive said info on the new generation;
        for(int[]t:u)Arrays.fill(t,0);
    }
} // end of lambda statement

Yes, there's a catch with my approach. Actually there's more than one; I'll briefly touch on the ones I'm aware of.

Firstly, As most of you probably noticed, my golfed code as it currently stands will loop forever. To prevent this, a counter can be introduced at the top and used in the while loop to only display n (in this case, 5) iterations as follows (notice the new b variable added):

u->{int b=0,w=35w=u.length,h=20h=u[0].length,x,y,i,j,n;ArrayList<Point>l=newn;Stack<Point>r=new ArrayList<Point>Stack<Point>(),r;while;for(++b<6;++b<6;){int[][]u=new int[w][h];forfor(Point c:lr)u[c.x][c.y]=1;r=new ArrayList<Point>y]=1;r.clear();for(x=0;x<w;++x){for(y=0;y<h;++y){boolean o=u[x][y]==1;n=oo=u[x][y]>0;n=o?-1:0;for(i=-2;++i<2;)for(j=-2;++j<2;)if(u[(w+x+i)%w][(h+y+j)%h]==1%h]>0)++n;if(o&n>1&n<4|!o&n==3)r.add(new Point(x,y));System.out.print(u[x][y]);}System.out.printlnu[x][y]+(y>h-2?"\n":""));}l.clearfor(int[]t:u);lArrays.addAllfill(rt,0);}}

The second, more considerable catch is the "user input". I...may have complicated that a little in an attempt to golf this as much as I possibly could. As such, entering live cells in the initial pattern (generation=0) will have to be done in the following manner (and in the exact position on the code):

l.add(new Point(x,y)); // l is the array defined in my code; I don't think I need to define what x and y would be ;)

as shown in this Try it online! (use this one for instant testing) link. (consequentally, the coordinates defined within that link translate to a glider, so it should 'gracefully' fly across the field.) That's why I advised against using the first link if you wanted to instantly check whether the program is valid or not. This second point is no longer valid given that my program now takes in a parameter defined as a 2D array, making user input considerably easier in this new version.

Finally Additionally, a few points worth mentioning. This program does not check if the input is correct and will, therefore, fail with (most likely) an ArrayOutOfBoundsException; as such, make sure to check the coordinates are within the limits defined as w and h - I've checked and double-checked that everything runs as it should through a GUI I had already built a while ago. make sure to check that the input is valid by completely filling in a part of an array (skewered arrays will throw the exception mentioned above). Also, the board as it currently is looks 'fluid' - that is, there is no separation between one generation and the next. If you wish to add that in to double-check that the generations being produced are indeed valid, an extra System.out.println(); needs to be added just before for(int[]t:u)Arrays.fill(t,0); (see this Try it online!Try it online! for clarity). And last, but not least, given that this is my first code golf, any feedback is greatly appreciated :)

P.S.Old code from previous 388 byte answer: I would be curious to see if anyone could write this implementation using only two data structures instead of three as I did in my code - one 2D int array and two array lists with elements of type Point (or, if it's not possible, to perhaps provide an explanation as to why because for a while I was under the impression that I could but nothing I tried worked properly). Solved it as explained above in the 'new' post.

u->{int w=u.length,h=u[0].length,x,y,i,j,n;ArrayList<Point>r=new ArrayList<Point>();while(true){for(Point c:r)u[c.x][c.y]=1;r.clear();for(x=0;x<w;++x){for(y=0;y<h;++y){boolean o=u[x][y]==1;n=o?-1:0;for(i=-2;++i<2;)for(j=-2;++j<2;)if(u[(w+x+i)%w][(h+y+j)%h]==1)++n;if(o&n>1&n<4|!o&n==3)r.add(new Point(x,y));System.out.print(u[x][y]);}System.out.println();}for(int[]t:u)Arrays.fill(t,0);}}

Old codeAnd from previousthe initial 400 byte answer here:

Java (OpenJDK 8) - 400 388 bytes

EDIT: As per Zacharý's comment, the code I submitted doesn't really form a working program/function (silly me I know :P). With that in mind, I set out to fix this - turns out, using a lambda expression, I not only fix that requirement, I also managed to shave 42 bytes off the result - and funny enough, I ended up 'solving' the problem noted in the P.S. by myself.

Resulting code:

u->{int w=u.length,h=u[0].length,x,y,i,j,n;ArrayList<Point>r=new ArrayList<Point>();while(true){for(Point c:r)u[c.x][c.y]=1;r.clear();for(x=0;x<w;++x){for(y=0;y<h;++y){boolean o=u[x][y]==1;n=o?-1:0;for(i=-2;++i<2;)for(j=-2;++j<2;)if(u[(w+x+i)%w][(h+y+j)%h]==1)++n;if(o&n>1&n<4|!o&n==3)r.add(new Point(x,y));System.out.print(u[x][y]);}System.out.println();}for(int[]t:u)Arrays.fill(t,0);}}

Try it online!

However I had a few issues because the code was suddently giving out weird and different results for both stable and non-stable patterns. Luckily I solved that at the cost of 30 bytes - which still brings me under the 400 byte mark (the added code will be marked accordingly in the explanation below).

Golfed:

Try it online! (don't actually use this - see below why) See edit above for tio link.

/*
 * Explanation of each variable's usage:
 * w=height* of array
 * h=width* of array
 * x=y* coord of point in array
 * y=x* coord of point in array
 * i and j are counters for calculating the neighbours around a point in the array
 * n=neighbour counter
 * r=temporary array to store the cells from the current generation
 * u=the 2d array used for all the calculations (parameter from lambda expression)
 * c=temporary variable used to help populate the 2d array
 * o=boolean variable that stores the value of whether the cell is alive or not
 */
u-> // start of lambda statement with u as parameter (no need for brackets as it's only one parameter being passed)
{
    int w=u.length,h=u[0].length,x,y,i,j,n; // defines all the necessary integer variables;
    ArrayList<Point>r=new ArrayList<Point>(); // same with the only array list needed (note how I only use two data structures);
    while(true)
    {
        for(Point c:r)u[c.x][c.y]=1; //for every point in the "previous" generation, add that to the 2D array as a live (evil?) cell;
        r.clear(); // clears the array list to be populated later on
        for(x=0;x<w;++x) // a pair of nested for loops to iterate over every cell of the 2D array;
        {
            for(y=0;y<h;++y)
            {
                // sets o to be the presence of a live cell at (x,y) then uses said value in initialising the neighbour counter;
                boolean o=u[x][y]==1;n=o?-1:0;
                for(i=-2;++i<2;) // another pair of nested for loops - this one iterates over a 3x3 grid around *each* cell of the 2D array;
                {                // this includes wrap-around (note the modulus sign in the if statement below);
                    for(j=-2;++j<2;)
                    {
                        if(u[(w+x+i)%w][(h+y+j)%h]==1)++n; // this is where the first interesting thing lies - the bit which makes wrap-around a reality;
                    }
                }
                if(o&n>1&n<4|!o&n==3)r.add(new Point(x,y)); // this is the second interesting bit of my code - perhaps more so as I use bitwise operators to calculate the number of neighbours (x,y) has;
                                                            // (since I'm technically dealing with 0s and 1s, it's not a total misuse of them imo);
                System.out.print(u[x][y]);
            } // a penalty of around 40 bytes for outputting the result - this can be further increased to improve readability - see below;
            System.out.println();
        }
        // this is the line of code added to fix the weird behaviour;
        // since the information about the new generation is now in the array list, this array can be emptied out, ready to receive said info on the new generation;
        for(int[]t:u)Arrays.fill(t,0);
    }
} // end of lambda statement

Yes, there's a catch with my approach. Actually there's more than one; I'll briefly touch on the ones I'm aware of.

Firstly, As most of you probably noticed, my golfed code as it currently stands will loop forever. To prevent this, a counter can be introduced at the top and used in the while loop to only display n (in this case, 5) iterations as follows (notice the new b variable added):

int b=0,w=35,h=20,x,y,i,j,n;ArrayList<Point>l=new ArrayList<Point>(),r;while(++b<6){int[][]u=new int[w][h];for(Point c:l)u[c.x][c.y]=1;r=new ArrayList<Point>();for(x=0;x<w;++x){for(y=0;y<h;++y){boolean o=u[x][y]==1;n=o?-1:0;for(i=-2;++i<2;)for(j=-2;++j<2;)if(u[(w+x+i)%w][(h+y+j)%h]==1)++n;if(o&n>1&n<4|!o&n==3)r.add(new Point(x,y));System.out.print(u[x][y]);}System.out.println();}l.clear();l.addAll(r);}

The second, more considerable catch is the "user input". I...may have complicated that a little in an attempt to golf this as much as I possibly could. As such, entering live cells in the initial pattern (generation=0) will have to be done in the following manner (and in the exact position on the code):

l.add(new Point(x,y)); // l is the array defined in my code; I don't think I need to define what x and y would be ;)

as shown in this Try it online! (use this one for instant testing) link. (consequentally, the coordinates defined within that link translate to a glider, so it should 'gracefully' fly across the field.) That's why I advised against using the first link if you wanted to instantly check whether the program is valid or not. This second point is no longer valid given that my program now takes in a parameter defined as a 2D array, making user input considerably easier in this new version.

Finally, a few points worth mentioning. This program does not check if the input is correct and will, therefore, fail with (most likely) an ArrayOutOfBoundsException; as such, make sure to check the coordinates are within the limits defined as w and h - I've checked and double-checked that everything runs as it should through a GUI I had already built a while ago. make sure to check that the input is valid by completely filling in a part of an array (skewered arrays will throw the exception mentioned above). Also, the board as it currently is looks 'fluid' - that is, there is no separation between one generation and the next. If you wish to add that in to double-check that the generations being produced are indeed valid, an extra System.out.println(); needs to be added just before for(int[]t:u)Arrays.fill(t,0); (see this Try it online! for clarity). And last, but not least, given that this is my first code golf, any feedback is greatly appreciated :)

P.S.: I would be curious to see if anyone could write this implementation using only two data structures instead of three as I did in my code - one 2D int array and two array lists with elements of type Point (or, if it's not possible, to perhaps provide an explanation as to why because for a while I was under the impression that I could but nothing I tried worked properly). Solved it as explained above in the 'new' post.

Old code from previous 400 byte answer here:

Java (OpenJDK 8) - 400 388 367 bytes

Second and (probably) Final Edit: Managed to golf an extra 21 bytes after finding these (imo) goldmines - definitely recommend new people to read these (especially if you're going to try some of these challenges using Java).

Resulting code (probably going to end up golfing even more if I find out how to shorten those double nested for loops...):

u->{int w=u.length,h=u[0].length,x,y,i,j,n;Stack<Point>r=new Stack<Point>();for(;;){for(Point c:r)u[c.x][c.y]=1;r.clear();for(x=0;x<w;++x)for(y=0;y<h;++y){boolean o=u[x][y]>0;n=o?-1:0;for(i=-2;++i<2;)for(j=-2;++j<2;)if(u[(w+x+i)%w][(h+y+j)%h]>0)++n;if(o&n>1&n<4|!o&n==3)r.add(new Point(x,y));System.out.print(u[x][y]+(y>h-2?"\n":""));}for(int[]t:u)Arrays.fill(t,0);}}

Try it online!

/*
 * Explanation of each variable's usage:
 * w=height* of array
 * h=width* of array
 * x=y* coord of point in array
 * y=x* coord of point in array
 * i and j are counters for calculating the neighbours around a point in the array
 * n=neighbour counter
 * r=temporary array to store the cells from the current generation
 * u=the 2d array used for all the calculations (parameter from lambda expression)
 * c=temporary variable used to help populate the 2d array
 * o=boolean variable that stores the value of whether the cell is alive or not
 */
u-> // start of lambda statement with u as parameter (no need for brackets as it's only one parameter being passed)
{
    int w=u.length,h=u[0].length,x,y,i,j,n; // defines all the necessary integer variables;
    Stack<Point>r=new Stack<Point>(); // same with the only array list needed (note how I only use two data structures);
    for(;;) // notice how this is still an infinite loop but using a for loop;
    {
        for(Point c:r)u[c.x][c.y]=1; //for every point in the "previous" generation, add that to the 2D array as a live (evil?) cell;
        r.clear(); // clears the array list to be populated later on
        for(x=0;x<w;++x) // a pair of nested for loops to iterate over every cell of the 2D array;
        {
            for(y=0;y<h;++y)
            {
                // sets o to be the presence of a live cell at (x,y) then uses said value in initialising the neighbour counter;
                boolean o=u[x][y]>1;n=o?-1:0;
                for(i=-2;++i<2;) // another pair of nested for loops - this one iterates over a 3x3 grid around *each* cell of the 2D array;
                {                // this includes wrap-around (note the modulus sign in the if statement below);
                    for(j=-2;++j<2;)
                    {
                        if(u[(w+x+i)%w][(h+y+j)%h]>0)++n; // this is where the first interesting thing lies - the bit which makes wrap-around a reality;
                    }
                }
                if(o&n>1&n<4|!o&n==3)r.add(new Point(x,y)); // this is the second interesting bit of my code - perhaps more so as I use bitwise operators to calculate the number of neighbours (x,y) has;
                                                            // (since I'm technically dealing with 0s and 1s, it's not a total misuse of them imo);
                System.out.print(u[x][y]+(y>h-2?"\n":""));  // that extra part of the print statement adds a newline if we reached the end of the current 'line';
            }
        }
        // since the information about the new generation is now in the array list, this array can be emptied out, ready to receive said info on the new generation;
        for(int[]t:u)Arrays.fill(t,0);
    }
} // end of lambda statement

Yes, there's a catch with my approach.

As most of you probably noticed, my golfed code as it currently stands will loop forever. To prevent this, a counter can be introduced at the top and used in the while loop to only display n (in this case, 5) iterations as follows (notice the new b variable added):

u->{int b=0,w=u.length,h=u[0].length,x,y,i,j,n;Stack<Point>r=new Stack<Point>();for(;++b<6;){for(Point c:r)u[c.x][c.y]=1;r.clear();for(x=0;x<w;++x)for(y=0;y<h;++y){boolean o=u[x][y]>0;n=o?-1:0;for(i=-2;++i<2;)for(j=-2;++j<2;)if(u[(w+x+i)%w][(h+y+j)%h]>0)++n;if(o&n>1&n<4|!o&n==3)r.add(new Point(x,y));System.out.print(u[x][y]+(y>h-2?"\n":""));}for(int[]t:u)Arrays.fill(t,0);}}

Additionally, a few points worth mentioning. This program does not check if the input is correct and will, therefore, fail with (most likely) an ArrayOutOfBoundsException; as such, make sure to check that the input is valid by completely filling in a part of an array (skewered arrays will throw the exception mentioned above). Also, the board as it currently is looks 'fluid' - that is, there is no separation between one generation and the next. If you wish to add that in to double-check that the generations being produced are indeed valid, an extra System.out.println(); needs to be added just before for(int[]t:u)Arrays.fill(t,0); (see this Try it online! for clarity). And last, but not least, given that this is my first code golf, any feedback is greatly appreciated :)

Old code from previous 388 byte answer:

u->{int w=u.length,h=u[0].length,x,y,i,j,n;ArrayList<Point>r=new ArrayList<Point>();while(true){for(Point c:r)u[c.x][c.y]=1;r.clear();for(x=0;x<w;++x){for(y=0;y<h;++y){boolean o=u[x][y]==1;n=o?-1:0;for(i=-2;++i<2;)for(j=-2;++j<2;)if(u[(w+x+i)%w][(h+y+j)%h]==1)++n;if(o&n>1&n<4|!o&n==3)r.add(new Point(x,y));System.out.print(u[x][y]);}System.out.println();}for(int[]t:u)Arrays.fill(t,0);}}

And from the initial 400 byte answer:

Changed the answer completely to reflect more the current version of my submission.
Source Link
NotBaal
  • 161
  • 1
  • 6

However I had a few issues because the code was suddently giving out weird and different results for both stable and non-stable patterns. Luckily I solved that at the cost of 30 bytes - which still brings me under the 400 byte mark (the added code will be marked accordingly in the explanation below).

int w=35,h=20,x,y,i,j,n;ArrayList<Point>l=new ArrayList<Point>(),r;while(true){int[][]u=new int[w][h];for(Point c:l)u[c.x][c.y]=1;r=new ArrayList<Point>();for(x=0;x<w;++x){for(y=0;y<h;++y){boolean o=u[x][y]==1;n=o?-1:0;for(i=-2;++i<2;)for(j=-2;++j<2;)if(u[(w+x+i)%w][(h+y+j)%h]==1)++n;if(o&n>1&n<4|!o&n==3)r.add(new Point(x,y));System.out.print(u[x][y]);}System.out.println();}l.clear();l.addAll(r);}

Try it online! (don't actually use this - see below why) See edit above for tio link.

/*
 * Explanation of each variable's usage:
 * w=widthw=height* of array
 * h=heighth=width* of array
 * x=xx=y* coord of point in array
 * y=yy=x* coord of point in array
 * i and j are counters for calculating the neighbours around a point in the array
 * n=neighbour counter
 * l=array list of alive cells from current generation
 * r=temporary array to store the cells from the current generation
 * u=the 2d array used for all the calculations (parameter from lambda expression)
 * c=temporary variable used to help populate the 2d array
 * o=boolean variable that stores the value of whether the cell is alive or not
 */
u-> // start of lambda statement with u as parameter (no need for brackets as it's only one parameter being passed)
{
    int w=35w=u.length,h=20h=u[0].length,x,y,i,j,n; // defines all the necessary integer variables;
ArrayList<Point>l=new    ArrayList<Point>r=new ArrayList<Point>(),r;; // same with the only array lists;
whilelist needed (true)
{
note how I only int[][]u=newuse int[w][h];two //ourdata 2Dstructures);
 array which will bewhile(true)
 processed below;  {
        for(Point c:lr) u[c.x][c.y]=1; //for every point in the "previous" generation, add that to the 2D array as a live (evil?) cell;
    r=new ArrayList<Point>   r.clear(); // initialisesclears thisthe array list object - it needs to be here otherwise it feedspopulated thelater otheron
 array with previous generations;
    for(x=0;x<w;++x) // a pair of nested for loops to iterate over every cell of the 2D array;
        {
            for(y=0;y<h;++y)
            {
                // sets o to be the presence of a live cell at (x,y) then uses said value in initialising the neighbour counter;
                boolean o=u[x][y]==1;n=o?-1:0;
                for(i=-2;++i<2;) // another pair of nested for loops - this one iterates over a 3x3 grid around *each* cell of the 2D array;
                {                // this includes wrap-around (note the modulus sign in the if statement below);
                    for(j=-2;++j<2;)
                    {
                        if(u[(w+x+i)%w][(h+y+j)%h]==1)++n; // this is where the first interesting thing lies - the bit which makes wrap-around a reality;
                    }
                }
                if(o&n>1&n<4|!o&n==3) r.add(new Point(x,y)); // this is the second interesting bit of my code - perhaps more so as I use bitwise operators to calculate the number of neighbours (x,y) has;
                                                            // (since I'm technically dealing with 0s and 1s, it's not a total misuse of them imo);
                System.out.print(u[x][y]);
            } // a penalty of overaround 40 bytes for outputting the result - this can be further increased to improve readability - see belowbelow;
            System.out.println();
        }
    l.clear();    // clearsthis is the mainline array;of code added to fix the weird behaviour;
    l.addAll(r);    // addssince the cellsinformation fromabout the currentnew generation is now in the array list, this array can be emptied out, ready to it;receive said info on the new generation;
        for(int[]t:u)Arrays.fill(t,0);
    }
} // end of lambda statement

Yes, there's a catch with my approach. Actually there's more than one; I'll briefly touch on the ones I'm aware of.(more information about lambda statements in Java 8 here)

Yes, there's a catch with my approach. Actually there's more than one; I'll briefly touch on the ones I'm aware of.

Firstly, asAs most of you probably noticed, my golfed code as it currently stands will loop forever. To prevent this, a counter can be introduced at the top and used in the while loop to only display n (in this case, 5) iterations as follows (notice the new b variable added):

The second, more considerable catch is the "user input". I...may have complicated that a little in an attempt to golf this as much as I possibly could. As such, entering live cells in the initial pattern (generation=0) will have to be done in the following manner (and in the exact position on the code):

l.add(new Point(x,y)); // l is the array defined in my code; I don't think I need to define what x and y would be ;)

as shown in this Try it online! (use this one for instant testing) link. (consequentally, the coordinates defined within that link translate to a glider, so it should 'gracefully' fly across the field.) That's why I advised against using the first link if you wanted to instantly check whether the program is valid or not.

The second, more considerable catch is the "user input". I...may have complicated that a little in an attempt to golf this as much as I possibly could. As such, entering live cells in the initial pattern (generation=0) will have to be done in the following manner (and in the exact position on the code):

l.add(new Point(x,y)); // l is the array defined in my code; I don't think I need to define what x and y would be ;)

as shown in this Try it online! (use this one for instant testing) link. (consequentally, the coordinates defined within that link translate to a glider, so it should 'gracefully' fly across the field.) That's why I advised against using the first link if you wanted to instantly check whether the program is valid or not. This second point is no longer valid given that my program now takes in a parameter defined as a 2D array, making user input considerably easier in this new version.

Finally, a few points worth mentioning. This program does not check if the input is correct and will, therefore, fail with (most likely) an ArrayOutOfBoundsException; as such, make sure to check the coordinates are within the limits defined as w and h - I've checked and double-checked that everything runs as it should through a GUI I had already built a while ago. make sure to check the coordinates are within the limits defined as w and h - I've checked and double-checked that everything runs as it should through a GUI I had already builtthe input is valid by completely filling in a while agopart of an array (skewered arrays will throw the exception mentioned above). Also, the board as it currently is looks 'fluid' - that is, there is no separation between one generation and the next. If you wish to add that in to double-check that the generations being produced are indeed valid, an extra System.out.println(); needs to be added just before lfor(int[]t:u)Arrays.clearfill(t,0); (since I can't post more than two links, I'm hopingsee this explanation is good enough ;)Try it online! for clarity). And last, but not least, given that this is my first code golf, any feedback is greatly appreciated :)

P.S.: I would be curious to see if anyone could write this implementation using only two data structures instead of threeI would be curious to see if anyone could write this implementation using only two data structures instead of three as I did in my code - one 2D int array and two array lists with elements of type Point (or, if it's not possible, to perhaps provide an explanation as to why because for a while I was under the impression that I could but nothing I tried worked properly). Solved it as I didexplained above in my code - one 2D int array and two array lists with elements of type Point (or, if it's not possible, to perhaps provide an explanation as to why because for a while I was under the impression that I could but nothing I tried worked properly)'new' post.

Old code from previous 400 byte answer here:

int w=35,h=20,x,y,i,j,n;ArrayList<Point>l=new ArrayList<Point>(),r;while(true){int[][]u=new int[w][h];for(Point c:l)u[c.x][c.y]=1;r=new ArrayList<Point>();for(x=0;x<w;++x){for(y=0;y<h;++y){boolean o=u[x][y]==1;n=o?-1:0;for(i=-2;++i<2;)for(j=-2;++j<2;)if(u[(w+x+i)%w][(h+y+j)%h]==1)++n;if(o&n>1&n<4|!o&n==3)r.add(new Point(x,y));System.out.print(u[x][y]);}System.out.println();}l.clear();l.addAll(r);}

However I had a few issues because the code was suddently giving out weird and different results for both stable and non-stable patterns. Luckily I solved that at the cost of 30 bytes - which still brings me under the 400 byte mark.

int w=35,h=20,x,y,i,j,n;ArrayList<Point>l=new ArrayList<Point>(),r;while(true){int[][]u=new int[w][h];for(Point c:l)u[c.x][c.y]=1;r=new ArrayList<Point>();for(x=0;x<w;++x){for(y=0;y<h;++y){boolean o=u[x][y]==1;n=o?-1:0;for(i=-2;++i<2;)for(j=-2;++j<2;)if(u[(w+x+i)%w][(h+y+j)%h]==1)++n;if(o&n>1&n<4|!o&n==3)r.add(new Point(x,y));System.out.print(u[x][y]);}System.out.println();}l.clear();l.addAll(r);}

Try it online! (don't actually use this - see below why) See edit above.

/*
 * Explanation of each variable's usage:
 * w=width of array
 * h=height of array
 * x=x coord of point in array
 * y=y coord of point in array
 * i and j are counters for calculating the neighbours around a point in the array
 * n=neighbour counter
 * l=array list of alive cells from current generation
 * r=temporary array to store the cells from the current generation
 * u=the 2d array used for all the calculations
 * c=temporary variable used to help populate the 2d array
 * o=boolean variable that stores the value of whether the cell is alive or not
 */
int w=35,h=20,x,y,i,j,n; // defines all the necessary integer variables;
ArrayList<Point>l=new ArrayList<Point>(),r; // same with the array lists;
while(true)
{
    int[][]u=new int[w][h]; //our 2D array which will be processed below;
    for(Point c:l) u[c.x][c.y]=1; //for every point in the "previous" generation, add that to the 2D array as a live (evil?) cell;
    r=new ArrayList<Point>(); // initialises this array list object - it needs to be here otherwise it feeds the other array with previous generations;
    for(x=0;x<w;++x) // a pair of nested for loops to iterate over every cell of the 2D array;
    {
        for(y=0;y<h;++y)
        {
            // sets o to be the presence of a live cell at (x,y) then uses said value in initialising the neighbour counter;
            boolean o=u[x][y]==1;n=o?-1:0;
            for(i=-2;++i<2;) // another pair of nested for loops - this one iterates over a 3x3 grid around *each* cell of the 2D array;
            {                // this includes wrap-around (note the modulus sign in the if statement below);
                for(j=-2;++j<2;)
                {
                    if(u[(w+x+i)%w][(h+y+j)%h]==1)++n; // this is where the first interesting thing lies - the bit which makes wrap-around a reality;
                }
            }
            if(o&n>1&n<4|!o&n==3) r.add(new Point(x,y)); // this is the second interesting bit of my code - perhaps more so as I use bitwise operators to calculate the number of neighbours (x,y) has;
                                                         // (since I'm technically dealing with 0s and 1s, it's not a total misuse of them imo);
            System.out.print(u[x][y]);
        } // a penalty of over 40 bytes for outputting the result - this can be further increased to improve readability - see below
        System.out.println();
    }
    l.clear();   // clears the main array;
    l.addAll(r); // adds the cells from the current generation to it;
}

Yes, there's a catch with my approach. Actually there's more than one; I'll briefly touch on the ones I'm aware of.

Firstly, as most of you probably noticed, my golfed code as it currently stands will loop forever. To prevent this, a counter can be introduced at the top and used in the while loop to only display n (in this case, 5) iterations as follows (notice the new b variable added):

The second, more considerable catch is the "user input". I...may have complicated that a little in an attempt to golf this as much as I possibly could. As such, entering live cells in the initial pattern (generation=0) will have to be done in the following manner (and in the exact position on the code):

l.add(new Point(x,y)); // l is the array defined in my code; I don't think I need to define what x and y would be ;)

as shown in this Try it online! (use this one for instant testing) link. (consequentally, the coordinates defined within that link translate to a glider, so it should 'gracefully' fly across the field.) That's why I advised against using the first link if you wanted to instantly check whether the program is valid or not.

Finally, a few points worth mentioning. This program does not check if the input is correct and will, therefore, fail with (most likely) an ArrayOutOfBoundsException; as such, make sure to check the coordinates are within the limits defined as w and h - I've checked and double-checked that everything runs as it should through a GUI I had already built a while ago. Also, the board as it currently is looks 'fluid' - that is, there is no separation between one generation and the next. If you wish to add that in to double-check that the generations being produced are indeed valid, an extra System.out.println(); needs to be added just before l.clear() (since I can't post more than two links, I'm hoping this explanation is good enough ;)). And last, but not least, given that this is my first code golf, any feedback is greatly appreciated :)

P.S.: I would be curious to see if anyone could write this implementation using only two data structures instead of three as I did in my code - one 2D int array and two array lists with elements of type Point (or, if it's not possible, to perhaps provide an explanation as to why because for a while I was under the impression that I could but nothing I tried worked properly).

However I had a few issues because the code was suddently giving out weird and different results for both stable and non-stable patterns. Luckily I solved that at the cost of 30 bytes - which still brings me under the 400 byte mark (the added code will be marked accordingly in the explanation below).

Try it online! (don't actually use this - see below why) See edit above for tio link.

/*
 * Explanation of each variable's usage:
 * w=height* of array
 * h=width* of array
 * x=y* coord of point in array
 * y=x* coord of point in array
 * i and j are counters for calculating the neighbours around a point in the array
 * n=neighbour counter
 * r=temporary array to store the cells from the current generation
 * u=the 2d array used for all the calculations (parameter from lambda expression)
 * c=temporary variable used to help populate the 2d array
 * o=boolean variable that stores the value of whether the cell is alive or not
 */
u-> // start of lambda statement with u as parameter (no need for brackets as it's only one parameter being passed)
{
    int w=u.length,h=u[0].length,x,y,i,j,n; // defines all the necessary integer variables;
    ArrayList<Point>r=new ArrayList<Point>(); // same with the only array list needed (note how I only use two data structures);
    while(true)
    {
        for(Point c:r)u[c.x][c.y]=1; //for every point in the "previous" generation, add that to the 2D array as a live (evil?) cell;
        r.clear(); // clears the array list to be populated later on
        for(x=0;x<w;++x) // a pair of nested for loops to iterate over every cell of the 2D array;
        {
            for(y=0;y<h;++y)
            {
                // sets o to be the presence of a live cell at (x,y) then uses said value in initialising the neighbour counter;
                boolean o=u[x][y]==1;n=o?-1:0;
                for(i=-2;++i<2;) // another pair of nested for loops - this one iterates over a 3x3 grid around *each* cell of the 2D array;
                {                // this includes wrap-around (note the modulus sign in the if statement below);
                    for(j=-2;++j<2;)
                    {
                        if(u[(w+x+i)%w][(h+y+j)%h]==1)++n; // this is where the first interesting thing lies - the bit which makes wrap-around a reality;
                    }
                }
                if(o&n>1&n<4|!o&n==3)r.add(new Point(x,y)); // this is the second interesting bit of my code - perhaps more so as I use bitwise operators to calculate the number of neighbours (x,y) has;
                                                            // (since I'm technically dealing with 0s and 1s, it's not a total misuse of them imo);
                System.out.print(u[x][y]);
            } // a penalty of around 40 bytes for outputting the result - this can be further increased to improve readability - see below;
            System.out.println();
        }
        // this is the line of code added to fix the weird behaviour;
        // since the information about the new generation is now in the array list, this array can be emptied out, ready to receive said info on the new generation;
        for(int[]t:u)Arrays.fill(t,0);
    }
} // end of lambda statement

(more information about lambda statements in Java 8 here)

Yes, there's a catch with my approach. Actually there's more than one; I'll briefly touch on the ones I'm aware of.

Firstly, As most of you probably noticed, my golfed code as it currently stands will loop forever. To prevent this, a counter can be introduced at the top and used in the while loop to only display n (in this case, 5) iterations as follows (notice the new b variable added):

The second, more considerable catch is the "user input". I...may have complicated that a little in an attempt to golf this as much as I possibly could. As such, entering live cells in the initial pattern (generation=0) will have to be done in the following manner (and in the exact position on the code):

l.add(new Point(x,y)); // l is the array defined in my code; I don't think I need to define what x and y would be ;)

as shown in this Try it online! (use this one for instant testing) link. (consequentally, the coordinates defined within that link translate to a glider, so it should 'gracefully' fly across the field.) That's why I advised against using the first link if you wanted to instantly check whether the program is valid or not. This second point is no longer valid given that my program now takes in a parameter defined as a 2D array, making user input considerably easier in this new version.

Finally, a few points worth mentioning. This program does not check if the input is correct and will, therefore, fail with (most likely) an ArrayOutOfBoundsException; as such, make sure to check the coordinates are within the limits defined as w and h - I've checked and double-checked that everything runs as it should through a GUI I had already built a while ago. make sure to check that the input is valid by completely filling in a part of an array (skewered arrays will throw the exception mentioned above). Also, the board as it currently is looks 'fluid' - that is, there is no separation between one generation and the next. If you wish to add that in to double-check that the generations being produced are indeed valid, an extra System.out.println(); needs to be added just before for(int[]t:u)Arrays.fill(t,0); (see this Try it online! for clarity). And last, but not least, given that this is my first code golf, any feedback is greatly appreciated :)

P.S.: I would be curious to see if anyone could write this implementation using only two data structures instead of three as I did in my code - one 2D int array and two array lists with elements of type Point (or, if it's not possible, to perhaps provide an explanation as to why because for a while I was under the impression that I could but nothing I tried worked properly). Solved it as explained above in the 'new' post.

Old code from previous 400 byte answer here:

int w=35,h=20,x,y,i,j,n;ArrayList<Point>l=new ArrayList<Point>(),r;while(true){int[][]u=new int[w][h];for(Point c:l)u[c.x][c.y]=1;r=new ArrayList<Point>();for(x=0;x<w;++x){for(y=0;y<h;++y){boolean o=u[x][y]==1;n=o?-1:0;for(i=-2;++i<2;)for(j=-2;++j<2;)if(u[(w+x+i)%w][(h+y+j)%h]==1)++n;if(o&n>1&n<4|!o&n==3)r.add(new Point(x,y));System.out.print(u[x][y]);}System.out.println();}l.clear();l.addAll(r);}
Fixed the omission of the code for the function itself.
Source Link
NotBaal
  • 161
  • 1
  • 6

Java (OpenJDK 8) - 400400 388 bytes

EDIT: As per Zacharý's comment, the code I submitted doesn't really form a working program/function (silly me I know :P). With that in mind, I set out to fix this - turns out, using a lambda expression, I not only fix that requirement, I also managed to shave 42 bytes off the result - and funny enough, I ended up 'solving' the problem noted in the P.S. by myself.

Resulting code:

u->{int w=u.length,h=u[0].length,x,y,i,j,n;ArrayList<Point>r=new ArrayList<Point>();while(true){for(Point c:r)u[c.x][c.y]=1;r.clear();for(x=0;x<w;++x){for(y=0;y<h;++y){boolean o=u[x][y]==1;n=o?-1:0;for(i=-2;++i<2;)for(j=-2;++j<2;)if(u[(w+x+i)%w][(h+y+j)%h]==1)++n;if(o&n>1&n<4|!o&n==3)r.add(new Point(x,y));System.out.print(u[x][y]);}System.out.println();}for(int[]t:u)Arrays.fill(t,0);}}

Try it online!

However I had a few issues because the code was suddently giving out weird and different results for both stable and non-stable patterns. Luckily I solved that at the cost of 30 bytes - which still brings me under the 400 byte mark.

(Original post starts here.)

Try it online! (don't actually use this - see below why)Try it online! (don't actually use this - see below why) See edit above.

Java (OpenJDK 8) - 400 bytes

Try it online! (don't actually use this - see below why)

Java (OpenJDK 8) - 400 388 bytes

EDIT: As per Zacharý's comment, the code I submitted doesn't really form a working program/function (silly me I know :P). With that in mind, I set out to fix this - turns out, using a lambda expression, I not only fix that requirement, I also managed to shave 42 bytes off the result - and funny enough, I ended up 'solving' the problem noted in the P.S. by myself.

Resulting code:

u->{int w=u.length,h=u[0].length,x,y,i,j,n;ArrayList<Point>r=new ArrayList<Point>();while(true){for(Point c:r)u[c.x][c.y]=1;r.clear();for(x=0;x<w;++x){for(y=0;y<h;++y){boolean o=u[x][y]==1;n=o?-1:0;for(i=-2;++i<2;)for(j=-2;++j<2;)if(u[(w+x+i)%w][(h+y+j)%h]==1)++n;if(o&n>1&n<4|!o&n==3)r.add(new Point(x,y));System.out.print(u[x][y]);}System.out.println();}for(int[]t:u)Arrays.fill(t,0);}}

Try it online!

However I had a few issues because the code was suddently giving out weird and different results for both stable and non-stable patterns. Luckily I solved that at the cost of 30 bytes - which still brings me under the 400 byte mark.

(Original post starts here.)

Try it online! (don't actually use this - see below why) See edit above.

Source Link
NotBaal
  • 161
  • 1
  • 6
Loading