use strict; use warnings; my %edges; while (<>) { /(\w+)-(\w+)/; $edges{$1} //= []; $edges{$2} //= []; push @{$edges{$1}}, $2; push @{$edges{$2}}, $1; } my $paths = 0; my @queue = (['start']); while (@queue) { my @path = @{pop @queue}; my %visited = map { $_ => 1 } @path; for (@{$edges{$path[0]}}) { if ($_ eq 'end') { $paths++; } elsif (/[a-z]/ && $visited{$_}) { next; } else { my @next = ($_, @path); push @queue, \@next; } } } print "$paths\n"; $paths = 0; @queue = (['start']); while (@queue) { my @path = @{pop @queue}; my (%visited, $twice); for (@path) { $twice = 1 if $visited{$_}++ && /[a-z]/; } for (@{$edges{$path[0]}}) { next if $_ eq 'start'; if ($_ eq 'end') { $paths++; } elsif (/[a-z]/ && $visited{$_} && $twice) { next; } else { my @next = ($_, @path); push @queue, \@next; } } } print "$paths\n";