Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/perl
- use strict;
- use warnings;
- use feature qw(say);
- use Array::Heap::PriorityQueue::Numeric;
- use Math::Vector::Real;
- my ($vy,$vx) = Math::Vector::Real->canonical_base(2);
- my @Dirs = ($vx, -$vy, -$vx, $vy);
- my @Grid = map { chomp; [split(//)] } <>;
- sub grid_at ($) { my $p = shift; return ($Grid[$p->[0]][$p->[1]]) }
- sub print_grid { say "\t", join( '', @$_ ) foreach (@Grid); }
- my ($start, $end);
- foreach my $y (0 .. $#Grid) {
- foreach my $x (0 .. $Grid[0]->$#*) {
- $start = V($x,$y) if ($Grid[$x][$y] eq 'S');
- $end = V($x,$y) if ($Grid[$x][$y] eq 'E');
- }
- }
- my %visit;
- my $queue = new Array::Heap::PriorityQueue::Numeric;
- $queue->add( [$start, 0, 0, 0], 0 );
- QUEUE:
- while (my $state = $queue->get) {
- my ($pos, $face, $turn, $moves) = @$state;
- if (grid_at($pos) eq 'E') {
- say "Part 1: $moves";
- last QUEUE;
- }
- next QUEUE if (exists $visit{$pos,$face});
- $visit{$pos,$face} = $moves;
- # Try straight if valid
- if (grid_at( $pos + $Dirs[$face] ) ne '#') {
- $queue->add( [$pos + $Dirs[$face], $face, 0, $moves + 1], $moves + 1);
- }
- # Try turns (if we didn't just turn the other way)
- foreach my $t (grep {$turn != -$_} (1,-1)) {
- $queue->add( [$pos, ($face+$t) % 4, $t, $moves + 1000], $moves + 1000);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement