From: Michael Howe Date: Tue, 8 Apr 2014 21:16:56 +0000 (+0100) Subject: It works! X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=a3dd92eef68cf36dbae91d5fb8d5f90fe3bfcee9;p=pub%2Fmichael%2Fnational-rail-ticket-split.git It works! Needs lots of tidying up and error- and sanity-checking adding, but it seems to be returning the information I expect. --- diff --git a/parse-route.pl b/parse-route.pl index 6eeebca..63ebd06 100755 --- a/parse-route.pl +++ b/parse-route.pl @@ -7,6 +7,7 @@ use HTML::TreeBuilder; use Data::Dumper; use List::Util qw(sum); +use Graph; use 5.14.0; @@ -17,11 +18,11 @@ my $query_site = "http://traintimes.org.uk"; die "Usage: $0 \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 @@ -29,22 +30,33 @@ my $route = get_stops( $url ); 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 )"; @@ -120,3 +132,25 @@ sub _parse_stopping_points { $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; + } + } +}