{"id":214,"date":"2010-01-19T12:16:32","date_gmt":"2010-01-19T12:16:32","guid":{"rendered":"https:\/\/blogs.mathworks.com\/loren\/2010\/01\/19\/mathematical-recreations-tweetable-game-of-life\/"},"modified":"2010-01-19T12:16:32","modified_gmt":"2010-01-19T12:16:32","slug":"mathematical-recreations-tweetable-game-of-life","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/loren\/2010\/01\/19\/mathematical-recreations-tweetable-game-of-life\/","title":{"rendered":"Mathematical Recreations: Tweetable Game Of Life"},"content":{"rendered":"<div xmlns:mwsh=\"https:\/\/www.mathworks.com\/namespace\/mcode\/v1\/syntaxhighlight.dtd\" class=\"content\">\r\n   <introduction>\r\n      <p>Today I&#8217;d like to introduce a guest blogger, Matt, who is consultant over in The MathWorks UK. Some of you may have come across\r\n         his customer projects and series of demos on using <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/22732-matlab-in-physics-visualisation\"><tt>MATLAB in Physics<\/tt><\/a>. He&#8217;s going to talk about an interesting one line MATLAB program.\r\n      <\/p>\r\n   <\/introduction>\r\n   <h3>Contents<\/h3>\r\n   <div>\r\n      <ul>\r\n         <li><a href=\"#1\">Introduction<\/a><\/li>\r\n         <li><a href=\"#6\">Conway's Game Of Life<\/a><\/li>\r\n         <li><a href=\"#7\">Calculating The Number Of Neighbours<\/a><\/li>\r\n         <li><a href=\"#10\">Calculating The Next State<\/a><\/li>\r\n         <li><a href=\"#12\">Reducing The Size<\/a><\/li>\r\n         <li><a href=\"#18\">Modifications<\/a><\/li>\r\n         <li><a href=\"#23\">Conclusion<\/a><\/li>\r\n      <\/ul>\r\n   <\/div>\r\n   <h3>Introduction<a name=\"1\"><\/a><\/h3>\r\n   <p>One Saturday afternoon I saw a link on <a href=\"http:\/\/news.ycombinator.com\/item?id=1041500\"><tt>Hacker News<\/tt><\/a> to a <a href=\"http:\/\/www.youtube.com\/watch?gl=GB&amp;hl=en-GB&amp;v=a9xAKttWgP4&amp;fmt=18\"><tt>YouTube<\/tt><\/a> video showing Conway's Game of Life in one line of APL.  This made me wonder whether MATLAB&reg; could perform as well.\r\n   <\/p>\r\n   <p>The answer: maybe not quite a single line, but definitely a <a href=\"http:\/\/twitter.com\/mattmcd\/statuses\/7589620127\"><tt>tweet<\/tt><\/a>.\r\n   <\/p>\r\n   <p>The code is reproduced below:<\/p><pre>s=[1 1 1]';\r\nn=@(a)conv2(s,s',1*a,'same')-a;\r\nlf=@(a)n(a)==2&amp;a|n(a)==3;\r\na=rand(128)&gt;0.8;\r\nfor ii=1:500,spy(a);drawnow;a=lf(a);end<\/pre><p>In the code below I've commented out the population initialisation and visualisation code and replaced it with various alternatives\r\n      for this published version, together with an animated gif of the output.\r\n   <\/p><pre>A = accumarray([3 3; 3 4; 4 2; 4 4; 5 4],1,[7 7]);\r\nimagesc(~A); colormap(gray);\r\nfor ii=1:9,imagesc(~A);drawnow;A=lf(A);end<\/pre><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/loren\/214\/glider.gif\"> <\/p>\r\n   <p>In this post I'll show the evolution of the code from initial conception to finished version, and how thinking in matrices\r\n      can lead to new algorithms.\r\n   <\/p>\r\n   <h3>Conway's Game Of Life<a name=\"6\"><\/a><\/h3>\r\n   <p><a href=\"http:\/\/en.wikipedia.org\/wiki\/Conway's_Game_of_Life\"><tt>Conway's Game of Life<\/tt><\/a> is a two-dimensional cellular automation that demonstrates complex behaviour.\r\n   <\/p>\r\n   <p>It consists of a grid of cells, each of which may be in one of two possible states, 0 ('dead') or 1 ('alive').  The state\r\n      of each cell in the next iteration of the game is dependent on the state of the surrounding eight cells as follows:\r\n   <\/p>\r\n   <div>\r\n      <ul>\r\n         <li>a live cell with 2 neighbours remains alive<\/li>\r\n         <li>any cell with 3 neighbours becomes or remains alive<\/li>\r\n         <li>any other cell dies of loneliness or overcrowding<\/li>\r\n      <\/ul>\r\n   <\/div>\r\n   <p>The core of the algorithm consists of two steps:<\/p>\r\n   <div>\r\n      <ul>\r\n         <li>calculate the number of live neighbours of each cell<\/li>\r\n         <li>using this, determine the new state of each cell based on its current   state<\/li>\r\n      <\/ul>\r\n   <\/div>\r\n   <h3>Calculating The Number Of Neighbours<a name=\"7\"><\/a><\/h3>\r\n   <p>To calculate the number of neighbours for each cell one approach would be to loop over each cell in the array, add up the\r\n      number of live cells in the surrounding 3x3 square, and finally subtract the state of the cell itself.\r\n   <\/p>\r\n   <p>The YouTube video used the different approach of creating 8 copies of the original array, offseting each by a step horizontally\r\n      and\/or vertically and then summing the arrays.\r\n   <\/p>\r\n   <p>The key part of development of my algorithm was to realise that this looping-with-sum-over-neighbourhood is just a 2D convolution.\r\n       In MATLAB we can do a 2D convolution using <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2009b\/techdoc\/ref\/conv2.html\"><tt>conv2<\/tt><\/a>.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">S = [1 1 1; 1 0 1; 1 1 1]\r\nneighbours=@(a) conv2(double(a),S,<span style=\"color: #A020F0\">'same'<\/span>)<\/pre><pre style=\"font-style:oblique\">S =\r\n     1     1     1\r\n     1     0     1\r\n     1     1     1\r\nneighbours = \r\n    @(a)conv2(double(a),S,'same')\r\n<\/pre><p>The 'same' argument is to restrict the output of conv2 to be the same size as the original input matrix.<\/p>\r\n   <p>For example:<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">b = rand(5)&gt;0.5\r\nneighbours(b)<\/pre><pre style=\"font-style:oblique\">b =\r\n     0     0     1     1     1\r\n     1     1     0     1     0\r\n     1     0     1     0     1\r\n     0     1     1     0     0\r\n     0     0     1     0     1\r\nans =\r\n     2     3     3     3     2\r\n     2     4     5     5     4\r\n     3     6     4     4     1\r\n     2     4     3     5     2\r\n     1     3     2     3     0\r\n<\/pre><h3>Calculating The Next State<a name=\"10\"><\/a><\/h3>\r\n   <p>After calculating the number of neighbours, the next step is to use it to determine the next state using the rules of Conway's\r\n      Game of Life.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">life = @(a) (neighbours(a)==2 &amp; a)<span style=\"color: #0000FF\">...<\/span><span style=\"color: #228B22\">  % Rule for 2 neighbours<\/span>\r\n    | (neighbours(a)==3)               <span style=\"color: #228B22\">% Rule for 3 neighbours<\/span>\r\nb\r\nlife(b)<\/pre><pre style=\"font-style:oblique\">life = \r\n    @(a)(neighbours(a)==2&amp;a)|(neighbours(a)==3)\r\nb =\r\n     0     0     1     1     1\r\n     1     1     0     1     0\r\n     1     0     1     0     1\r\n     0     1     1     0     0\r\n     0     0     1     0     1\r\nans =\r\n     0     1     1     1     1\r\n     1     0     0     0     0\r\n     1     0     0     0     0\r\n     0     0     1     0     0\r\n     0     1     1     1     0\r\n<\/pre><p>Let's use this as a reference implementation to test that modifications to the function do the same thing:<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">t = @(fOrig,f,a) assert(all(all(fOrig(a) == f(a))));<\/pre><h3>Reducing The Size<a name=\"12\"><\/a><\/h3>\r\n   <p><a href=\"http:\/\/twitter.com\"><tt>Twitter<\/tt><\/a> allows users to post 'tweets' of up to 140 characters in length.  Fitting in the Game of Life evolution function <i>and<\/i> visualisation in this limit required a few tricks:\r\n   <\/p>\r\n   <p>Use the syntax of conv2 that uses 1D vectors for the filter.  This happens to also be faster but requires an extra element-wise\r\n      matrix subtraction:\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">s = [1 1 1]';\r\nn2 = @(a) conv2(s,s',double(a),<span style=\"color: #A020F0\">'same'<\/span>)-a;\r\nt(neighbours, n2, b)<\/pre><p>Drop some more characters by using an implicit cast to double by multiplying a by 1. Also remove spaces:<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">n=@(a)conv2(s,s',1*a,<span style=\"color: #A020F0\">'same'<\/span>)-a;\r\nt(neighbours, n2, b)<\/pre><p>Now shorten the Life rule function by removing spaces and parentheses, instead relying on the operator precedence rules:<\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">lf=@(a)n(a)==2&amp;a|n(a)==3;\r\nt(life,lf,b)<\/pre><p>Finally, initialise a random population and visualise using <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2009b\/techdoc\/ref\/spy.html\"><tt>spy<\/tt><\/a> in a loop:\r\n   <\/p><pre>a=rand(128)&gt;0.8;for ii=1:25,spy(a);drawnow;a=lf(a);end<\/pre><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/loren\/214\/life.gif\"> <\/p>\r\n   <h3>Modifications<a name=\"18\"><\/a><\/h3>\r\n   <p>It is possible to lose a few more characters by changing the 'for' loop to a 'while 1' loop (to go forever), changing the\r\n      definition of s to be a row vector, changing the 0.8 to .8, etc.  I stopped at the point where I did since it allowed me to\r\n      fit the code into a tweet, with room for a #MATLAB tag.\r\n   <\/p>\r\n   <p>A modification that <i>would<\/i> be worth making is to introduce periodic boundary conditions:\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">makeperiodic = @(a) [a(end,end), a(end,:),a(end,1);<span style=\"color: #0000FF\">...<\/span>\r\n    a(:,end),a,a(:,1);<span style=\"color: #0000FF\">...<\/span>\r\n    a(1,end),a(1,:),a(1,1)];\r\nunperiodic = @(a) a(2:end-1,2:end-1);\r\nnp = @(a) unperiodic(n(makeperiodic(a)));\r\nlfp = @(a) np(a)==2&amp;a|np(a)==3;<\/pre><p>(an alternative is to use the <a href=\"https:\/\/www.mathworks.com\/access\/helpdesk\/help\/releases\/R2009b\/toolbox\/images\"><tt>Image Processing Toolbox<\/tt><\/a> <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2009b\/toolbox\/images\/imfilter.html\"><tt>imfilter<\/tt><\/a> command which has an option to use periodic boundaries)\r\n   <\/p>\r\n   <p>... and making the visualisation nicer:<\/p><pre>A = accumarray([3 3; 3 4; 4 2; 4 4; 5 4],1,[7 7]);\r\nimagesc(~A); colormap(gray);\r\nfor ii=1:25,imagesc(~A);drawnow;A=lfp(A);end<\/pre><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/loren\/214\/glider_periodic.gif\"> <\/p>\r\n   <p>Other things to try are left as an exercise for the reader:<\/p>\r\n   <div>\r\n      <ul>\r\n         <li>other life rules e.g. <a href=\"http:\/\/en.wikipedia.org\/wiki\/HighLife\"><tt>HighLife<\/tt><\/a>   (hint: think about using   <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2009b\/techdoc\/ref\/ismember.html\">  <tt>ismember<\/tt><\/a>)\r\n         <\/li>\r\n         <li>1D or 3D life (hint: think about using   <a href=\"https:\/\/www.mathworks.com\/help\/releases\/R2009b\/techdoc\/ref\/convn.html\">  <tt>convn<\/tt><\/a>)\r\n         <\/li>\r\n      <\/ul>\r\n   <\/div>\r\n   <h3>Conclusion<a name=\"23\"><\/a><\/h3>\r\n   <p>I've shown here how thinking in terms of operations on matrices rather than looping constructs can result in compact code.\r\n       In this case the motivation was just for fun, but in general it can make use of the built-in MATLAB functionality and avoid\r\n      having to reimplement existing functions.\r\n   <\/p>\r\n   <p>Do you have any good one line (or one tweet) MATLAB programs? I'd love to hear from you <a href=\"https:\/\/blogs.mathworks.com\/loren\/?p=214#respond\">here<\/a>.\r\n   <\/p><script language=\"JavaScript\">\r\n<!--\r\n\r\n    function grabCode_1ab7b349823d4f6991bd578962adf84b() {\r\n        \/\/ Remember the title so we can use it in the new page\r\n        title = document.title;\r\n\r\n        \/\/ Break up these strings so that their presence\r\n        \/\/ in the Javascript doesn't mess up the search for\r\n        \/\/ the MATLAB code.\r\n        t1='1ab7b349823d4f6991bd578962adf84b ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 1ab7b349823d4f6991bd578962adf84b';\r\n    \r\n        b=document.getElementsByTagName('body')[0];\r\n        i1=b.innerHTML.indexOf(t1)+t1.length;\r\n        i2=b.innerHTML.indexOf(t2);\r\n \r\n        code_string = b.innerHTML.substring(i1, i2);\r\n        code_string = code_string.replace(\/REPLACE_WITH_DASH_DASH\/g,'--');\r\n\r\n        \/\/ Use \/x3C\/g instead of the less-than character to avoid errors \r\n        \/\/ in the XML parser.\r\n        \/\/ Use '\\x26#60;' instead of '<' so that the XML parser\r\n        \/\/ doesn't go ahead and substitute the less-than character. \r\n        code_string = code_string.replace(\/\\x3C\/g, '\\x26#60;');\r\n\r\n        author = 'Loren Shure';\r\n        copyright = 'Copyright 2010 The MathWorks, Inc.';\r\n\r\n        w = window.open();\r\n        d = w.document;\r\n        d.write('<pre>\\n');\r\n        d.write(code_string);\r\n\r\n        \/\/ Add author and copyright lines at the bottom if specified.\r\n        if ((author.length > 0) || (copyright.length > 0)) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (author.length > 0) {\r\n                d.writeln('% _' + author + '_');\r\n            }\r\n            if (copyright.length > 0) {\r\n                d.writeln('% _' + copyright + '_');\r\n            }\r\n        }\r\n\r\n        d.write('<\/pre>\\n');\r\n      \r\n      d.title = title + ' (MATLAB code)';\r\n      d.close();\r\n      }   \r\n      \r\n-->\r\n<\/script><p style=\"text-align: right; font-size: xx-small; font-weight:lighter;   font-style: italic; color: gray\"><br><a href=\"javascript:grabCode_1ab7b349823d4f6991bd578962adf84b()\"><span style=\"font-size: x-small;        font-style: italic;\">Get \r\n            the MATLAB code \r\n            <noscript>(requires JavaScript)<\/noscript><\/span><\/a><br><br>\r\n      Published with MATLAB&reg; 7.9<br><\/p>\r\n<\/div>\r\n<!--\r\n1ab7b349823d4f6991bd578962adf84b ##### SOURCE BEGIN #####\r\n%% Mathematical Recreations: Tweetable Game Of Life\r\n% Today I\u00e2\u20ac\u2122d like to introduce a guest blogger, Matt, who is consultant over\r\n% in The MathWorks UK. Some of you may have come across his customer projects \r\n% and series of demos on using\r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/22732-matlab-in-physics-visualisation\r\n% |MATLAB in Physics|>.\r\n% He\u00e2\u20ac\u2122s going to talk about an interesting one line MATLAB program.\r\n\r\n%% Introduction \r\n% One Saturday afternoon I saw a link on\r\n% <http:\/\/news.ycombinator.com\/item?id=1041500 |Hacker News|> to a\r\n% <http:\/\/www.youtube.com\/watch?gl=GB&hl=en-GB&v=a9xAKttWgP4&fmt=18\r\n% |YouTube|> video showing Conway's Game of Life in one line of APL.  This\r\n% made me wonder whether MATLAB(R) could perform as well.\r\n%\r\n% The answer: maybe not quite a single line, but definitely a \r\n% <http:\/\/twitter.com\/mattmcd\/statuses\/7589620127 |tweet|>.\r\n%\r\n% The code is reproduced below:\r\n\r\n%%\r\n%  s=[1 1 1]';\r\n% n=@(a)conv2(s,s',1*a,'same')-a;\r\n% lf=@(a)n(a)==2&a|n(a)==3;\r\n% a=rand(128)>0.8;\r\n% for ii=1:500,spy(a);drawnow;a=lf(a);end \r\n\r\n%%\r\n% In the code below I've commented out the population initialisation \r\n% and visualisation code and replaced it with various alternatives\r\n% for this published version, together with an animated gif of the output.\r\n\r\n%% \r\n%  A = accumarray([3 3; 3 4; 4 2; 4 4; 5 4],1,[7 7]);\r\n% imagesc(~A); colormap(gray);\r\n% for ii=1:9,imagesc(~A);drawnow;A=lf(A);end\r\n%\r\n% <<glider.gif>>\r\n% \r\n\r\n%%\r\n% In this post I'll show the evolution of the code from initial conception\r\n% to finished version, and how thinking in matrices can lead to new\r\n% algorithms.\r\n\r\n%% Conway's Game Of Life\r\n% <http:\/\/en.wikipedia.org\/wiki\/Conway's_Game_of_Life |Conway's Game of\r\n% Life|> is a two-dimensional cellular automation that demonstrates complex\r\n% behaviour.  \r\n%\r\n% It consists of a grid of cells, each of which may be in one of two\r\n% possible states, 0 ('dead') or 1 ('alive').  The state of each cell in\r\n% the next iteration of the game is dependent on the state of the\r\n% surrounding eight cells as follows:\r\n%\r\n% * a live cell with 2 neighbours remains alive\r\n% * any cell with 3 neighbours becomes or remains alive\r\n% * any other cell dies of loneliness or overcrowding\r\n%\r\n% The core of the algorithm consists of two steps:\r\n%\r\n% * calculate the number of live neighbours of each cell\r\n% * using this, determine the new state of each cell based on its current\r\n%   state \r\n\r\n%% Calculating The Number Of Neighbours\r\n% To calculate the number of neighbours for each cell one approach would be\r\n% to loop over each cell in the array, add up the number of live cells in the\r\n% surrounding 3x3 square, and finally subtract the state of the cell itself.\r\n%\r\n% The YouTube video used the different approach of creating 8 copies of the\r\n% original array, offseting each by a step horizontally and\/or vertically and\r\n% then summing the arrays.\r\n%\r\n% The key part of development of my algorithm was to realise that this\r\n% looping-with-sum-over-neighbourhood is just a 2D convolution.  In MATLAB\r\n% we can do a 2D convolution using\r\n% <https:\/\/www.mathworks.com\/help\/releases\/R2009b\/techdoc\/ref\/conv2.html\r\n% |conv2|>.\r\nS = [1 1 1; 1 0 1; 1 1 1]\r\nneighbours=@(a) conv2(double(a),S,'same')\r\n\r\n%%\r\n% The 'same' argument is to restrict the output of conv2 to be the same\r\n% size as the original input matrix.\r\n\r\n%% \r\n% For example:\r\nb = rand(5)>0.5\r\nneighbours(b)\r\n\r\n%% Calculating The Next State\r\n% After calculating the number of neighbours, the next step is to use it to\r\n% determine the next state using the rules of Conway's Game of Life.\r\nlife = @(a) (neighbours(a)==2 & a)...  % Rule for 2 neighbours\r\n    | (neighbours(a)==3)               % Rule for 3 neighbours\r\nb\r\nlife(b)\r\n\r\n%%\r\n% Let's use this as a reference implementation to test that modifications\r\n% to the function do the same thing:\r\nt = @(fOrig,f,a) assert(all(all(fOrig(a) == f(a))));\r\n\r\n%% Reducing The Size\r\n% <http:\/\/twitter.com |Twitter|> allows users to post 'tweets' of up to 140\r\n% characters in length.  Fitting in the Game of Life evolution function\r\n% _and_ visualisation in this limit required a few tricks:\r\n%%\r\n% Use the syntax of conv2 that uses 1D vectors for the filter.  This\r\n% happens to also be faster but requires an extra element-wise matrix\r\n% subtraction:\r\ns = [1 1 1]';\r\nn2 = @(a) conv2(s,s',double(a),'same')-a;\r\nt(neighbours, n2, b)\r\n%%\r\n% Drop some more characters by using an implicit cast to double by \r\n% multiplying a by 1. Also remove spaces:\r\nn=@(a)conv2(s,s',1*a,'same')-a;\r\nt(neighbours, n2, b)\r\n%%\r\n% Now shorten the Life rule function by removing spaces and parentheses,\r\n% instead relying on the operator precedence rules:\r\nlf=@(a)n(a)==2&a|n(a)==3;\r\nt(life,lf,b)\r\n%%\r\n% Finally, initialise a random population and visualise using \r\n% <https:\/\/www.mathworks.com\/help\/releases\/R2009b\/techdoc\/ref\/spy.html\r\n% |spy|> in a loop:\r\n\r\n%%\r\n%  a=rand(128)>0.8;for ii=1:25,spy(a);drawnow;a=lf(a);end\r\n%\r\n% <<life.gif>>\r\n%\r\n%% Modifications\r\n% \r\n% It is possible to lose a few more characters by changing the 'for' loop to\r\n% a 'while 1' loop (to go forever), changing the definition of s to be a\r\n% row vector, changing the 0.8 to .8, etc.  I stopped at the point where I\r\n% did since it allowed me to fit the code into a tweet, with room for a\r\n% #MATLAB tag.\r\n%\r\n% A modification that _would_ be worth making is to introduce periodic\r\n% boundary conditions:\r\nmakeperiodic = @(a) [a(end,end), a(end,:),a(end,1);...\r\n    a(:,end),a,a(:,1);...\r\n    a(1,end),a(1,:),a(1,1)];\r\nunperiodic = @(a) a(2:end-1,2:end-1);\r\nnp = @(a) unperiodic(n(makeperiodic(a)));\r\nlfp = @(a) np(a)==2&a|np(a)==3;\r\n\r\n%%\r\n% (an alternative is to use the <https:\/\/www.mathworks.com\/access\/helpdesk\/help\/releases\/R2009b\/toolbox\/images \r\n% |Image Processing Toolbox|>\r\n% <https:\/\/www.mathworks.com\/help\/releases\/R2009b\/toolbox\/images\/imfilter.html\r\n% |imfilter|> command which has an option to use periodic boundaries)\r\n\r\n%%\r\n% ... and making the visualisation nicer:\r\n\r\n%%\r\n%  A = accumarray([3 3; 3 4; 4 2; 4 4; 5 4],1,[7 7]);\r\n% imagesc(~A); colormap(gray);\r\n% for ii=1:25,imagesc(~A);drawnow;A=lfp(A);end\r\n%\r\n% <<glider_periodic.gif>> \r\n%\r\n%%\r\n% Other things to try are left as an exercise for the reader:\r\n%\r\n% * other life rules e.g. <http:\/\/en.wikipedia.org\/wiki\/HighLife |HighLife|>\r\n%   (hint: think about using\r\n%   <https:\/\/www.mathworks.com\/help\/releases\/R2009b\/techdoc\/ref\/ismember.html\r\n%   |ismember|>)\r\n% * 1D or 3D life (hint: think about using\r\n%   <https:\/\/www.mathworks.com\/help\/releases\/R2009b\/techdoc\/ref\/convn.html\r\n%   |convn|>)\r\n\r\n%% Conclusion\r\n% I've shown here how thinking in terms of operations on matrices rather\r\n% than looping constructs can result in compact code.  In this case the\r\n% motivation was just for fun, but in general it can make use of \r\n% the built-in MATLAB functionality and avoid having to reimplement\r\n% existing functions.\r\n%\r\n% Do you have any good one line (or one tweet) MATLAB programs?\r\n% I'd love to hear from you\r\n% <https:\/\/blogs.mathworks.com\/loren\/?p=214#respond here>.\r\n##### SOURCE END ##### 1ab7b349823d4f6991bd578962adf84b\r\n-->","protected":false},"excerpt":{"rendered":"<p>\r\n   \r\n      Today I&#8217;d like to introduce a guest blogger, Matt, who is consultant over in The MathWorks UK. Some of you may have come across\r\n         his customer projects and series of demos... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/loren\/2010\/01\/19\/mathematical-recreations-tweetable-game-of-life\/\">read more >><\/a><\/p>","protected":false},"author":39,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[33,3,27],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/214"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/users\/39"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/comments?post=214"}],"version-history":[{"count":0,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/214\/revisions"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/media?parent=214"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/categories?post=214"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/tags?post=214"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}