You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
<li>Think about how we're going to represent our data in Haskell</li>
154
154
<li>Figure out how to operate on that data in Haskell so that we produce at a solution</li>
155
155
</ul>
156
-
<p>In the RPN calculator section, we first figured out that when calculating an expression by hand, we'd keep a sort of stack in our minds and then go over the expression one item at a time. We decided to use a list of strings to represent our expression. Finally, we used a left fold to walk oevr the list of strings while keeping a stack to produce a solution.</p>
156
+
<p>In the RPN calculator section, we first figured out that when calculating an expression by hand, we'd keep a sort of stack in our minds and then go over the expression one item at a time. We decided to use a list of strings to represent our expression. Finally, we used a left fold to walk over the list of strings while keeping a stack to produce a solution.</p>
157
157
<p>Okay, so how would we figure out the shortest path from Heathrow to London by hand? Well, we can just sort of look at the whole picture and try to guess what the shortest path is and hopefully we'll make a guess that's right. That solution works for very small inputs, but what if we have a road that has 10,000 sections? Yikes! We also won't be able to say for certain that our solution is the optimal one, we can just sort of say that we're pretty sure.</p>
158
158
<p>That's not a good solution then. Here's a simplified picture of our road system:</p>
<divclass="hintbox"><em>Maybe you're asking yourself</em>: but what about getting to <i>A2</i> by first crossing over at <i>B1</i> and then going on forward? Well, we already covered crossing from <i>B1</i> to <i>A1</i> when we were looking for the best way to <i>A1</i>, so we don't have to take that into account in the next step as well.</div>
164
164
<p>Now that we have the best path to <i>A2</i> and <i>B2</i>, we can repeat this indefinitely until we reach the end. Once we've gotten the best paths for <i>A4</i> and <i>B4</i>, the one that's cheaper is the optimal path!</p>
165
165
<p>So in essence, for the second section, we just repeat the step we did at first, only we take into account what the previous best paths on A and B. We could say that we also took into account the best paths on A and on B in the first step, only they were both empty paths with a cost of 0.</p>
166
-
<p>Here's a summary. To get the bast path from Heathrow to London, we do this: first we see what the best path to the next crossroads on main road A is. The two options are going directly forward or starting at the opposite road, going forward and then crossing over. We remember the cost and the path. We use the same method to see what the best path to the next crossroads on main road B is and remember that. Then, we see if the path to the next crossroads on A is cheaper if we go from the previous A crossroads or if we go from the previous B crossroads and then cross over. We remember the cheaper path and then we do the same for the crossroads opposite of it. We do this for every section until we reach the end. Once we've reached the end, the cheapest of the two paths that we have is our optimal path!</p>
166
+
<p>Here's a summary. To get the best path from Heathrow to London, we do this: first we see what the best path to the next crossroads on main road A is. The two options are going directly forward or starting at the opposite road, going forward and then crossing over. We remember the cost and the path. We use the same method to see what the best path to the next crossroads on main road B is and remember that. Then, we see if the path to the next crossroads on A is cheaper if we go from the previous A crossroads or if we go from the previous B crossroads and then cross over. We remember the cheaper path and then we do the same for the crossroads opposite of it. We do this for every section until we reach the end. Once we've reached the end, the cheapest of the two paths that we have is our optimal path!</p>
167
167
<p>So in essence, we keep one shortest path on the A road and one shortest path on the B road and when we reach the end, the shorter of those two is our path. We now know how to figure out the shortest path by hand. If you had enough time, paper and pencils, you could figure out the shortest path through a road system with any number of sections.</p>
168
168
<p>Next step! How do we represent this road system with Haskell's data types? One way is to think of the starting points and crossroads as nodes of a graph that point to other crossroads. If we imagine that the starting points actually point to each other with a road that has a length of one, we see that every crossroads (or node) points to the node on the other side and also to the next one on its side. Except for the last nodes, they just point to the other side. </p>
data Section = Section { getA :: Int, getB :: Int, getC :: Int } deriving (Show)
183
183
type RoadSystem = [Section]
184
184
</pre>
185
-
<p>This is pretty much perfect! It's as simple as it goes and I have a feeling it'll work perfectly for implementing our solution. <spanclass="fixed">Section</span> is a simple algebraic data type that holds three integers for the lenghts of its three road parts. We introduce a type synonym as well, saying that <spanclass="fixed">RoadSystem</span> is a list of sections.
185
+
<p>This is pretty much perfect! It's as simple as it goes and I have a feeling it'll work perfectly for implementing our solution. <spanclass="fixed">Section</span> is a simple algebraic data type that holds three integers for the lengths of its three road parts. We introduce a type synonym as well, saying that <spanclass="fixed">RoadSystem</span> is a list of sections.
186
186
<divclass="hintbox">We could also use a triple of <spanclass="fixed">(Int, Int, Int)</span> to represent a road section. Using tuples instead of making your own algebraic data types is good for some small localized stuff, but it's usually better to make a new type for things like this. It gives the type system more information about what's what. We can use <spanclass="fixed">(Int, Int, Int)</span> to represent a road section or a vector in 3D space and we can operate on those two, but that allows us to mix them up. If we use <spanclass="fixed">Section</span> and <spanclass="fixed">Vector</span> data types, then we can't accidentally add a vector to a section of a road system.</div>
187
187
<p>Our road system from Heathrow to London can now be represented like this:</p>
<p>We're going to have to walk over the list with the sections from left to right and keep the optimal path on A and optimal path on B as we go along. We'll accumulate the best path as we walk over the list, left to right. What does that sound like? Ding, ding, ding! That's right, A LEFT FOLD!</p>
202
-
<p>When doing the solution by hand, there was a step that we repeated over and over again. It involed checking the optimal paths on A and B so far and the current section to produce the new optimal paths on A and B. For instance, at the beginning the optimal paths were <spanclass="fixed">[]</span> and <spanclass="fixed">[]</span> for A and B respectively. We examined the section <spanclass="fixed">Section 50 10 30</span> and concluded that the new optimal path to <i>A1</i> is <spanclass="fixed">[(B,10),(C,30)]</span> and the optimal path to <i>B1</i> is <spanclass="fixed">[(B,10)]</span>. If you look at this step as a function, it takes a pair of paths and a section and produces a new pair of paths. The type is <spanclass="fixed">(Path, Path) -> Section -> (Path, Path)</span>. Let's go ahead and implement this function, because it's bound to be useful.</p>
202
+
<p>When doing the solution by hand, there was a step that we repeated over and over again. It involved checking the optimal paths on A and B so far and the current section to produce the new optimal paths on A and B. For instance, at the beginning the optimal paths were <spanclass="fixed">[]</span> and <spanclass="fixed">[]</span> for A and B respectively. We examined the section <spanclass="fixed">Section 50 10 30</span> and concluded that the new optimal path to <i>A1</i> is <spanclass="fixed">[(B,10),(C,30)]</span> and the optimal path to <i>B1</i> is <spanclass="fixed">[(B,10)]</span>. If you look at this step as a function, it takes a pair of paths and a section and produces a new pair of paths. The type is <spanclass="fixed">(Path, Path) -> Section -> (Path, Path)</span>. Let's go ahead and implement this function, because it's bound to be useful.</p>
203
203
<divclass="hintbox"><em>Hint:</em> it will be useful because <spanclass="fixed">(Path, Path) -> Section -> (Path, Path)</span> can be used as the binary function for a left fold, which has to have a type of <spanclass="fixed">a -> b -> a</span></div>
0 commit comments