Here is the stream that goes around the edges.
Assuming input (3.3), 2 gives
{(1,1), (2,1), (3,1), (4,1), (5,1), (1,2), (5,2), (1,3), (5,3), (1,4), (5,4), (1,5), (2,5), (3,5), (4,5), (5,5)}
then you can use the following:
def border(p: (Int,Int), r: Int) = { val X1 = p._1 - r val X2 = p._1 + r val Y1 = p._2 - r val Y2 = p._2 + r def stream(currentPoint: (Int,Int)): Stream[(Int,Int)] = { val nextPoint = currentPoint match { case (X1, Y1) => (X1+1, Y1) case (X2, Y2) => (X2-1, Y2) case (X1, Y2) => (X1, Y2-1) case (X2, Y1) => (X2, Y1+1) case (x, Y1) => (x+1, Y1) case (x, Y2) => (x-1, Y2) case (X1, y) => (X1, y-1) case (X2, y) => (X2, y+1) } Stream.cons(nextPoint, if (nextPoint == (X1,Y1)) Stream.empty else stream(nextPoint)) } stream((X1,Y1)) }
Using:
scala> val b = border((3,3),2) b: Stream[(Int, Int)] = Stream((2,1), ?) scala> b.toList res24: List[(Int, Int)] = List((2,1), (3,1), (4,1), (5,1), (5,2), (5,3), (5,4), (5,5), (4,5), (3,5), (2,5), (1,5), (1,4), (1,3), (1,2), (1,1))