pwagyi has asked for the wisdom of the Perl Monks concerning the following question:
I am facing a problem in recognizing a pattern in 2 dimensional grid. 2D grid is represented by hash of hash (X,Y coordinate as key, and value). I need to recognize some patterns like (horizontal, vertical, or diagonal) example data (x,y coordinate and value (a,b,c,..))
recognize( pattern => 'horizontal', min => 3); # recognize 3 or more +consecutive horizontal pattern recognize( pattern => 'vertical', min => 5); |a|a|b|a|c| |a|a|c|e|f| |e|f|a|1|b|
|
---|
Replies are listed 'Best First'. | |||
---|---|---|---|
Re: Recognizing pattern in 2D grid
by Athanasius (Archbishop) on Jan 16, 2018 at 03:49 UTC | |||
Hello pwagyi, I think an array of arrays (AoA) is a better data structure for this task than a hash of hashes (HoH). And if each datum is only a single character, as in the example given, you can use regular expressions to do the searching. The following script lacks proper error checking, etc., but should give you an idea of how to proceed:
Output:
Update: It occurs to me, belatedly, that a “diagonal” pattern might mean a sequence on any diagonal, and not just one of the two major diagonals, as I naïvely assumed. Extending the code to allow for matches on any diagonal is hereby left as the proverbial exercise for the reader. :-) Hope that helps,
| [reply] [d/l] [select] | ||
Re: Recognizing pattern in 2D grid
by tybalt89 (Monsignor) on Jan 16, 2018 at 07:29 UTC | |||
Form a multiline string and play with the $gap.
Outputs:
| [reply] [d/l] [select] | ||
Re: Recognizing pattern in 2D grid
by Eily (Monsignor) on Jan 16, 2018 at 15:23 UTC | |||
Hello pwagyi. I wanted to try a on a flat string, with a regex that would do something like /A(.*)B.{N}C.{N}D/ where (.*) would be of length 0 (row), width (column) or width+1 (diagonal from top left to bottom right), and N would somehow be equal to that length. I managed to do that using (??{ CODE }) patterns, which makes it possible to embed a new sub pattern in a regex while it is being run. But it is not available by default: you need use re "eval";. Since the regex is build from the searched pattern, this ended up being a function that takes a pattern as a parameter, and returns a closure that will search that pattern in a grid. Maybe that's too many advanced perl feature for usable code ^^" .
| [reply] [d/l] [select] |