diff options
| author | E7-87-83 <fungcheokyin@gmail.com> | 2024-08-10 15:50:12 +0800 |
|---|---|---|
| committer | E7-87-83 <fungcheokyin@gmail.com> | 2024-08-10 15:50:12 +0800 |
| commit | 3a503ee926baebda59104d60eddd9ca351686ef5 (patch) | |
| tree | f7538a508de2826d6848a4f7449a84cb9a630128 | |
| parent | cbb4830d700aae2157fd59d506c0807a0c14f8dc (diff) | |
| download | perlweeklychallenge-club-3a503ee926baebda59104d60eddd9ca351686ef5.tar.gz perlweeklychallenge-club-3a503ee926baebda59104d60eddd9ca351686ef5.tar.bz2 perlweeklychallenge-club-3a503ee926baebda59104d60eddd9ca351686ef5.zip | |
Week 281 Task 2
| -rw-r--r-- | challenge-281/cheok-yin-fung/perl/ch-2.pl | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/challenge-281/cheok-yin-fung/perl/ch-2.pl b/challenge-281/cheok-yin-fung/perl/ch-2.pl new file mode 100644 index 0000000000..09874c7416 --- /dev/null +++ b/challenge-281/cheok-yin-fung/perl/ch-2.pl @@ -0,0 +1,89 @@ +# The Weekly Challenge 281 +# Task 2 Knight's Move + +use v5.30.0; +use warnings; +use List::Util qw/min/; + +sub small_dist { + my $pos_a = $_[0]; + my $pos_b = $_[1]; + my $diff0 = abs($pos_a->[0]-$pos_b->[0]); + my $diff1 = abs($pos_a->[1]-$pos_b->[1]); + if ($diff0 == 1 && $diff1 == 2 || $diff0 == 2 && $diff1 == 1) + {return 1;} + if ($diff0 == 0 && $diff1 == 2 || $diff0 == 2 && $diff1 == 0) + {return 2;} + if ($diff0 == 0 && $diff1 == 1 || $diff0 == 1 && $diff1 == 0) + {return 3;} + if ($diff0 == 1 && $diff1 == 1) { + if (is_corner($pos_a)|| is_corner($pos_b)) { + return 4; + } + else { + return 2; + } + } + if ($diff0 == 2 && $diff1 == 2) { + return 4; + } +} + +sub km { + my $targt = $_[0]; + my $begin = $_[1]; + my $pos_a = [ord(substr($begin,0,1))-ord("a"), substr($begin,1,2)-1]; + my $pos_b = [ord(substr($targt,0,1))-ord("a"), substr($targt,1,2)-1]; + return dist($pos_a, $pos_b); +} + +sub dist { + my $pos_a = $_[0]; + my $pos_b = $_[1]; + if ((abs($pos_a->[0]-$pos_b->[0]) <= 2) && (abs($pos_a->[1]-$pos_b->[1]) <= 2)) { + return small_dist($pos_a, $pos_b); + } + my $cur_tc_dist = taxicab_dist($pos_a, $pos_b); + my @px = (+2, +2, +1, +1, -1, -1, -2, -2); + my @py = (+1, -1, +2, -2, +2, -2, +1, -1); + my @nxt; + for my $k (0..7) { + my $npx = $pos_b->[0]+$px[$k]; + my $npy = $pos_b->[1]+$py[$k]; + if ($npx < 0 || $npx > 7) {next;} + if ($npy < 0 || $npy > 7) {next;} + my $tc_dist = taxicab_dist($pos_a, [$npx, $npy]); + push @nxt, [$npx, $npy] if $tc_dist < $cur_tc_dist; + } + if (scalar @nxt == 1) { + return ( 1 + dist($pos_a, $nxt[0]) ); + } else { + my @choice_val; + for (0..$#nxt) { + $choice_val[$_] = 1 + dist($pos_a, $nxt[$_]); + } + #say(chr(ord('a')+$pos_b->[0]).(1+$pos_b->[1])." ", min(@choice_val)); + return min(@choice_val); + } +} +sub taxicab_dist { + my $pos_a = $_[0]; + my $pos_b = $_[1]; + my $taxicab_dist = + abs($pos_a->[0]-$pos_b->[0]) + + + abs($pos_a->[1]-$pos_b->[1]); + return $taxicab_dist; +} + +sub is_corner { + my $pos = $_[0]; + if (($pos->[0] == 0 || $pos->[0] == 7) + && + ($pos->[1] == 0 || $pos->[1] == 7)) + { + return 1; + } + return 0; +} + |
