{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Advent of Code 2017\n", "\n", "## December 6th\n", "\n", "\n", " [0 2 7 0] dup max\n" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "from notebook_preamble import D, J, V, define" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0 2 7 0] 7\n" ] } ], "source": [ "J('[0 2 7 0] dup max')" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "from joy.library import SimpleFunctionWrapper\n", "from joy.utils.stack import list_to_stack\n", "\n", "\n", "@SimpleFunctionWrapper\n", "def index_of(stack):\n", " '''Given a sequence and a item, return the index of the item, or -1 if not found.\n", "\n", " E.g.:\n", "\n", " [a b c] a index_of\n", " ------------------------\n", " 0\n", "\n", " [a b c] d index_of\n", " ------------------------\n", " -1\n", "\n", " '''\n", " item, (sequence, stack) = stack\n", " i = 0\n", " while sequence:\n", " term, sequence = sequence\n", " if term == item:\n", " break\n", " i += 1\n", " else:\n", " i = -1\n", " return i, stack\n", "\n", "\n", "D['index_of'] = index_of" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2\n" ] } ], "source": [ "J('[0 2 7 0] 7 index_of')" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "-1\n" ] } ], "source": [ "J('[0 2 7 0] 23 index_of')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Starting at `index` distribute `count` \"blocks\" to the \"banks\" in the sequence.\n", "\n", " [...] count index distribute\n", " ----------------------------\n", " [...]\n", "\n", "This seems like it would be a PITA to implement in Joypy..." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "from joy.utils.stack import iter_stack, list_to_stack\n", "\n", "\n", "@SimpleFunctionWrapper\n", "def distribute(stack):\n", " '''Starting at index+1 distribute count \"blocks\" to the \"banks\" in the sequence.\n", "\n", " [...] count index distribute\n", " ----------------------------\n", " [...]\n", "\n", " '''\n", " index, (count, (sequence, stack)) = stack\n", " assert count >= 0\n", " cheat = list(iter_stack(sequence))\n", " n = len(cheat)\n", " assert index < n\n", " cheat[index] = 0\n", " while count:\n", " index += 1\n", " index %= n\n", " cheat[index] += 1\n", " count -= 1\n", " return list_to_stack(cheat), stack\n", "\n", "\n", "D['distribute'] = distribute" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[2 4 1 2]\n" ] } ], "source": [ "J('[0 2 7 0] dup max [index_of] nullary distribute')" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[3 1 2 3]\n" ] } ], "source": [ "J('[2 4 1 2] dup max [index_of] nullary distribute')" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0 2 3 4]\n" ] } ], "source": [ "J('[3 1 2 3] dup max [index_of] nullary distribute')" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1 3 4 1]\n" ] } ], "source": [ "J('[0 2 3 4] dup max [index_of] nullary distribute')" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[2 4 1 2]\n" ] } ], "source": [ "J('[1 3 4 1] dup max [index_of] nullary distribute')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Recalling \"Generator Programs\"\n", "\n", " [a F] x\n", " [a F] a F \n", " \n", " [a F] a swap [C] dip rest cons\n", " a [a F] [C] dip rest cons\n", " a C [a F] rest cons\n", " a C [F] cons\n", "\n", " w/ C == dup G\n", "\n", " a dup G [F] cons\n", " a a G [F] cons\n", "\n", " w/ G == dup max [index_of] nullary distribute" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "define('direco dip rest cons')" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "define('G [direco] cons [swap] swoncat cons')" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "define('make_distributor [dup dup max [index_of] nullary distribute] G')" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0 2 7 0] [2 4 1 2] [3 1 2 3] [0 2 3 4] [1 3 4 1] [2 4 1 2]\n" ] } ], "source": [ "J('[0 2 7 0] make_distributor 6 [x] times pop')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### A function to drive a generator and count how many states before a repeat.\n", "First draft:\n", "\n", " [] [GEN] x [pop index_of 0 >=] [pop size --] [[swons] dip x] tailrec\n", "\n", "(?)\n", "\n", " [] [GEN] x [pop index_of 0 >=] [pop size --] [[swons] dip x] tailrec\n", " [] [...] [GEN] [pop index_of 0 >=] [pop size --] [[swons] dip x] tailrec\n", " [] [...] [GEN] pop index_of 0 >=\n", " [] [...] index_of 0 >=\n", " -1 0 >=\n", " False\n", "\n", "Base case\n", "\n", " [] [...] [GEN] [pop index_of 0 >=] [pop size --] [[swons] dip x] tailrec\n", " [] [...] [GEN] pop size --\n", " [] [...] size --\n", " [] [...] size --\n", "\n", "A mistake, `popop` and no need for `--`\n", "\n", " [] [...] [GEN] popop size\n", " [] size\n", " n\n", "\n", "Recursive case\n", "\n", " [] [...] [GEN] [pop index_of 0 >=] [popop size] [[swons] dip x] tailrec\n", " [] [...] [GEN] [swons] dip x F\n", " [] [...] swons [GEN] x F\n", " [[...]] [GEN] x F\n", " [[...]] [...] [GEN] F\n", "\n", " [[...]] [...] [GEN] F\n", "\n", "What have we learned?\n", "\n", " F == [pop index_of 0 >=] [popop size] [[swons] dip x] tailrec" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "define('count_states [] swap x [pop index_of 0 >=] [popop size] [[swons] dip x] tailrec')" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [], "source": [ "define('AoC2017.6 make_distributor count_states')" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "5\n" ] } ], "source": [ "J('[0 2 7 0] AoC2017.6')" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "4\n" ] } ], "source": [ "J('[1 1 1] AoC2017.6')" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "15\n" ] } ], "source": [ "J('[8 0 0 0 0 0] AoC2017.6')" ] } ], "metadata": { "kernelspec": { "display_name": "Python 2", "language": "python", "name": "python2" }, "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.8.3" } }, "nbformat": 4, "nbformat_minor": 2 }