if you don't have node, install nvm.
then,
$ nvm use 5.6.0
$ npm run startand watch the maps go...
a map is a 2-dimensional array of values in range [0,1].
/* map */
[
[0, 1, 0],
[1, 1, 0],
[0, 0, 0]
]connections in this map are represented as a list of tuples.
every point [x,y] is connected to itself.
given a point [x,y], there exists a point upward ([x-1,y]) and
leftward ([x,y-1]) from that point. if the value in the map at
either of these points equals 1, a connection is made. if there is no
point leftward or upward from [x,y], its value defaults to 0.
the connections in the map above are listed:
/* connections */
[ [ [0,1], [0,1] ],
[ [1,0], [1,0] ],
[ [1,1], [1,1] ],
[ [1,1], [0,1] ],
[ [1,1], [1,0] ] ]an island is a blob of 1s that are mutually connected to each other.
each island is represented as an array of points [x,y]
an island in the map above:
/* island */
[ [0,1], [1,0], [1,1] ]islands are a list of these islands:
/* islands */
[ [ [0,1], [1,0], [1,1] ] ]defining representation of map as grid x * y,
0 1 2 3 . . . y
0 . . % . <- % @ [0,2],
1 . # * . * @ [1,2],
2 . . . . # @ [1,1]
3 . . . . % is upward of *
. # is leftward of *
.
.
x
, for any two points [x,y], [p,q] such that map[x][y] = map[p][q] = 1, we define a connection [[x,y],[p,q]]
- between a point
[x,y]and itself (wherex = p, y = q).(1) - between a point
[x,y]and leftward point[p,q]wherex = pandy > q.(2) - between a point
[x,y]and upward point[p,q]wherex > pandy = q.(3)
therefore, for any given connection [[x,y],[p,q]], x >= p and y >= q. (4)
when processing arrays, we iterate right-to-left and up-to-down - i.e.,
in increasing order. therefore, for any point [p,q] = 1 left- or
up- ward from [x,y] during iteration, by (1) and (4), there will
already exist a connection [[p,q],[p,q]]. (5)
by only storing in one direction per dimension, we do not store duplicate connections.
so, given these connections...
this is done recursively, by calling findIslands with (connections)
and (islands). in the steps below, any recur signifies going back
to step 1..
- if
connections = [], returnislands(how we break out of recursion) - take connection
[[a,b],[p,q]]fromconnections, storing the rest of the connections inknxs - find index
isleof island inislandsthat contains point[p,q]((5)) - if there exists no island in
islands(indicated byisle < 0), recur with(knxs)and concatenation of island[[p,q]]toislands. - if there does exist an island containing
[p,q], construct new island from concatentation ofislands[isle]and[a,b]and look for index of a connected islandkntdIslecontaining[a,b] - if there is no such
kntdIsle, recur with(knxs)and updatedislands - if it does exist, integrate this island into
islands[isle], taking all points[x,y] != [a,b]inislands[kntdIsle]and removingislands[kntdIsle], and recur with(knxs)and updatedislands.
and... that's it.
/* map */
[ [ 0, 0, 1 ],
[ 1, 1, 0 ],
[ 1, 0, 0 ] ]
/* connections */
[ [ [ 0, 2 ], [ 0, 2 ] ],
[ [ 1, 0 ], [ 1, 0 ] ],
[ [ 1, 1 ], [ 1, 1 ] ],
[ [ 1, 1 ], [ 1, 0 ] ],
[ [ 2, 0 ], [ 2, 0 ] ],
[ [ 2, 0 ], [ 1, 0 ] ] ]
islands = []
[ a, b ] [ p, q ]
[ 0, 2 ] [ 0, 2 ] 'index of isle:' -1
islands = [ [ [0,2] ] ]
[ a, b ] [ p, q ]
[ 1, 0 ] [ 1, 0 ] 'index of isle:' -1
islands = [ [ [0,2] ], [ [1,0] ] ]
[ a, b ] [ p, q ]
[ 1, 1 ] [ 1, 1 ] 'index of isle:' -1
[ [ [0,2] ], [ [1,0] ], [ [1,1] ] ]
[ a, b ] [ p, q ]
[ 1, 1 ] [ 1, 0 ] 'index of isle:' 1
islands = [ [ [0,2] ], [ [1,0], [1,1] ] ]
[ a, b ] [ p, q ]
[ 2, 0 ] [ 2, 0 ] 'index of isle:' -1
islands = [ [ [0,2] ], [ [1,0], [1,1] ], [ [2,0] ] ]
[ a, b ] [ p, q ]
[ 2, 0 ] [ 1, 0 ] 'index of isle:' 1
islands = [ [ [0,2] ], [ [1,0], [1,1], [2,0] ] ]