9 "instructions = [l.strip() for l in open('../../data/01-mowmaster.txt')]"
13 "cell_type": "markdown",
17 "`startswith()` isn't useful that often, but it makes for easily readable code when it is."
22 "execution_count": 31,
31 "execution_count": 31,
33 "output_type": "execute_result"
38 "for i in instructions:\n",
39 " if not i.startswith('#'):\n",
40 " non_comments += 1\n",
45 "cell_type": "markdown",
48 "This sort if simple walking along a list is sometimes easier with a list comprehension. \n",
50 "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."
55 "execution_count": 21,
64 "execution_count": 21,
66 "output_type": "execute_result"
70 "sum(1 for i in instructions if not i.startswith('#'))"
74 "cell_type": "markdown",
82 "execution_count": 22,
91 "execution_count": 22,
93 "output_type": "execute_result"
97 "sum(1 for i in open('../../data/01-mowmaster.txt') if not i.startswith('#'))"
101 "cell_type": "markdown",
104 "How many comments and total lines?"
109 "execution_count": 23,
118 "execution_count": 23,
120 "output_type": "execute_result"
124 "sum(1 for i in instructions if i.startswith('#'))"
129 "execution_count": 24,
138 "execution_count": 24,
140 "output_type": "execute_result"
148 "cell_type": "markdown",
153 "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."
157 "cell_type": "markdown",
160 "An initial mower. I adopt the Scratch convention that a heading of 0 degrees is up, increasing clockwise; so right is 90 degrees."
165 "execution_count": 25,
169 "def init_mowmaster():\n",
170 " return {'x': 0, 'y': 0, 'd': 90}"
174 "cell_type": "markdown",
177 "Execute the instructions. Do them one at a time, updating the mowmaster for each one.\n",
179 "(Can you see an accumulator pattern again?)"
184 "execution_count": 26,
188 "def execute(mowmaster, instructions, debug=False):\n",
189 " for instruction in instructions:\n",
190 " mowmaster = execute_one(mowmaster, instruction, debug=debug)\n",
195 "cell_type": "markdown",
198 "Execute one instruction. If it starts `C` or `A`, turn; if it starts `F`, move forward. Ignore all other instructions."
203 "execution_count": 27,
207 "def execute_one(mowmaster, instruction, debug=False):\n",
208 " if instruction == 'C':\n",
209 " mowmaster['d'] = (mowmaster['d'] + 90) % 360 # Use the modulus operator to keep the angle in the range 0--360\n",
210 " elif instruction == 'A':\n",
211 " mowmaster['d'] = (mowmaster['d'] - 90) % 360\n",
212 " elif instruction.startswith('F'):\n",
213 " mowmaster = move(mowmaster, int(instruction[1:]))\n",
215 " print(instruction, mowmaster)\n",
220 "cell_type": "markdown",
223 "The movement. Update `x` or `y` depending on the direction."
228 "execution_count": 28,
232 "def move(mower, distance):\n",
233 " if mower['d'] == 0:\n",
234 " mower['y'] += distance\n",
235 " elif mower['d'] == 90:\n",
236 " mower['x'] += distance\n",
237 " elif mower['d'] == 180:\n",
238 " mower['y'] -= distance\n",
239 " elif mower['d'] == 270:\n",
240 " mower['x'] -= distance\n",
242 " raise ValueError\n",
247 "cell_type": "markdown",
250 "Finally, how far the Mowmaster has moved."
255 "execution_count": 29,
259 "def mowmaster_distance(mw):\n",
260 " return abs(mw['x']) + abs(mw['y'])"
264 "cell_type": "markdown",
267 "Now we have all the parts, put them together into the solution."
272 "execution_count": 30,
281 "execution_count": 30,
283 "output_type": "execute_result"
287 "mw = init_mowmaster()\n",
288 "execute(mw, instructions)\n",
289 "mowmaster_distance(mw)"
294 "execution_count": null,
302 "display_name": "Python 3",
303 "language": "python",
311 "file_extension": ".py",
312 "mimetype": "text/x-python",
314 "nbconvert_exporter": "python",
315 "pygments_lexer": "ipython3",