Add files via upload
This commit is contained in:
parent
9b67beaee6
commit
32bf3c2298
@ -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)"
|
||||
]
|
||||
}
|
||||
],
|
||||
|
Loading…
Reference in New Issue
Block a user