"cells": [
{
"cell_type": "code",
- "execution_count": 1,
+ "execution_count": 20,
"metadata": {},
"outputs": [],
"source": [
"cell_type": "markdown",
"metadata": {},
"source": [
- "# Part 1"
+ "# Part 1\n",
+ "`startswith()` isn't useful that often, but it makes for easily readable code when it is."
]
},
{
"cell_type": "code",
- "execution_count": 3,
+ "execution_count": 31,
"metadata": {},
"outputs": [
{
"1136"
]
},
- "execution_count": 3,
+ "execution_count": 31,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "non_comments = 0\n",
+ "for i in instructions:\n",
+ " if not i.startswith('#'):\n",
+ " non_comments += 1\n",
+ "non_comments"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "This sort if simple walking along a list is sometimes easier with a list comprehension. \n",
+ "\n",
+ "In this case, I transform each element into the number 1, but only if it's not a comment. Then I sum all the 1s, which is the number of non-comment lines."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 21,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "1136"
+ ]
+ },
+ "execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
},
{
"cell_type": "code",
- "execution_count": 4,
+ "execution_count": 22,
"metadata": {},
"outputs": [
{
"1136"
]
},
- "execution_count": 4,
+ "execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
"sum(1 for i in open('../../data/01-mowmaster.txt') if not i.startswith('#'))"
]
},
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "How many comments and total lines?"
+ ]
+ },
{
"cell_type": "code",
- "execution_count": 5,
+ "execution_count": 23,
"metadata": {},
"outputs": [
{
"395"
]
},
- "execution_count": 5,
+ "execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
},
{
"cell_type": "code",
- "execution_count": 6,
+ "execution_count": 24,
"metadata": {},
"outputs": [
{
"1531"
]
},
- "execution_count": 6,
+ "execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
"cell_type": "markdown",
"metadata": {},
"source": [
- "# Part 2"
+ "# Part 2\n",
+ "\n",
+ "I have the `mower` as an \"object\" storing its state. (In this case, the mower is a `dict` and the state is just its location and direction.) As each instruction is executed, the mower is updated."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "An initial mower. I adopt the Scratch convention that a heading of 0 degrees is up, increasing clockwise; so right is 90 degrees."
]
},
{
"cell_type": "code",
- "execution_count": 7,
+ "execution_count": 25,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def init_mowmaster():\n",
+ " return {'x': 0, 'y': 0, 'd': 90}"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Execute the instructions. Do them one at a time, updating the mowmaster for each one.\n",
+ "\n",
+ "(Can you see an accumulator pattern again?)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 26,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def execute(mowmaster, instructions, debug=False):\n",
+ " for instruction in instructions:\n",
+ " mowmaster = execute_one(mowmaster, instruction, debug=debug)\n",
+ " return mowmaster"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Execute one instruction. If it starts `C` or `A`, turn; if it starts `F`, move forward. Ignore all other instructions."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 27,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def execute_one(mowmaster, instruction, debug=False):\n",
+ " if instruction == 'C':\n",
+ " mowmaster['d'] = (mowmaster['d'] + 90) % 360 # Use the modulus operator to keep the angle in the range 0--360\n",
+ " elif instruction == 'A':\n",
+ " mowmaster['d'] = (mowmaster['d'] - 90) % 360\n",
+ " elif instruction.startswith('F'):\n",
+ " mowmaster = move(mowmaster, int(instruction[1:]))\n",
+ " if debug: \n",
+ " print(instruction, mowmaster)\n",
+ " return mowmaster"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The movement. Update `x` or `y` depending on the direction."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 28,
"metadata": {},
"outputs": [],
"source": [
]
},
{
- "cell_type": "code",
- "execution_count": 12,
+ "cell_type": "markdown",
"metadata": {},
- "outputs": [],
"source": [
- "def init_mowmaster():\n",
- " return {'x': 0, 'y': 0, 'd': 90}"
+ "Finally, how far the Mowmaster has moved."
]
},
{
"cell_type": "code",
- "execution_count": 16,
+ "execution_count": 29,
"metadata": {},
"outputs": [],
"source": [
]
},
{
- "cell_type": "code",
- "execution_count": 13,
+ "cell_type": "markdown",
"metadata": {},
- "outputs": [],
"source": [
- "def execute(mowmaster, instructions, debug=False):\n",
- " for instruction in instructions:\n",
- " if instruction == 'C':\n",
- " mowmaster['d'] = (mowmaster['d'] + 90) % 360\n",
- " elif instruction == 'A':\n",
- " mowmaster['d'] = (mowmaster['d'] - 90) % 360\n",
- " elif instruction.startswith('F'):\n",
- " mowmaster = move(mowmaster, int(instruction[1:]))\n",
- " if debug: \n",
- " print(instruction, mowmaster)\n",
- " return mowmaster"
+ "Now we have all the parts, put them together into the solution."
]
},
{
"cell_type": "code",
- "execution_count": 18,
+ "execution_count": 30,
"metadata": {},
"outputs": [
{
"337"
]
},
- "execution_count": 18,
+ "execution_count": 30,
"metadata": {},
"output_type": "execute_result"
}