{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import itertools\n", "import time\n", "import re\n", "from IPython.display import clear_output\n", "import random" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": true }, "outputs": [], "source": [ "WIDTH = 50\n", "HEIGHT = 8" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def new_grid(w=WIDTH, h=HEIGHT):\n", " return ['.' * w for r in range(1, h+1)]" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def print_grid(grid, md=False, suppress_dots=False):\n", " if md:\n", " print('```')\n", " for row in grid:\n", " if suppress_dots:\n", " print(re.sub(r'\\.', ' ', row))\n", " else:\n", " print(row) \n", " if md:\n", " print('```')" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def top(grid, l, r):\n", " new_segment = ''\n", " for i in range(l-1, r):\n", " if grid[0][i] == '.':\n", " new_segment += '*'\n", " else:\n", " new_segment += '.'\n", " grid[0] = grid[0][:l-1] + new_segment + grid[0][r:]\n", " return grid" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def left(grid, t, b):\n", " for i in range(t-1, b):\n", " if grid[i][0] == '.':\n", " grid[i] = '*' + grid[i][1:]\n", " else:\n", " grid[i] = '.' + grid[i][1:]\n", " return grid" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def rotate_column(grid, c, raw_n):\n", " n = raw_n % len(grid)\n", " col = [row[c-1] for row in grid]\n", " new_col = col[-n:] + col[:-n]\n", " for i in range(len(grid)):\n", " grid[i] = grid[i][:c-1] + new_col[i] + grid[i][c:]\n", " return grid" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def rotate_row(grid, r, raw_n):\n", " n = raw_n % len(grid[0])\n", " grid[r-1] = grid[r-1][-n:] + grid[r-1][:-n]\n", " return grid" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": true }, "outputs": [], "source": [ "command_dispatch = {'left': left, 'top': top,\n", " 'rotate row': rotate_row,\n", " 'rotate column': rotate_column}" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def parse(command):\n", " cmd, a, b = command.rsplit(maxsplit=2)\n", " return cmd, int(a), int(b) " ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def interpret(commands, grid=None, w=WIDTH, h=HEIGHT, \n", " uninterpret=False,\n", " show_each_step=False, md=False, overprint=False,\n", " suppress_dots=False):\n", " if grid is None:\n", " grid = new_grid(w, h)\n", " if uninterpret:\n", " ordered_commands = reversed(commands)\n", " else:\n", " ordered_commands = commands\n", " for c in ordered_commands:\n", " cmd, a, b = parse(c)\n", " if uninterpret and cmd in uncommand_dispatch:\n", " uncommand_dispatch[cmd](grid, a, b)\n", " elif not uninterpret and cmd in command_dispatch:\n", " command_dispatch[cmd](grid, a, b)\n", " else:\n", " raise ValueError('Unknown command')\n", " if show_each_step:\n", " if overprint:\n", " time.sleep(0.25)\n", " if md: \n", " print('`{}`'.format(c))\n", " else:\n", " print(c)\n", " print_grid(grid, md=md, suppress_dots=suppress_dots)\n", " print()\n", " if overprint:\n", " clear_output(wait=True)\n", " if show_each_step: \n", " print('Final')\n", " print_grid(grid, md=md, suppress_dots=suppress_dots)\n", " return grid\n", " \n", " \n", "# for i in range(10):\n", "# time.sleep(0.25)\n", "# print(i)\n", "# clear_output(wait=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For instance, with a smaller grid that is 10 pixels wide and 4 tall, this is what a sample sequence of instructions would do.\n", "\n", "* `toggle 1 6` turns on the first six pixels on the top row.\n", "```\n", "******....\n", "..........\n", "..........\n", "..........\n", "```\n", "\n", "* `rotate column 2 3` moves the lit pixel on the second column to the bottom row.\n", "```\n", "*.****....\n", "..........\n", "..........\n", ".*........\n", "```\n", "\n", "* `toggle 3 10` turns off the pixels in columns 4, 5, and 6, and turns on the pixels in columns 7 to 10.\n", "\n", "```\n", "*.....****\n", "..........\n", "..........\n", ".*........\n", "```\n", "\n", "* `rotate column 8 1` moves the one lit pixel in column 8 down one row.\n", "```\n", "*.....*.**\n", ".......*..\n", "..........\n", ".*........\n", "```\n", "\n", "* `rotate row 2 6` moves that pixel off the right edge of the display, to it wraps around to appear in column 4.\n", "```\n", "*.....*.**\n", "...*......\n", "..........\n", ".*........\n", "```\n", "\n", "* `left 1 3` toggles the pixels in rows 1, 2, and 3 of the first column. The top left pixel (previously on) turns off, while the pixels in rows 2 and 3 come on.\n", "\n", "```\n", "......*.**\n", "*..*......\n", "*.........\n", ".*........\n", "```" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "`top 1 6`\n", "```\n", "******....\n", "..........\n", "..........\n", "..........\n", "```\n", "\n", "`rotate column 2 3`\n", "```\n", "*.****....\n", "..........\n", "..........\n", ".*........\n", "```\n", "\n", "`top 3 10`\n", "```\n", "*.....****\n", "..........\n", "..........\n", ".*........\n", "```\n", "\n", "`rotate column 8 1`\n", "```\n", "*.....*.**\n", ".......*..\n", "..........\n", ".*........\n", "```\n", "\n", "`rotate row 2 6`\n", "```\n", "*.....*.**\n", "...*......\n", "..........\n", ".*........\n", "```\n", "\n", "`left 1 3`\n", "```\n", "......*.**\n", "*..*......\n", "*.........\n", ".*........\n", "```\n", "\n", "Final\n", "```\n", "......*.**\n", "*..*......\n", "*.........\n", ".*........\n", "```\n" ] }, { "data": { "text/plain": [ "['......*.**', '*..*......', '*.........', '.*........']" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cmds = '''\n", "top 1 6\n", "rotate column 2 3\n", "top 3 10\n", "rotate column 8 1\n", "rotate row 2 6\n", "left 1 3\n", "'''.split('\\n')[1:-1]\n", "interpret(cmds, w=10, h=4, show_each_step=True, md=True)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def unrotate_column(grid, c, raw_n):\n", " return rotate_column(grid, c, (-1 * raw_n) % len(grid))\n", "\n", "def unrotate_row(grid, r, raw_n):\n", " return rotate_row(grid, r, (-1 * raw_n) % len(grid[0]))\n" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": true }, "outputs": [], "source": [ "uncommand_dispatch = {'left': left, 'top': top,\n", " 'rotate row': unrotate_row,\n", " 'rotate column': unrotate_column}" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['..................................................',\n", " '..*****..****....***...*...*..*****...***...****..',\n", " '....*....*...*..*...*..**..*....*....*...*..*...*.',\n", " '....*....*..*...*...*..*.*.*....*....*...*..*..*..',\n", " '....*....****...*****..*.*.*....*....*...*..****..',\n", " '....*....*...*..*...*..*..**....*....*...*..*...*.',\n", " '....*....*...*..*...*..*...*....*.....***...*...*.',\n", " '..................................................']" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "trantor_grid = '''\n", "..................................................\n", "..*****..****....***...*...*..*****...***...****..\n", "....*....*...*..*...*..**..*....*....*...*..*...*.\n", "....*....*..*...*...*..*.*.*....*....*...*..*..*..\n", "....*....****...*****..*.*.*....*....*...*..****..\n", "....*....*...*..*...*..*..**....*....*...*..*...*.\n", "....*....*...*..*...*..*...*....*.....***...*...*.\n", "..................................................\n", "'''.split('\\n')[1:-1]\n", "trantor_grid" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def tg():\n", " return '''\n", "..................................................\n", "..*****..****....***...*...*..*****...***...****..\n", "....*....*...*..*...*..**..*....*....*...*..*...*.\n", "....*....*..*...*...*..*.*.*....*....*...*..*..*..\n", "....*....****...*****..*.*.*....*....*...*..****..\n", "....*....*...*..*...*..*..**....*....*...*..*...*.\n", "....*....*...*..*...*..*...*....*.....***...*...*.\n", "..................................................\n", "'''.split('\\n')[1:-1]" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "....................................................................................................\n", "....................................................................................................\n", "....................................................................................................\n", "....................................................................................................\n", "....................................................................................................\n", "....................................................................................................\n", "....................................................................................................\n", "....................................................................................................\n" ] } ], "source": [ "print_grid(new_grid(100, 8))" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def jantar_mantar():\n", " return '''\n", "..*****.............................................................................................\n", ".....*..............................................................................................\n", ".....*..............................................................................................\n", ".....*..............................................................................................\n", ".....*..............................................................................................\n", ".....*..............................................................................................\n", ".*...*..............................................................................................\n", "..***...............................................................................................\n", "'''.split('\\n')[1:-1]" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def jantar_mantar():\n", " return '''\n", "...****..............*...................*.....*..............*.................\n", "......*..............*...................***..**..............*.................\n", "......*.*****.*****.****.*****..****.....*.*.***.*****.*****.****.*****..****...\n", "......*.....*.*...*..*.......*..*........*..**.*.....*.*...*..*.......*..*......\n", "......*.*****.*...*..*...*****..*........*..*..*.*****.*...*..*...*****..*......\n", "......*.*...*.*...*..*...*...*..*........*.....*.*...*.*...*..*...*...*..*......\n", "...*..*.*..**.*...*..**..*..**..*........*.....*.*..**.*...*..**..*..**..*......\n", "....**...**.*.*...*...**..**.*..*........*.....*..**.*.*...*...**..**.*..*......\n", "'''.split('\\n')[1:-1]" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "left 3 7\n", "..................................................\n", "..*****..****....***...*...*..*****...***...****..\n", "*...*....*...*..*...*..**..*....*....*...*..*...*.\n", "*...*....*..*...*...*..*.*.*....*....*...*..*..*..\n", "*...*....****...*****..*.*.*....*....*...*..****..\n", "*...*....*...*..*...*..*..**....*....*...*..*...*.\n", "*...*....*...*..*...*..*...*....*.....***...*...*.\n", "..................................................\n", "\n", "rotate column 1 1\n", "..................................................\n", "*.*****..****....***...*...*..*****...***...****..\n", "*...*....*...*..*...*..**..*....*....*...*..*...*.\n", "*...*....*..*...*...*..*.*.*....*....*...*..*..*..\n", "*...*....****...*****..*.*.*....*....*...*..****..\n", "*...*....*...*..*...*..*..**....*....*...*..*...*.\n", "....*....*...*..*...*..*...*....*.....***...*...*.\n", "..................................................\n", "\n", "left 3 7\n", "..................................................\n", "*.*****..****....***...*...*..*****...***...****..\n", "....*....*...*..*...*..**..*....*....*...*..*...*.\n", "....*....*..*...*...*..*.*.*....*....*...*..*..*..\n", "....*....****...*****..*.*.*....*....*...*..****..\n", "....*....*...*..*...*..*..**....*....*...*..*...*.\n", "*...*....*...*..*...*..*...*....*.....***...*...*.\n", "..................................................\n", "\n", "rotate column 3 1\n", "..*...............................................\n", "*..****..****....***...*...*..*****...***...****..\n", "....*....*...*..*...*..**..*....*....*...*..*...*.\n", "....*....*..*...*...*..*.*.*....*....*...*..*..*..\n", "....*....****...*****..*.*.*....*....*...*..****..\n", "....*....*...*..*...*..*..**....*....*...*..*...*.\n", "*...*....*...*..*...*..*...*....*.....***...*...*.\n", "..................................................\n", "\n", "Final\n", "..*...............................................\n", "*..****..****....***...*...*..*****...***...****..\n", "....*....*...*..*...*..**..*....*....*...*..*...*.\n", "....*....*..*...*...*..*.*.*....*....*...*..*..*..\n", "....*....****...*****..*.*.*....*....*...*..****..\n", "....*....*...*..*...*..*..**....*....*...*..*...*.\n", "*...*....*...*..*...*..*...*....*.....***...*...*.\n", "..................................................\n" ] }, { "data": { "text/plain": [ "['..*...............................................',\n", " '*..****..****....***...*...*..*****...***...****..',\n", " '....*....*...*..*...*..**..*....*....*...*..*...*.',\n", " '....*....*..*...*...*..*.*.*....*....*...*..*..*..',\n", " '....*....****...*****..*.*.*....*....*...*..****..',\n", " '....*....*...*..*...*..*..**....*....*...*..*...*.',\n", " '*...*....*...*..*...*..*...*....*.....***...*...*.',\n", " '..................................................']" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "trantor_grid = '''\n", "..................................................\n", "..*****..****....***...*...*..*****...***...****..\n", "....*....*...*..*...*..**..*....*....*...*..*...*.\n", "....*....*..*...*...*..*.*.*....*....*...*..*..*..\n", "....*....****...*****..*.*.*....*....*...*..****..\n", "....*....*...*..*...*..*..**....*....*...*..*...*.\n", "....*....*...*..*...*..*...*....*.....***...*...*.\n", "..................................................\n", "'''.split('\\n')[1:-1]\n", "\n", "cmds = '''\n", "rotate column 3 1\n", "left 3 7\n", "rotate column 1 1\n", "left 3 7\n", "'''.split('\\n')[1:-1]\n", "interpret(cmds, trantor_grid, show_each_step=True, uninterpret=True)" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def transpose(grid):\n", " return list(zip(*grid))" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "[('.', '*', '.', '.', '.', '.', '*', '.'),\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", " ('.', '*', '.', '.', '.', '.', '*', '.'),\n", " ('.', '.', '*', '*', '*', '*', '.', '.'),\n", " ('.', '.', '.', '.', '.', '.', '.', '.'),\n", " ('.', '.', '.', '.', '.', '.', '.', '.'),\n", " ('.', '*', '*', '*', '*', '*', '*', '.'),\n", " ('.', '*', '.', '.', '*', '.', '.', '.'),\n", " ('.', '*', '.', '.', '*', '.', '.', '.'),\n", " ('.', '*', '.', '*', '*', '.', '.', '.'),\n", " ('.', '.', '*', '.', '.', '*', '*', '.'),\n", " ('.', '.', '.', '.', '.', '.', '.', '.')]" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "transpose(trantor_grid)" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def count_empty_rows(grid, col):\n", " return len(list(itertools.takewhile(lambda c: c == '.', transpose(grid)[col-1])))" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "[1,\n", " 8,\n", " 0,\n", " 1,\n", " 1,\n", " 1,\n", " 1,\n", " 8,\n", " 8,\n", " 1,\n", " 1,\n", " 1,\n", " 1,\n", " 2,\n", " 8,\n", " 8,\n", " 2,\n", " 1,\n", " 1,\n", " 1,\n", " 2,\n", " 8,\n", " 8,\n", " 1,\n", " 2,\n", " 3,\n", " 5,\n", " 1,\n", " 8,\n", " 8,\n", " 1,\n", " 1,\n", " 1,\n", " 1,\n", " 1,\n", " 8,\n", " 8,\n", " 2,\n", " 1,\n", " 1,\n", " 1,\n", " 2,\n", " 8,\n", " 8,\n", " 1,\n", " 1,\n", " 1,\n", " 1,\n", " 2,\n", " 8]" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[count_empty_rows(trantor_grid, i) for i in range(1, WIDTH+1)]" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def lift_cols(grid, randomise=False):\n", " commands = []\n", " h = len(grid)\n", " for i in range(1, len(grid[0])+1):\n", " n = count_empty_rows(grid, i)\n", " if n != h:\n", " commands.append('rotate column {} {}'.format(i, n))\n", " if randomise:\n", " random.shuffle(commands)\n", " return commands" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "['rotate column 3 1',\n", " 'rotate column 4 1',\n", " 'rotate column 5 1',\n", " 'rotate column 6 1',\n", " 'rotate column 7 1',\n", " 'rotate column 10 1',\n", " 'rotate column 11 1',\n", " 'rotate column 12 1',\n", " 'rotate column 13 1',\n", " 'rotate column 14 2',\n", " 'rotate column 17 2',\n", " 'rotate column 18 1',\n", " 'rotate column 19 1',\n", " 'rotate column 20 1',\n", " 'rotate column 21 2',\n", " 'rotate column 24 1',\n", " 'rotate column 25 2',\n", " 'rotate column 26 3',\n", " 'rotate column 27 5',\n", " 'rotate column 28 1',\n", " 'rotate column 31 1',\n", " 'rotate column 32 1',\n", " 'rotate column 33 1',\n", " 'rotate column 34 1',\n", " 'rotate column 35 1',\n", " 'rotate column 38 2',\n", " 'rotate column 39 1',\n", " 'rotate column 40 1',\n", " 'rotate column 41 1',\n", " 'rotate column 42 2',\n", " 'rotate column 45 1',\n", " 'rotate column 46 1',\n", " 'rotate column 47 1',\n", " 'rotate column 48 1',\n", " 'rotate column 49 2']" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "lift_cols(tg())" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "['rotate column 24 1',\n", " 'rotate column 41 1',\n", " 'rotate column 10 1',\n", " 'rotate column 18 1',\n", " 'rotate column 39 1',\n", " 'rotate column 3 1',\n", " 'rotate column 6 1',\n", " 'rotate column 14 2',\n", " 'rotate column 42 2',\n", " 'rotate column 32 1',\n", " 'rotate column 20 1',\n", " 'rotate column 38 2',\n", " 'rotate column 34 1',\n", " 'rotate column 31 1',\n", " 'rotate column 35 1',\n", " 'rotate column 28 1',\n", " 'rotate column 45 1',\n", " 'rotate column 13 1',\n", " 'rotate column 40 1',\n", " 'rotate column 5 1',\n", " 'rotate column 4 1',\n", " 'rotate column 12 1',\n", " 'rotate column 47 1',\n", " 'rotate column 25 2',\n", " 'rotate column 7 1',\n", " 'rotate column 49 2',\n", " 'rotate column 46 1',\n", " 'rotate column 26 3',\n", " 'rotate column 27 5',\n", " 'rotate column 19 1',\n", " 'rotate column 11 1',\n", " 'rotate column 17 2',\n", " 'rotate column 48 1',\n", " 'rotate column 33 1',\n", " 'rotate column 21 2']" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "lift_cols(tg(), randomise=True)" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def count_empty_cols(grid, row):\n", " return len(list(itertools.takewhile(lambda r: r == '.', grid[row-1])))" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[2, 0, 4, 4, 4, 4, 0, 50]" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[count_empty_cols(trantor_grid, i) for i in range(1, HEIGHT+1)]" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def slide_rows(grid, randomise=False):\n", " commands = []\n", " w = len(grid[0])\n", " for i in range(1, len(grid)+1):\n", " n = count_empty_cols(grid, i)\n", " if n != w:\n", " commands.append('rotate row {} {}'.format(i, n))\n", " if randomise:\n", " random.shuffle(commands)\n", " return commands" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def untop(grid, randomise=False):\n", " groups = [(k, len(list(g))) for k, g in itertools.groupby(grid[0])]\n", " commands = []\n", " col = 1\n", " for c, l in groups:\n", " if c == '*':\n", " commands.append('top {} {}'.format(col, col + l - 1))\n", " col += l\n", " if randomise:\n", " random.shuffle(commands)\n", " return commands" ] }, { "cell_type": "code", "execution_count": 32, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def unleft(grid, randomise=False):\n", " groups = [(k, len(list(g))) for k, g in itertools.groupby(transpose(grid)[0])]\n", " commands = []\n", " row = 1\n", " for c, l in groups:\n", " if c == '*':\n", " commands.append('left {} {}'.format(row, row + l - 1))\n", " row += l\n", " if randomise:\n", " random.shuffle(commands)\n", " return commands" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['***********.******.*****.*..***********.******....',\n", " '*....*...*..*...*..*...*....*....*...*..*...*.....',\n", " '*....*..*...*...*..*.*.*....*....*...*..*..*......',\n", " '*....*.**...*..**..*.*.*....*....*...*..*.**......',\n", " '*....*...*..*...*..*...*....*........*..*...*.....',\n", " '*........*......*...........*.......*.......*.....',\n", " '..................................................',\n", " '..................................................']" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "trantor_grid = tg() \n", "\n", "cmds = []\n", "\n", "c = slide_rows(trantor_grid)\n", "cmds = c + cmds\n", "\n", "interpret(c, trantor_grid, uninterpret=True)\n", "\n", "c = lift_cols(trantor_grid)\n", "cmds = c + cmds\n", "\n", "interpret(c, trantor_grid, uninterpret=True)" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['top 1 11', 'top 13 18', 'top 20 24', 'top 26 26', 'top 29 39', 'top 41 46']" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "g = interpret(cmds, tg(), uninterpret=True)\n", "untop(g)" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "..................................................\n", ".....*...*..*...*..*...*....*....*...*..*...*.....\n", ".....*..*...*...*..*.*.*....*....*...*..*..*......\n", ".....*.**...*..**..*.*.*....*....*...*..*.**......\n", ".....*...*..*...*..*...*....*........*..*...*.....\n", ".........*......*...........*.......*.......*.....\n", "..................................................\n", "..................................................\n" ] } ], "source": [ "g = tg() \n", "\n", "cmds = []\n", "\n", "c = slide_rows(g, randomise=True)\n", "interpret(c, g, uninterpret=True)\n", "cmds = c + cmds\n", "\n", "c = lift_cols(g, randomise=True)\n", "interpret(c, g, uninterpret=True)\n", "cmds = c + cmds\n", "\n", "c = untop(g, randomise=True)\n", "interpret(c, g, uninterpret=True)\n", "cmds = c + cmds\n", "\n", "c = unleft(g, randomise=True)\n", "interpret(c, g, uninterpret=True)\n", "cmds = c + cmds\n", "\n", "print_grid(g)" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "..................................................\n", "..................................................\n", "..................................................\n", "..................................................\n", "..................................................\n", "..................................................\n", "..................................................\n", "..................................................\n" ] }, { "data": { "text/plain": [ "139" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "g = tg() \n", "cmds = []\n", "\n", "while '*' in ''.join(g):\n", " if random.choice([True, False]):\n", " c = slide_rows(g, randomise=True)\n", " interpret(c, g, uninterpret=True)\n", " cmds = c + cmds\n", " \n", " c = unleft(g, randomise=True)\n", " interpret(c, g, uninterpret=True)\n", " cmds = c + cmds\n", " \n", " else:\n", " c = lift_cols(g, randomise=True)\n", " interpret(c, g, uninterpret=True)\n", " cmds = c + cmds\n", " \n", " c = untop(g, randomise=True)\n", " interpret(c, g, uninterpret=True)\n", " cmds = c + cmds\n", " \n", "print_grid(g)\n", "len(cmds)" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['..................................................',\n", " '..................................................',\n", " '..................................................',\n", " '..................................................',\n", " '..................................................',\n", " '..................................................',\n", " '..................................................',\n", " '..................................................']" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "g = tg()\n", "interpret(cmds, g, uninterpret=True)" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['..................................................',\n", " '..*****..****....***...*...*..*****...***...****..',\n", " '....*....*...*..*...*..**..*....*....*...*..*...*.',\n", " '....*....*..*...*...*..*.*.*....*....*...*..*..*..',\n", " '....*....****...*****..*.*.*....*....*...*..****..',\n", " '....*....*...*..*...*..*..**....*....*...*..*...*.',\n", " '....*....*...*..*...*..*...*....*.....***...*...*.',\n", " '..................................................']" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "interpret(cmds)" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['top 5 5',\n", " 'top 8 8',\n", " 'top 29 29',\n", " 'top 12 12',\n", " 'rotate column 29 1',\n", " 'rotate column 8 1',\n", " 'rotate column 12 1',\n", " 'rotate column 5 1',\n", " 'top 12 12',\n", " 'top 22 22',\n", " 'top 17 17',\n", " 'top 29 29',\n", " 'top 5 5',\n", " 'top 26 26',\n", " 'top 8 8',\n", " 'rotate column 5 1',\n", " 'rotate column 26 1',\n", " 'rotate column 12 1',\n", " 'rotate column 29 1',\n", " 'rotate column 8 1',\n", " 'rotate column 22 1',\n", " 'rotate column 17 1',\n", " 'top 21 22',\n", " 'top 29 30',\n", " 'top 5 5',\n", " 'top 2 2',\n", " 'top 33 33',\n", " 'top 14 14',\n", " 'top 16 17',\n", " 'top 37 37',\n", " 'top 12 12',\n", " 'top 26 26',\n", " 'top 8 9',\n", " 'rotate column 30 1',\n", " 'rotate column 5 1',\n", " 'rotate column 22 2',\n", " 'rotate column 33 1',\n", " 'rotate column 12 1',\n", " 'rotate column 21 1',\n", " 'rotate column 16 1',\n", " 'rotate column 2 1',\n", " 'rotate column 14 1',\n", " 'rotate column 9 1',\n", " 'rotate column 37 1',\n", " 'rotate column 26 1',\n", " 'rotate column 8 2',\n", " 'rotate column 17 2',\n", " 'rotate column 29 2',\n", " 'left 2 5',\n", " 'rotate row 2 3',\n", " 'rotate row 4 7',\n", " 'rotate row 5 7',\n", " 'rotate row 3 7',\n", " 'top 19 19',\n", " 'top 29 33',\n", " 'top 12 12',\n", " 'top 24 24',\n", " 'top 8 10',\n", " 'top 15 17',\n", " 'top 2 5',\n", " 'top 36 40',\n", " 'rotate column 9 3',\n", " 'rotate column 30 5',\n", " 'rotate column 37 3',\n", " 'rotate column 8 1',\n", " 'rotate column 4 2',\n", " 'rotate column 3 3',\n", " 'rotate column 19 1',\n", " 'rotate column 32 5',\n", " 'rotate column 40 3',\n", " 'rotate column 2 3',\n", " 'rotate column 29 1',\n", " 'rotate column 36 1',\n", " 'rotate column 24 1',\n", " 'rotate column 5 3',\n", " 'rotate column 31 5',\n", " 'rotate column 39 1',\n", " 'rotate column 15 1',\n", " 'rotate column 17 2',\n", " 'rotate column 38 3',\n", " 'rotate column 33 1',\n", " 'rotate column 12 1',\n", " 'rotate column 16 1',\n", " 'rotate column 10 3',\n", " 'top 15 19',\n", " 'top 24 25',\n", " 'top 7 12',\n", " 'top 21 21',\n", " 'top 36 40',\n", " 'top 2 5',\n", " 'top 28 33',\n", " 'top 42 45',\n", " 'rotate column 33 2',\n", " 'rotate column 3 1',\n", " 'rotate column 28 1',\n", " 'rotate column 24 2',\n", " 'rotate column 12 2',\n", " 'rotate column 36 1',\n", " 'rotate column 11 4',\n", " 'rotate column 10 1',\n", " 'rotate column 31 1',\n", " 'rotate column 5 2',\n", " 'rotate column 39 3',\n", " 'rotate column 32 1',\n", " 'rotate column 43 1',\n", " 'rotate column 18 5',\n", " 'rotate column 16 1',\n", " 'rotate column 45 1',\n", " 'rotate column 9 1',\n", " 'rotate column 40 2',\n", " 'rotate column 42 1',\n", " 'rotate column 4 1',\n", " 'rotate column 2 1',\n", " 'rotate column 44 1',\n", " 'rotate column 30 1',\n", " 'rotate column 19 2',\n", " 'rotate column 7 1',\n", " 'rotate column 38 1',\n", " 'rotate column 25 1',\n", " 'rotate column 21 1',\n", " 'rotate column 37 1',\n", " 'rotate column 8 1',\n", " 'rotate column 15 1',\n", " 'rotate column 17 1',\n", " 'rotate column 29 1',\n", " 'left 2 7',\n", " 'rotate row 7 5',\n", " 'rotate row 6 5',\n", " 'rotate row 5 5',\n", " 'rotate row 3 5',\n", " 'rotate row 4 5',\n", " 'rotate row 2 1',\n", " 'left 2 7',\n", " 'rotate row 2 2',\n", " 'rotate row 5 4',\n", " 'rotate row 7 4',\n", " 'rotate row 6 4',\n", " 'rotate row 3 4',\n", " 'rotate row 4 4']" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cmds" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Final\n", "..................................................\n", "..*****..****....***...*...*..*****...***...****..\n", "....*....*...*..*...*..**..*....*....*...*..*...*.\n", "....*....*..*...*...*..*.*.*....*....*...*..*..*..\n", "....*....****...*****..*.*.*....*....*...*..****..\n", "....*....*...*..*...*..*..**....*....*...*..*...*.\n", "....*....*...*..*...*..*...*....*.....***...*...*.\n", "..................................................\n" ] }, { "data": { "text/plain": [ "['..................................................',\n", " '..*****..****....***...*...*..*****...***...****..',\n", " '....*....*...*..*...*..**..*....*....*...*..*...*.',\n", " '....*....*..*...*...*..*.*.*....*....*...*..*..*..',\n", " '....*....****...*****..*.*.*....*....*...*..****..',\n", " '....*....*...*..*...*..*..**....*....*...*..*...*.',\n", " '....*....*...*..*...*..*...*....*.....***...*...*.',\n", " '..................................................']" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "g = new_grid()\n", "interpret(cmds, g, show_each_step=True, overprint=True)" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Final\n", "..................................................\n", "..................................................\n", "..................................................\n", "..................................................\n", "..................................................\n", "..................................................\n", "..................................................\n", "..................................................\n" ] }, { "data": { "text/plain": [ "['..................................................',\n", " '..................................................',\n", " '..................................................',\n", " '..................................................',\n", " '..................................................',\n", " '..................................................',\n", " '..................................................',\n", " '..................................................']" ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "g = tg()\n", "interpret(cmds, g, show_each_step=True, overprint=True, uninterpret=True)" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "98" ] }, "execution_count": 42, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sum(1 for c in ''.join(tg()) if c == '*')" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2163" ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "open('05-pixels.txt', 'w').write('\\n'.join(cmds))" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "................................................................................\n", "................................................................................\n", "................................................................................\n", "................................................................................\n", "................................................................................\n", "................................................................................\n", "................................................................................\n", "................................................................................\n" ] }, { "data": { "text/plain": [ "237" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "g = jantar_mantar() \n", "cmds = []\n", "\n", "while '*' in ''.join(g):\n", " if random.choice([True, False]):\n", " c = slide_rows(g, randomise=True)\n", " interpret(c, g, uninterpret=True)\n", " cmds = c + cmds\n", " \n", " c = unleft(g, randomise=True)\n", " interpret(c, g, uninterpret=True)\n", " cmds = c + cmds\n", " \n", " else:\n", " c = lift_cols(g, randomise=True)\n", " interpret(c, g, uninterpret=True)\n", " cmds = c + cmds\n", " \n", " c = untop(g, randomise=True)\n", " interpret(c, g, uninterpret=True)\n", " cmds = c + cmds\n", " \n", "print_grid(g)\n", "len(cmds)" ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Final\n", "...****..............*...................*.....*..............*.................\n", "......*..............*...................***..**..............*.................\n", "......*.*****.*****.****.*****..****.....*.*.***.*****.*****.****.*****..****...\n", "......*.....*.*...*..*.......*..*........*..**.*.....*.*...*..*.......*..*......\n", "......*.*****.*...*..*...*****..*........*..*..*.*****.*...*..*...*****..*......\n", "......*.*...*.*...*..*...*...*..*........*.....*.*...*.*...*..*...*...*..*......\n", "...*..*.*..**.*...*..**..*..**..*........*.....*.*..**.*...*..**..*..**..*......\n", "....**...**.*.*...*...**..**.*..*........*.....*..**.*.*...*...**..**.*..*......\n" ] }, { "data": { "text/plain": [ "['...****..............*...................*.....*..............*.................',\n", " '......*..............*...................***..**..............*.................',\n", " '......*.*****.*****.****.*****..****.....*.*.***.*****.*****.****.*****..****...',\n", " '......*.....*.*...*..*.......*..*........*..**.*.....*.*...*..*.......*..*......',\n", " '......*.*****.*...*..*...*****..*........*..*..*.*****.*...*..*...*****..*......',\n", " '......*.*...*.*...*..*...*...*..*........*.....*.*...*.*...*..*...*...*..*......',\n", " '...*..*.*..**.*...*..**..*..**..*........*.....*.*..**.*...*..**..*..**..*......',\n", " '....**...**.*.*...*...**..**.*..*........*.....*..**.*.*...*...**..**.*..*......']" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "g = new_grid(w=80)\n", "interpret(cmds, g, show_each_step=True, overprint=True)" ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "80" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "len(jantar_mantar()[0])" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3900" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "open('05-pixels.txt', 'w').write('\\n'.join(cmds))" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " **** * * * * \n", " * * *** ** * \n", " * ***** ***** **** ***** **** * * *** ***** ***** **** ***** **** \n", " * * * * * * * * ** * * * * * * * \n", " * ***** * * * ***** * * * * ***** * * * ***** * \n", " * * * * * * * * * * * * * * * * * * * \n", " * * * ** * * ** * ** * * * * ** * * ** * ** * \n", " ** ** * * * ** ** * * * * ** * * * ** ** * * \n" ] } ], "source": [ "print_grid(jantar_mantar(), suppress_dots=True)" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Final\n", " **** * * * * \n", " * * *** ** * \n", " * ***** ***** **** ***** **** * * *** ***** ***** **** ***** **** \n", " * * * * * * * * ** * * * * * * * \n", " * ***** * * * ***** * * * * ***** * * * ***** * \n", " * * * * * * * * * * * * * * * * * * * \n", " * * * ** * * ** * ** * * * * ** * * ** * ** * \n", " ** ** * * * ** ** * * * * ** * * * ** ** * * \n" ] } ], "source": [ "g = new_grid(w=80)\n", "interpret(cmds, g, show_each_step=True, overprint=True, suppress_dots=True);" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "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.5.2+" } }, "nbformat": 4, "nbformat_minor": 2 }