-
Notifications
You must be signed in to change notification settings - Fork 0
/
day12a.pl
83 lines (63 loc) · 1.64 KB
/
day12a.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#!/usr/bin/env perl
use feature ':5.16';
use strict;
use warnings;
use utf8;
use Path::Tiny;
use Storable qw( dclone );
my $small = {
'start' => 1,
'end' => 1,
};
{ package Cave;
sub is_small {
my ($next) = @_;
# See if we've already checked
return 0 if (($small->{ $next } || 0) < 0);
return 1 if (($small->{ $next } || 0) > 0);
my $test = ($next =~ /^[a-z]+$/) ? 1 : -1;
$small->{ $next } = $test;
return $test > 0 ? 1 : 0;
}
sub move {
my ($self, $next) = @_;
my $small = is_small( $next );
return if ($small && $self->{ visited }{ $next });
my $new = Storable::dclone( $self );
$new->{ position } = $next;
$new->{ visited }{ $next } = 1 if ($small);
push @{ $new->{ path } }, $next;
return $new;
}
sub new {
my ($class, $input_file) = @_;
my $self = {
paths => {},
visited => { 'start' => 1 },
position => 'start',
path => [ 'start' ],
};
my @lines = Path::Tiny::path( $input_file )->lines( { chomp => 1 } );
for my $line (@lines) {
my ($start, $end) = $line =~ /^([^-]+)-(.*)$/;
push @{ $self->{ paths }{ $start } }, $end;
push @{ $self->{ paths }{ $end } }, $start;
}
bless $self, $class;
return $self;
}
}
my $input_file = $ARGV[0] || 'input12.txt';
my @caves = ( Cave->new( $input_file ) );
my @paths = ();
while (@caves) {
my $cave = shift @caves;
my $pos = $cave->{ position };
for my $next (@{ $cave->{ paths }{ $pos } }) {
my $new_pos = $cave->move( $next );
push @caves, $new_pos if ($new_pos && $next ne 'end');
push @paths, $new_pos if ($new_pos && $next eq 'end');
}
}
print "There are ", scalar @paths, " possible paths.\n";
exit;