Perl Monk, Perl Meditation PerlMonks

### comment on

 Need Help??
One possible solution:
1. Start at the first number from the input list.
2. Create two lists: list of visited numbers, and list of the matrix positions to visit.
3. Mark the current number as visited at the current position. If you visited all the input numbers, return true.
4. Check all the neighbouring positions, non-visited ones present in the input list should go to the list of positions to visit.
5. Visit the first position from the list, go to #3.
6. If the list is empty, try starting with the next input number (this is needed, as numbers could be repeated, e.g. 2 in your sample). Go to #2.
7. You tried all the input numbers, but you can't reach all the rest from any of them. Return false.

Which translates easily to Perl:

```#! /usr/bin/perl
use warnings;
use strict;

my @matrix = ( [ 1,  2,  3,  4],
[ 5,  6,  7,  8],
[ 9, 10, 11, 12],
[13, 14,  3, 16],
[ 2, 18, 19, 20],
);

sub nearby {
my @input = @_;
my %numbers;
undef @numbers{@input};

for my \$y (0 .. \$#matrix) {
for my \$x (0 .. \$#{ \$matrix[\$y] }) {
next unless exists \$numbers{ \$matrix[\$y][\$x] };

my @next = ([\$x, \$y]);
my %visited;
while (@next) {
my (\$r, \$s) = @{ shift @next };
undef \$visited{ \$matrix[\$s][\$r] }{"\$r \$s"};
return 1 if keys %visited == keys %numbers;

push @next, grep \$_->[0] >= 0 && \$_->[1] >= 0
&& \$_->[0] <= \$#{ \$matrix[\$s] } && \$_->[1]
+ <= \$#matrix
&& exists \$numbers{ \$matrix[ \$_->[1] ][ \$_
+->[0] ] }
&& ! exists \$visited{ \$matrix[ \$_->[1] ][
+\$_->[0] ] }{"@\$_"},
[\$r - 1, \$s - 1],
[\$r,     \$s - 1],
[\$r + 1, \$s - 1],
[\$r + 1, \$s    ],
[\$r + 1, \$s + 1],
[\$r,     \$s + 1],
[\$r - 1, \$s + 1],
[\$r - 1, \$s    ];
# warn map "<@\$_>", @next;
}
}
}
return
}

use Test::More;

ok(nearby(2, 7, 12, 16));
ok(nearby(2, 4, 7, 12));
ok(! nearby(1, 6, 8, 12));
ok(! nearby(1, 5, 14, 15));

# Unspecified?
ok(nearby(2, 13, 9, 5, 7));
ok(! nearby(2, 13, 7));
ok(nearby(6, 3, 8, 12, 18));

@matrix = ( [ 1,  1,  1,  1, 2],
[ 1,  0,  0,  0, 0],
[ 1,  0,  1,  1, 3],
[ 1,  0,  1,  0, 0],
[ 1,  0,  1,  1, 1],
[ 1,  0,  0,  0, 1],
[ 1,  1,  1,  1, 1],
);
ok(nearby(1, 2, 3));

done_testing();

Update: It's unclear how to handle duplicate numbers. The code returns true for the last case, but did you really want to use 1 several times? Please, clarify your specification.

Update 2: added positions to visited numbers.

لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

In reply to Re: perl array matrix by choroba
in thread perl array matrix by perlhelp

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

• Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
• Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
• Read Where should I post X? if you're not absolutely sure you're posting in the right place.
• Posts may use any of the Perl Monks Approved HTML tags:
a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
• You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
 For: Use: & & < < > > [ [ ] ]
• Link using PerlMonks shortcuts! What shortcuts can I use for linking?

Create A New User
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (5)
As of 2021-04-17 21:33 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?

No recent polls found

Notices?