# Scala algorithm: Read a matrix as a spiral

Published , last updated

## Algorithm goal

For a matrix, read it in a clockwise spiral order. For example, if this is the matrix:

1 | 2 | 3 |

4 | 5 | 6 |

7 | 8 | 9 |

Would be read as:

1 | 2 | 3 | 6 | 9 | 8 | 7 | 4 | 5 |

## Explanation

There are different approaches to this problem, but this approach is the most interesting as it first of all does not mutate the matrix nor perform any heavy transformations of the inputs: by representing the matrix indices in the form of a pair of Ranges, we can simply get the indices and then after getting those indices, extract the respective elements.

The key concept here is that if we take the top part of the matrix, and then rotate it anti-clockwise, that is our next set of indices, and we just keep on going. To do that, in each iteration, the horizontal range becomes the vertical range (without the first line), and vertical range becomes the horizontal range, reversed. (this is Â© from www.scala-algorithms.com)

In essence, the example matrix would be treated like this (where the outline indicates what we are selecting in this iteration):

1 | 2 | 3 |

4 | 5 | 6 |

7 | 8 | 9 |

After the second transformation, it would look like this:

6 | 9 |

5 | 8 |

4 | 7 |

## Scala concepts & Hints

### Drop, Take, dropRight, takeRight

Scala's `drop` and `take` methods typically remove or select `n` items from a collection.

### Lazy List

The 'LazyList' type (previously known as 'Stream' in Scala) is used to describe a potentially infinite list that evaluates only when necessary ('lazily').

### Range

The

`(1 to n)`

syntax produces a "Range" which is a representation of a sequence of numbers.

## Algorithm in Scala

27 lines of Scala (version 2.13), showing how concise Scala can be!

## Test cases in Scala

```
assert(
getIndicesBased(
Vector(
Vector(1, 2, 3),
Vector(4, 5, 6),
Vector(7, 8, 9),
Vector(10, 11, 12)
)
).toVector == Vector(1, 2, 3, 6, 9, 12, 11, 10, 7, 4, 5, 8)
)
assert(
getIndicesBased(
Vector(
Vector(1, 2, 3, 4),
Vector(5, 6, 7, 8),
Vector(9, 10, 11, 12),
Vector(13, 14, 15, 16),
Vector(17, 18, 19, 20)
)
).toVector == Vector(
1, 2, 3, 4, 8, 12, 16, 20, 19, 18, 17, 13, 9, 5, 6, 7, 11, 15, 14, 10
)
)
assert(getIndicesBased(Vector(Vector(1, 2, 3))).toVector == Vector(1, 2, 3))
assert(
getIndicesBased(Vector(Vector(1), Vector(2), Vector(3))).toVector ==
Vector(1, 2, 3)
)
```