aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-121/lance-wicks/perl/ch-2.pl15
-rw-r--r--challenge-121/lance-wicks/perl/lib/Salesman.pm47
-rw-r--r--challenge-121/lance-wicks/perl/t/02-salesman.t49
3 files changed, 111 insertions, 0 deletions
diff --git a/challenge-121/lance-wicks/perl/ch-2.pl b/challenge-121/lance-wicks/perl/ch-2.pl
new file mode 100644
index 0000000000..e22675c320
--- /dev/null
+++ b/challenge-121/lance-wicks/perl/ch-2.pl
@@ -0,0 +1,15 @@
+use strict;
+use warnings;
+
+__PACKAGE__->run() unless caller;
+
+use lib './lib';
+use Salesman;
+
+sub run {
+ my $s = Salesman->new;
+ print "Input: length = 10\ntour = (0 2 1 3 0)";
+}
+
+1;
+
diff --git a/challenge-121/lance-wicks/perl/lib/Salesman.pm b/challenge-121/lance-wicks/perl/lib/Salesman.pm
new file mode 100644
index 0000000000..3cb495d97b
--- /dev/null
+++ b/challenge-121/lance-wicks/perl/lib/Salesman.pm
@@ -0,0 +1,47 @@
+package Salesman;
+
+use Moo;
+use Data::Dumper;
+use List::MoreUtils;
+
+sub route {
+ my ( $self, $stops ) = @_;
+
+ my $length = 0;
+ my @tour;
+
+ push @tour, 0;
+ my $next = $self->closest( $stops->[0] );
+ push @tour, $next->[0];
+ $length += $next->[1];
+ while ( $next->[0] > 0 ) {
+ my $city_num = $next->[0];
+ $next = $self->closest( $stops->[$city_num] );
+
+ push @tour, $next->[0];
+ $length += $next->[1];
+
+ }
+
+ return {
+ length => $length,
+ tour => \@tour,
+ };
+}
+
+sub closest {
+ my ( $self, $cities ) = @_;
+
+ my $distance = 99999;
+ my $city_id;
+ for my $city_num ( 0 .. @$cities - 1 ) {
+ next if $cities->[$city_num] == 0;
+ if ( $cities->[$city_num] < $distance ) {
+ $distance = $cities->[$city_num];
+ $city_id = $city_num;
+ }
+ }
+ return [ $city_id, $distance ];
+}
+
+1;
diff --git a/challenge-121/lance-wicks/perl/t/02-salesman.t b/challenge-121/lance-wicks/perl/t/02-salesman.t
new file mode 100644
index 0000000000..8ed566789c
--- /dev/null
+++ b/challenge-121/lance-wicks/perl/t/02-salesman.t
@@ -0,0 +1,49 @@
+use Test2::V0 -target => 'Salesman';
+use Test::Output;
+
+subtest 'Testing the script output' => sub {
+ require './ch-2.pl';
+
+ stdout_is { &run() }
+ "Input: length = 10\ntour = (0 2 1 3 0)", 'Example 1';
+
+};
+
+subtest 'Salesman::route' => sub {
+ my $stops
+ = [ [ 0, 5, 2, 7 ], [ 5, 0, 5, 3 ], [ 3, 1, 0, 6 ], [ 4, 5, 4, 0 ], ];
+ is $CLASS->route($stops),
+ {
+ length => 10,
+ tour => [ 0, 2, 1, 3, 0 ]
+ },
+ 'Example 1 route';
+
+ $stops = [
+ [ 0, 5, 2, 7, 9 ],
+ [ 5, 0, 5, 3, 9 ],
+ [ 3, 1, 0, 6, 9 ],
+ [ 4, 5, 4, 0, 3 ],
+ [ 2, 16, 5, 5, 0 ]
+ ];
+ is $CLASS->route($stops),
+ {
+ length => 11,
+ tour => [ 0, 2, 1, 3, 4, 0 ]
+ },
+ 'Example 1 route';
+};
+
+subtest 'Salesman::closest' => sub {
+ is $CLASS->closest( [ 0, 5, 2, 7 ] ), [ 2, 2 ],
+ 'Shortest is city 2 (zero indexed), with distance of 2';
+ is $CLASS->closest( [ 5, 0, 5, 3 ] ), [ 3, 3 ],
+ 'Shortest is city 3 (zero indexed), with distance of 3';
+ is $CLASS->closest( [ 3, 1, 0, 6 ] ), [ 1, 1 ],
+ 'Shortest is city 1 (zero indexed), with distance of 1';
+ is $CLASS->closest( [ 4, 5, 4, 0 ] ), [ 0, 4 ],
+ 'Shortest is city 0 (zero indexed), with distance of 4';
+
+};
+
+done_testing;