Add files via upload

This commit is contained in:
Peter Norvig 2017-12-05 23:14:26 -08:00 committed by GitHub
parent 9b67beaee6
commit 32bf3c2298
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -784,7 +784,7 @@
"source": [
"# [Day 5](https://adventofcode.com/2017/day/5): A Maze of Twisty Trampolines, All Alike\n",
"\n",
"Let's first make sure we can read the data okay:"
"Let's first make sure we can read the data/program okay:"
]
},
{
@ -795,7 +795,7 @@
{
"data": {
"text/plain": [
"[0, 2, 0, 0, -2, -2, -1, -4, -5, -6]"
"(0, 2, 0, 0, -2, -2, -1, -4, -5, -6)"
]
},
"execution_count": 18,
@ -804,17 +804,17 @@
}
],
"source": [
"def jumps(): return [int(x) for x in Input(5)]\n",
"program = mapt(int, Input(5))\n",
"\n",
"jumps()[:10]"
"program[:10]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now I'll make a little interpreter, `run`, which takes a list, `M` for memory, as input,\n",
"and maintains a program counter `pc`, and does the incrementing as described in the puzzle,\n",
"Now I'll make a little interpreter, `run`, which takes a program, loads it into memory,\n",
" and executes the instruction, maintaining a program counter, `pc`, and doing the incrementing/branching as described in the puzzle,\n",
"until the program counter is out of range:"
]
},
@ -835,16 +835,17 @@
}
],
"source": [
"def run(M):\n",
" pc = 0\n",
" for steps in count_from(1):\n",
"def run(program):\n",
" memory = list(program)\n",
" pc = steps = 0\n",
" while pc in range(len(memory)):\n",
" steps += 1\n",
" oldpc = pc\n",
" pc += M[pc]\n",
" M[oldpc] += 1\n",
" if pc not in range(len(M)):\n",
" pc += memory[pc]\n",
" memory[oldpc] += 1\n",
" return steps\n",
" \n",
"run(jumps())"
"run(program)"
]
},
{
@ -853,7 +854,7 @@
"source": [
"**Part Two:**\n",
"\n",
"Part Two seems tricky, so I'll include an optional argument, `verbose`, to print out info as we go, to make sure I've got it right on a small example:"
"Part Two seems tricky, so I'll include an optional argument, `verbose`, and check if the printout it produces matches the example in the puzzle description:"
]
},
{
@ -889,14 +890,15 @@
}
],
"source": [
"def run2(M, verbose=False):\n",
" pc = 0\n",
" for steps in count_from(1):\n",
"def run2(program, verbose=False):\n",
" memory = list(program)\n",
" pc = steps = 0\n",
" while pc in range(len(memory)):\n",
" steps += 1\n",
" oldpc = pc\n",
" pc += M[pc]\n",
" M[oldpc] += (-1 if M[oldpc] >= 3 else 1)\n",
" if verbose: print(steps, pc, M)\n",
" if pc not in range(len(M)):\n",
" pc += memory[pc]\n",
" memory[oldpc] += (-1 if memory[oldpc] >= 3 else 1)\n",
" if verbose: print(steps, pc, memory)\n",
" return steps\n",
" \n",
"run2([0, 3, 0, 1, -3], True)"
@ -926,7 +928,179 @@
}
],
"source": [
"run2(jumps())"
"run2(program)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Thanks to [Clement Sreeves](https://github.com/ClementSreeves) for the suggestion of making a distinction between the `program` and the `memory`. In my first version, `run` would mutate the argument, which was OK for a short exercise, but not best practice for a reliable API."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# [Day 6](https://adventofcode.com/2017/day/6): Memory Reallocation "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"I had to read the puzzle description carefully, but then it is pretty clear what to do. I'll keep a set of previously seen configurations, which will all be tuples. But in the function `spread`, I want to mutate the configuration of banks, so I will convert to a list at the start, then convert back to a tuple at the end."
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [],
"source": [
"banks = vector('4\t10\t4\t1\t8\t4\t9\t14\t5\t1\t14\t15\t0\t15\t3\t5')\n",
"\n",
"def realloc(banks):\n",
" \"How many cycles until we reach a configuration we've seen before?\"\n",
" seen = {banks}\n",
" for cycles in count_from(1):\n",
" banks = spread(banks)\n",
" if banks in seen:\n",
" return cycles\n",
" seen.add(banks)\n",
" \n",
"def spread(banks):\n",
" \"Find the area with the most blocks, and spread them evenly to following areas.\"\n",
" banks = list(banks)\n",
" maxi = max(range(len(banks)), key=lambda i: banks[i])\n",
" blocks = banks[maxi]\n",
" banks[maxi] = 0\n",
" for i in range(maxi + 1, maxi + 1 + blocks):\n",
" banks[i % len(banks)] += 1\n",
" return tuple(banks)"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(2, 4, 1, 2)"
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"spread((0, 2, 7, 0))"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"5"
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"realloc((0, 2, 7, 0))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"These tests look good; let's solve the problem:"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"12841"
]
},
"execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"realloc(banks)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Part Two:** Here I will just replace the `set` of `seen` banks with a `dict` of `{bank: cycle_number}`; everything else is the same, and the final result is the current cycle number minus the cycle number of the previously-seen tuple of banks."
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"4"
]
},
"execution_count": 26,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def realloc2(banks):\n",
" \"When we hit a cycle, what is the length of the cycle?\"\n",
" seen = {banks: 0}\n",
" for cycles in count_from(1):\n",
" banks = spread(banks)\n",
" if banks in seen:\n",
" return cycles - seen[banks]\n",
" seen[banks] = cycles\n",
"\n",
"realloc2((0, 2, 7, 0))"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"8038"
]
},
"execution_count": 27,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"realloc2(banks)"
]
}
],