To code related to the explanations available here can be found at https://github.com/juliendelplanque/AOC2016
To solve this puzzle, one need to follow a list of instructions describing the path to reach a point on a grid. Once the point is found, one need to compute the length of the shortest path to this point (using Taxicab geometry).
To hold the solution, let's create a AOCSolver1
class which instances will be able to solve this problem by sending #solve
message to them.
Let's create a #rawData
message returning raw data provided in the text file:
AOCSolver1>>#rawInputData
^ 'L2, L5, L5, R5, L2, L4, R1, R1, L4, R2, R1, L1, L4, R1, L4, L4, R5, R3, R1, L1, R1, L5, L1, R5, L4, R2, L5, L3, L3, R3, L3, R4, R4, L2, L5, R1, R2, L2, L1, R3, R4, L193, R3, L5, R45, L1, R4, R79, L5, L5, R5, R1, L4, R3, R3, L4, R185, L5, L3, L1, R5, L2, R1, R3, R2, L3, L4, L2, R2, L3, L2, L2, L3, L5, R3, R4, L5, R1, R2, L2, R4, R3, L4, L3, L1, R3, R2, R1, R1, L3, R4, L5, R2, R1, R3, L3, L2, L2, R2, R1, R2, R3, L3, L3, R4, L4, R4, R4, R4, L3, L1, L2, R5, R2, R2, R2, L4, L3, L4, R4, L5, L4, R2, L4, L4, R4, R1, R5, L2, L4, L5, L3, L2, L4, L4, R3, L3, L4, R1, L2, R3, L2, R1, R2, R5, L4, L2, L1, L3, R2, R3, L2, L1, L5, L2, L1, R4'
Now let's create a method that converts raw data to a more processable form:
AOCSolver1>>#inputData
"Parses input data to get a list of instructions to move on the map."
^ (self rawInputData splitOn: $,)
collect: #trimmed
The #solve
method I would like to write is the following:
AOCSolver1>>#solve
self inputData do: [ :instruction |
instruction first = $L
ifTrue: [
self turnLeft. ].
instruction first = $R
ifTrue: [
self turnRight ].
self position: (self orientation move: instruction allButFirst asInteger from: self position) ].
"This is how you compute the distance between 0@0 and the point reached in taxicab geometry :-)"
^ self position x abs + self position y abs
Obviously, we have orientation
and position
instance variables and their accessors. The position
will be defined as an instance of Point
and the orientation
will be one of the custom object we define after.
Thus, #initialize
method of AOCSolver1
will be:
AOCSolver1>>#initialize
super initialize.
self
orientation: AOCNorth new;
position: 0@0
Let's define the objects representing the orientation. The class hierarchy of these objects is the following:
AOCOrientation
|- AOCEast
|- AOCNorth
|- AOCSouth
|- AOCWest
These objects implement the method #turnLeft
and #turnRight
that return an AOCOrientation
instance depending of the orientation they represent. For example, in AOCEast
, these methods are implemented as:
AOCEast>>#turnLeft
^ AOCNorth new
AOCEast>>#turnRight
^ AOCSouth new
Additionally, those orientation objects implement a #move:from:
message that, from an initial point and a step count, returns the new position on the grid after moving of the number of step in the given direction. For example, in AOCEast
this method is implemented as:
AOCEast>>#move: steps from: position
"Returns the new position when walking of steps in the current orientation."
^ (position x + steps) @ position y
Having those orientation objects, we can now implement the methods #turnLeft
and #turnRight
of AOCSolver1
using the polymorphism property of AOCOrientation
objects:
AOCSolver1>>#turnLeft
self orientation: self orientation turnLeft
AOCSolver1>>#turnRight
self orientation: self orientation turnRight
And that's it, you can now run AOCSolver1 new solve inspect
to get the solution to this puzzle.
Short description of the problem.
Code snippets for your solution and description of this code.