How to find minimum and maximum of cartesian co-ordinates in Scala
-
17-04-2021 - |
Question
I am trying to solve GameOfLife in Scala where I have an infinte grid. I am trying to represent the grid as a Set of Cell(x,y). When I read from say String I start at (0,0). But because of the laws of GameOfLife and since I am considering Infinite Grid after having applied rules to my Generation class I want to print current generation.
Here I am not sure how to calculate the minimum position (read x,y iterators) from where to start iterating and printing either 'X' for alive cell and '-' for dead cell in GameOfLife for that Generation.I am supplying my naive solution of toString method of Generation class. But I am not at all happy with it. Can somebody suggest be a better succient solution?
override def toString:String =
{
val output:StringBuilder = new StringBuilder();
val minOfRowColumn = for
{
cell <- aliveCells
row = cell.row
column = cell.column
} yield if( row < column ) row else column
val min = minOfRowColumn.min
val maxOfRowColumn = for
{
cell <- aliveCells
row = cell.row
column = cell.column
} yield if( row > column ) row else column
val max = maxOfRowColumn.max
var row = min;
var column = min;
while(row <= max)
{
while(column <= max)
{
if(aliveCells.contains(Cell(row,column)))
{
output.append('X')
}
else
output.append('-')
column = column + 1
}
output.append("\n");
column = min
row = row + 1
}
//remove the last new line addded.
val indexOfNewLine = output.lastIndexOf("\n");
if( -1 != indexOfNewLine )
output.delete(indexOfNewLine,output.length());
return output.toString();
}
aliveCells here is a Set[Cell] where Cell is Cell(x,y) a case class.
La solution
I propose the following code :
override def toString = {
val min = aliveCells.iterator.flatMap(c => Seq(c.row, c.column)).min
val max = aliveCells.iterator.flatMap(c => Seq(c.row, c.column)).max
(min to max) map { row =>
(min to max) map (col => if (aliveCells(Cell(row, col))) "X" else "-") mkString
} mkString ("\n")
}
You may want to separate min/max column and row if you do not specifically want a squared grid:
val minC = aliveCells.iterator.map(_.column).min
and so on.