Voronoi diagram is a partition of a plane (or part of plane) into regions close to each of a given set of objects ("seeds").
Here we’ll be dealing with discrete arrays or even rather with ASCII-art:
2 2 4 4 4 4 1 1 1 1 1 1 1 3 3 3 3
2 2 4 4 4 1 1 1 1 1 1 1 3 3 3 3 3
2 2 4 4 4 1 1 1 1 1 1 3 3 3 3 3 3
2 2 2 4 1 1 1 1 1 1 3 3 3 3 3 3 3
2 2 2 1 1 1 1 1 1 3 3 3 3 3 3 3 3
2 2 2 1 1 1 1 1 1 3 3 3 3 3 3 3 3
2 2 2 1 1 1 1 1 1 3 3 3 3 3 3 3 3
5 5 5 1 1 1 1 1 1 3 3 3 3 3 3 3 3
5 5 5 5 5 5 5 1 1 3 3 3 3 3 3 3 3
5 5 5 5 5 5 5 5 3 3 3 3 3 3 3 3 3
5 5 5 5 5 5 5 5 3 3 3 3 3 3 3 3 3
5 5 5 5 5 5 5 5 3 3 3 3 3 3 3 3 3
5 5 5 5 5 5 5 5 3 3 3 3 3 3 3 3 3
5 5 5 5 5 5 5 5 5 3 3 3 3 3 3 3 3
Since it is not difficult to draw a discrete Voronoi diagram, we will go a little further and consider Lloyd's algorithm.
Short description
It repeatedly finds the centroid of each cell in the Voronoi partition and then re-partitions the input according to which of these centroids is closest. The process converges quickly to a certain precision, but for real numbers formally infinitely long. For integer coordinates the process should always stop.
To find Voronoi cells you can use any of the algorithms of several known. Like just brutal-force tagging with nearest seed, or something like this.
It seems that with the next distance functions process will be converge (but I have no math proof):
- SquaredEuclidean distance
- Euclidean distance
- Chessboard (Chebyshev) distance
- Manhattan distance
- Canberra distance
Probably with slightly different visual results. You can use any distance that is suitable for golfing in your language.
Challenge
Print out ASCII art as a result of Lloyd's algorithm for given initial seeds.
Input
- Width
W
and heightH
of the board. IntegersW, H > 0
and not very big (no more than100
I think) - Initial array of seeds as explicit list of coordinates:
[[4,5], [1,1], …]
- Number of seeds (as length of array)
N
should be0 < N < 10
(for not to break print formatting)
Output
Final state of Lloyd's process as a pretty-printed array of ASCII strings, where "0"
is used for any seed and "1"..."9"
digits for filling corresponding cells.
Might be interesting to print firstly initial state.
Test cases
The main test is that the code is not broken in obvious cases, for example:
Input: W:2, H:2, initial seeds: [[1,1]]
Output:
01
11
Input: W:10, H:1, initial seeds:[[1, 1], [2, 1]]
Output:
1011220222
Simple program on Mathematica 12.2 was used for samples.
With ChessboardDistance
as distance function,
Nearest
as core for Voronoi tessellation and FixedPoint
, Floor@Mean@Position
combination for Lloyd relaxation.
Input: W:13, H:10, initial seeds: [[2, 3], [4, 7], [8, 8], [9, 11]]
Initial Voronoi partition:
1 1 1 1 1 1 2 2 2 2 2 2 2
1 1 0 1 1 2 2 2 2 2 2 2 2
1 1 1 1 1 2 2 2 2 2 2 2 3
1 1 1 1 1 2 0 2 2 2 2 3 3
1 1 1 1 2 2 2 2 2 2 3 3 4
1 1 1 2 2 2 2 2 2 3 3 4 4
1 1 2 2 2 3 3 3 3 3 4 4 4
1 2 2 2 3 3 3 0 3 4 4 4 4
2 2 2 3 3 3 3 3 3 4 0 4 4
2 2 3 3 3 3 3 3 3 4 4 4 4
Result of the Lloyd process:
1 1 1 1 1 2 2 2 2 2 2 2 2
1 1 1 1 1 2 2 2 2 2 2 2 4
1 1 0 1 1 2 2 0 2 2 2 4 4
1 1 1 1 1 2 2 2 2 2 4 4 4
1 1 1 1 1 2 2 4 4 4 4 4 4
1 3 3 3 3 3 3 4 4 4 4 4 4
3 3 3 3 3 3 3 4 4 4 0 4 4
3 3 3 0 3 3 3 4 4 4 4 4 4
3 3 3 3 3 3 3 4 4 4 4 4 4
3 3 3 3 3 3 3 3 4 4 4 4 4
As challenge is not very difficult, it is code-golf and shortest code wins.
[[1,1]]
in the first test case would be either the top-left if 1-based indexing is used or bottom-right if 0-based indexing is used. But instead, the output has a0
at index[1,2]
(1-based) /[0,1]
(0-based). Likewise I also don't get how coordinate[2,1]
can result in a0
at the 6th position of the 1x10 output-block. \$\endgroup\$