{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "
Generation: 3, Population: 4\n", ". . . . .\n", ". . . . .\n", ". @ @ . .\n", ". @ @ . .\n", ". . . . ." ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "animate_life(world, 4, range(5), range(5), 1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Interesting Worlds\n", "\n", "Now let's take a look at some configurations of cells that *Life* enthusiasts have discovered. It would be tedious to write out a set of `(x, y)` coordinates, so we will define the function `shape` that takes a picture as input and returns a world; `shape` and `picture` are more-or-less inverses. " ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "def shape(picture, dx=3, dy=3) -> World:\n", " \"\"\"Convert a graphical picture (e.g. '@ @ .\\n. @ @') into a world (set of cells).\"\"\"\n", " cells = {(x, y) \n", " for (y, row) in enumerate(picture.splitlines())\n", " for (x, c) in enumerate(row.replace(PAD, ''))\n", " if c == LIVE}\n", " return slide(cells, dx, dy)\n", "\n", "def slide(cells, dx, dy):\n", " \"\"\"Translate/slide a set of cells by a (dx, dy) offset.\"\"\"\n", " return {(x + dx, y + dy) for (x, y) in cells}\n", "\n", "blinker = shape(\"@@@\")\n", "block = shape(\"@@\\n@@\")\n", "beacon = block | slide(block, 2, 2)\n", "toad = shape(\".@@@\\n@@@.\")\n", "glider = shape(\".@.\\n..@\\n@@@\")\n", "rpentomino = shape(\".@@\\n@@.\\n.@.\", 36, 20)\n", "line = shape(\".@@@@@@@@.@@@@@...@@@......@@@@@@@.@@@@@\", 10, 10)\n", "growth = shape(\"@@@.@\\n@\\n...@@\\n.@@.@\\n@.@.@\", 15, 20)\n", "zoo = (slide(blinker, 5, 25) | slide(glider, 8, 13) | slide(blinker, 20, 25) |\n", " slide(beacon, 24, 25) | slide(toad, 30, 25) | slide(block, 13, 25) | slide(block, 17, 33))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here is how `shape` and `slide` work:" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{(3, 3), (4, 3), (4, 4), (5, 4)}" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "shape(\"\"\"@ @ .\n", " . @ @\"\"\")" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ ". . . . . . .\n", ". . . . . . .\n", ". . . . . . .\n", ". . . @ @ . .\n", ". . . . @ @ .\n", ". . . . . . .\n", ". . . . . . .\n" ] } ], "source": [ "print(picture(_, range(7), range(7)))" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{(3, 3), (3, 4), (4, 3), (4, 4)}" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "block" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{(103, 203), (103, 204), (104, 203), (104, 204)}" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "slide(block, 100, 200)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's run some examples. If you are viewing a static notebook, you will only see the last generation; rerun each cell to see all the generations." ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
Generation: 9, Population: 3\n", ". . . . . . . . . .\n", ". . . . . . . . . .\n", ". . . . @ . . . . .\n", ". . . . @ . . . . .\n", ". . . . @ . . . . .\n", ". . . . . . . . . .\n", ". . . . . . . . . .\n", ". . . . . . . . . .\n", ". . . . . . . . . .\n", ". . . . . . . . . ." ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "animate_life(blinker)" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
Generation: 9, Population: 6\n", ". . . . . . . . . .\n", ". . . . . . . . . .\n", ". . . . . . . . . .\n", ". . . @ @ . . . . .\n", ". . . @ . . . . . .\n", ". . . . . . @ . . .\n", ". . . . . @ @ . . .\n", ". . . . . . . . . .\n", ". . . . . . . . . .\n", ". . . . . . . . . ." ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "animate_life(beacon)" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
Generation: 9, Population: 6\n", ". . . . . . . . . .\n", ". . . . . . . . . .\n", ". . . . . @ . . . .\n", ". . . @ . . @ . . .\n", ". . . @ . . @ . . .\n", ". . . . @ . . . . .\n", ". . . . . . . . . .\n", ". . . . . . . . . .\n", ". . . . . . . . . .\n", ". . . . . . . . . ." ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "animate_life(toad)" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
Generation: 19, Population: 5\n", ". . . . . . . . . .\n", ". . . . . . . . . .\n", ". . . . . . . . . .\n", ". . . . . . . . . .\n", ". . . . . . . . . .\n", ". . . . . . . . . .\n", ". . . . . . . . . .\n", ". . . . . . . . . .\n", ". . . . . . . . @ .\n", ". . . . . . . . . @" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "animate_life(glider, 20)" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
Generation: 129, Population: 163\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ @ @ . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . . . . . . @ @\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ @\n", ". . . . @ . . . @ @ . . @ . . . . . . . . . . . . . . . . . . . . . . . @ @ . . . . . . . @ . @\n", ". . . . @ . @ @ . . . . @ . . . . . . . . . . . . . . . . . . . . . . . @ @ . . . . . . . @ . @\n", ". . . . @ . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ .\n", ". . . . . . . @ . . . @ . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . . . . . . . .\n", ". . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . . . . . . .\n", ". . . . . . . @ . @ . . . . . . . . . . . . . . . . . . @ @ . . . . @ . . . . . . . . . . . . .\n", ". . . . . @ . . . @ @ . . . . . . . . . . . . . . . . @ @ @ . . . @ . . . . . . . . . . . . . .\n", ". . . . @ @ . . . @ . . . . . . . . . . . . . . . . . @ . . . . . . . . . . . . . . . . . @ @ @\n", ". . . . @ . . . . . . . . . . . . . . . . . . . . . . . @ @ . . . . . . . . . . . . . . . @ . .\n", ". . . . . @ . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . @ @ @ . . . . . . . @ @\n", ". . . . . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . @ @ . @ @ @ . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ @ @ @ @ @ @ . . . @ . . . . .\n", "@ . . . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . @ @ @ @ . . . . . . @ . @ @ . . .\n", "@ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ @ . . . . . . . . . . @ @ . . . .\n", ". . @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . . . . @ . . . . .\n", ". . . @ . . @ @ . . . . . . . . . . . . . . . . . . . . . . . . @ @ @ @ @ . . . . . . . . . . .\n", "@ . . @ . . . . . . . . . . . @ @ . . . . . . . . . . . . . . . . @ @ @ . . . . . . . . . . . .\n", "@ @ . @ . . . . . . . . . . . @ @ . . . . . . . . . . . . . . . . . . @ . . . . . . . . . . . .\n", ". @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . @ . . . @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . @ . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . @ @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ." ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "animate_life(rpentomino, 130, range(48), range(40))" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
Generation: 159, Population: 105\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . @\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . @ . . . @\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ @ @ . . @ . @ . . @ .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ @ . @ . . . @ @ . . . @\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . @ . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . @ . . . @ . @ @ . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . @ . . . @ @ . @ @ @ . . . @ . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . @ @ . . @ @ @ @ . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . @ . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ @ @ @ @ @ . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . @ @ . . . . . . . @ .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . @ . . . . . . . . @ @ .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ @ @ . . . . . . . . . @ .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ @ . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ @ . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . @ . . . . . . @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . @ . . . . . @ . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ @ . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ @ . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ." ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "animate_life(zoo, 160, range(48), range(40))" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
Generation: 199, Population: 100\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . @ @ . . @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . @ . . @ . @ @ @ . . . @ . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . @ . @ . . . @ @ @ . @ . . . @ @ . . @ @ . . . . . . . . . . . . . .\n", ". . . . . . @ . . . @ . @ @ @ . . . . . . @ @ . @ @ @ . . . . . . . . . . . . .\n", ". . . . . . . @ . . . @ @ @ . . . . . @ . @ . @ . . . @ @ . . . . . . . . . . .\n", ". . . . . . . . @ . . . @ . @ @ . . . . @ . . @ . @ . @ @ . . . . . . . . . . .\n", ". . . . . . . . . . . @ . . . @ . . @ @ . . . @ . @ . @ @ . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . @ @ @ . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . @ @ . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . @ . @ . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . @ . . @ . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . @ . . . . . @ . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . @ . @ @ . @ . . . . . . @ @ @ . . .\n", ". . . . . . . . . . . . . . . . . . . . . @ . . . @ @ @ . . . . . @ . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . @ . . . @ . . . . . . @ . . @ . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . @ @ @ @ . . . . . . . @ @ . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . @ @ . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . @ @ . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . @ @ . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . @ @ . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ." ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "animate_life(growth, 200, range(40), range(40))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Outside of IPython\n", "\n", "If you want to run this code in your terminal, outside of an Ipython/Jupyter notebook, you can remove the line:\n", "\n", " from IPython.display import clear_output, display_html\n", " \n", "and add these lines:\n", "\n", " def clear_output(): print(\"\\033[;H\\033[2J\") # ANSI terminal home and clear\n", " def display_html(text, raw=False): print(text) \n", " def pre(text) -> str: return text\n", " \n", "If you want to create a fancier display using some graphics packagee, be my guest. Let me know what you create.\n", " \n", "# Coding Kata\n", "\n", "I once attended a [code kata](https://en.wikipedia.org/wiki/Kata_%28programming%29) in which one of the exercises was to write *Life* without using any conditional (e.g. `if`) statements. I did it by using roughly the program shown here, but changing the lone `if` to a `filter` in `next_generation`:" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [], "source": [ "def next_generation(world):\n", " \"\"\"The set of live cells in the next generation.\"\"\"\n", " counts = neighbor_counts(world)\n", " def live(cell): return counts[cell] == 3 or (counts[cell] == 2 and cell in world)\n", " return set(filter(live, counts))" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.7" } }, "nbformat": 4, "nbformat_minor": 1 }