Last updated on
Counting paths
- Points
- 40 points
- Topics
- Recursion, State, Specifications
- Files to submit
src/main/scala/paths/CountPaths.scala
In this exercise, your task is to write a function that counts the number of ways to travel from one point to another an infinite integer grid, without encountering obstacles, under the following constraints:
- All coordinates are integers.
- You may only move up (i.e. go from $(x, y)$ to $(x, y+1)$) or to the right (i.e., go from $(x, y)$ to $(x+1, y)$); never down or to the left.
- The starting and ending points never have obstacles.
- You may assume that the number of paths in tests is always $< 2^{31}$.
You are given the following inputs:
- The coordinates of a starting point
src: Coord. - The coordinate of a destination
dst: Coord. - A predicate
hasObstacle: Coord => Boolindicating which coordinates are blocked by obstacles.
The type Coord is shown below for your reference:
case class Coord(x: Int, y: Int)
pathcounting/src/main/scala/paths/CountPaths.scala
Warm up
Use the following examples to check your understanding of the problem:
- Base cases
-
- How many ways are there to travel from
(-2, -2)to(-2, -2)? - How many ways are there to travel from
(3, 4)to(3, 1)? - How many ways are there to travel from
(3, 4)to(0, 4)?
- How many ways are there to travel from
- Recursion
-
If obstacles are laid out such that there are 18 ways to travel from
(0, 0)to(4, 5)and 21 ways to travel from(0, 0)to(5, 4), how many ways are there to travel from(0, 0)to(5, 5)? - Examples
-
- How many ways are there to travel from
(0, 0)to(1, 3)if there are no obstacles? - How many ways are there to travel from
(0, 0)to(1, 3)ifhasObstacleis_ == Coord(1, 0)?
- How many ways are there to travel from
Answers
- Base cases
-
- 1
- 0
- 0
- Recursion
-
18 + 21 = 39
- Examples
-
- 4
- 3
Naive implementation (10 points)
Implement the function countPathsNaive without worrying about efficiency. countPathsNaive should throw an IllegalArgumentException if src or dst has an obstacle.
def countPathsNaive(
src: Coord,
dst: Coord,
hasObstacle: Coord => Boolean
): Int =
require(???)
???
pathcounting/src/main/scala/paths/CountPaths.scala
Optimized implementation (30 points)
Implement the function countPathsFast, making sure that it runs in time at proportional to at most $|\texttt{dst.x} - \texttt{src.x}| \cdot |\texttt{dst.y} - \texttt{src.y}|$:
def countPathsFast(src: Coord, dst: Coord, hasObstacle: Coord => Boolean): Int =
require(???)
???
pathcounting/src/main/scala/paths/CountPaths.scala
The last two tests (related to stack overflows) are hard to pass and worth very few points (2 out of 40). Do not waste time on them! Use testOnly -- *Naive* and testOnly -- *Fast* to run the naive and fast tests without the last two tests.