aboutsummaryrefslogtreecommitdiff
path: root/challenge-281/e-choroba/perl/ch-2.pl
blob: 60e9bdba295cb578225446492795a51fa11138a6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#!/usr/bin/perl
use warnings;
use strict;
use experimental qw( signatures );

sub knights_move($start, $end) {
    return 0 if $start eq $end;

    tr/a-h/1-8/ for $start, $end;
    my %agenda = ($start => undef);
    my %visited;
    my $tally = 1;

  SEARCH:
    while (1) {
        my %next;
        for my $coord (keys %agenda) {
            my ($x, $y) = split //, $coord;
            for my $jump ([-2, -1], [-1, -2], [1, -2], [2, -1],
                          [2, 1], [1, 2], [-1, 2], [-2, 1]
            ) {
                my ($x2, $y2) = ($x + $jump->[0], $y + $jump->[1]);
                next if $x2 < 1 || $y2 < 1 || $x2 > 8 || $y2 > 8;

                last SEARCH if "$x2$y2" eq $end;

                undef $next{"$x2$y2"};
            }
        }
        %agenda = %next;
    } continue {
        ++$tally;
    }
    return $tally
}

use Test::More tests => 2 + 2;

is knights_move('g2', 'a8'), 4, 'Example 1';
is knights_move('g2', 'h2'), 3, 'Example 2';

is knights_move('a1', 'a1'), 0, 'Zero';
is knights_move('a1', 'h8'), 6, 'Far';