Marching squares
# 20220708 Raku programming solution
enum <E N W S>;
my (@dx,@dy) := (1,0,-1,0), (0,-1,0,1);
my \example = ((0, 0, 0, 0, 0),
(0, 0, 0, 0, 0),
(0, 0, 1, 1, 0),
(0, 0, 1, 1, 0),
(0, 0, 0, 1, 0),
(0, 0, 0, 0, 0));
printf("X: %d, Y: %d, Path: %s\n", identifyPerimeter(example));
sub identifyPerimeter(\data) {
my (\height,\width) = { .elems, .first.elems }(data);
for ^width X ^height -> (\x,\y) {
if data[y;x] {
my ($cx,$cy,$directions,$previous) = x, y;
repeat {
my $mask;
for (0,0,1),(1,0,2),(0,1,4),(1,1,8) -> (\dx,\dy,\b) {
my ($mx,$my) = $cx+dx,$cy+dy;
$mask += b if all $mx>1, $my>1, data[$my-1;$mx-1]
}
given do given $mask {
when * ∈ ( 1, 5, 13 ) { N }
when * ∈ ( 2, 3, 7 ) { E }
when * ∈ ( 4, 12, 14 ) { W }
when * ∈ ( 8, 10, 11 ) { S }
when * ∈ ( 6 ) { $previous == N ?? W !! E }
when * ∈ ( 9 ) { $previous == E ?? N !! S }
} {
$directions ~= $previous = $_ ;
($cx,$cy) <<+=<< (@dx[.value], @dy[.value])
}
} until $cx==x and $cy==y ;
return x, -y, $directions
}
}
return -1, -1, "Not found!"
}
Output is the same as the Phix entry.
Last updated