use Data::Dumper;
use List::Util qw(sum);
+use Graph;
use 5.14.0;
die "Usage: $0 <source> <dest> <date> <departure time>\n"
unless( scalar( @ARGV ) == 4 );
-my ( $src, $dest, $date, $depart ) = @ARGV;
+my ( $src_in, $dest_in, $date, $depart ) = @ARGV;
-say "Finding routes from $src to $dest on $date at $depart";
+say "Finding routes from $src_in to $dest_in on $date at $depart";
-my $url = "${query_site}/${src}/${dest}/${depart}/${date}";
+my $url = "${query_site}/${src_in}/${dest_in}/${depart}/${date}";
say "Checking $url";
# This is the overall route
print Dumper( $route );
-my @options;
+# Give me some more useful variables. Note that we need the array because we need the order.
+my @all_stops = map { $_->{abbr} } @{$route->{stops}};
+my %stop_details = map { $_->{abbr} => { departs => $_->{departs}, arrives => $_->{arrives}, point => $_->{point} } } @{$route->{stops}};
-# We can't find the time to the start point, obviously
-for( my $i = 1; $i <= $#{$route->{stops}}; $i++ ){
- my $current_stop = $route->{stops}[$i];
- my $prev_stop = $route->{stops}[$i - 1];
- say "Checking $prev_stop->{point} -> $current_stop->{point}";
-#
- my $stop_url = sprintf "%s/%s/%s/%s/%s", $query_site, $prev_stop->{abbr}, $current_stop->{abbr}, $prev_stop->{departs}, $date;
- push @options, get_stops( $stop_url );
-}
+print Dumper( \%stop_details );
+my $graph = Graph->new();
+my %journeys;
+
+$graph->add_weighted_edge( $all_stops[0], $all_stops[-1], $route->{price} );
+get_substops( \@all_stops );
+
+print Dumper( \%journeys );
-say Dumper( \@options );
+my @best_route = $graph->SP_Dijkstra( $all_stops[0], $all_stops[-1] );
-say sum( map { $_->{price} } @options );
+say "Best route:";
+my $sum = 0;
+for(my $i = 0; $i < $#best_route; $i++ ){
+ my $journey = $journeys{$best_route[$i]}->{$best_route[$i+1]};
+ printf "%s -> %s: %s (%s)\n", $best_route[$i], $best_route[$i+1], $journey->{price}, $journey->{type};
+ $sum += $journey->{price};
+}
+say "Total price: $sum";
+say "Direct price: " . $route->{price};
+##
+## functions below here
sub get_stops {
my ( $url ) = @_;
say "get_stops( $url )";
$tree = $tree->delete();
return \@stops;
}
+
+sub get_substops {
+ my ( $stop_list ) = @_;
+
+ for( my $i = 0; $i <= $#{$stop_list}; $i++ ){
+ for( my $j = $i + 1; $j <= $#{$stop_list}; $j++ ){
+ # skip src-dest as we've already calculated that
+ next if( 0 == $i and $#{$stop_list} == $j );
+ my $src = $stop_list->[$i];
+ my $dst = $stop_list->[$j];
+
+ say "checking $src -> $dst ($i -> $j)";
+
+ my $depart = $stop_details{$src}->{departs};
+ my $url = "${query_site}/${src}/${dst}/${depart}/${date}";
+ my $journey = get_stops( $url );
+
+ $graph->add_weighted_edge($src, $dst, $journey->{price} );
+ $journeys{$src}->{$dst} = $journey;
+ }
+ }
+}