88 lines
1.6 KiB
Perl
88 lines
1.6 KiB
Perl
|
package part2;
|
||
|
|
||
|
use 5.20.0;
|
||
|
use warnings;
|
||
|
|
||
|
use List::AllUtils qw/ pairmap zip product /;
|
||
|
use Range::Merge qw/ merge /;
|
||
|
use Set::Object qw/ set /;
|
||
|
|
||
|
require './part1.pm';
|
||
|
|
||
|
use experimental qw/ signatures postderef /;
|
||
|
|
||
|
sub inRanges($n, $ranges) {
|
||
|
|
||
|
for (@$ranges) {
|
||
|
return 1 if $_->[0] <= $n and $_->[1] >= $n;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
sub possibilities($n,$fields) {
|
||
|
|
||
|
return set(
|
||
|
grep { inRanges($n, $fields->{$_})} keys %$fields
|
||
|
)
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
sub solution($input) {
|
||
|
my ( $fields, $myticket, $tickets ) = split "\n\n", $input;
|
||
|
|
||
|
my %fields = map {
|
||
|
my ( $name, $ranges) = split ':';
|
||
|
$name => merge([ map { [ split '-'] } $ranges =~ /(\d+-\d+)/g ])
|
||
|
} split "\n", $fields;
|
||
|
|
||
|
my @global;
|
||
|
|
||
|
for my $ticket ( split "\n", $tickets ) {
|
||
|
next if $ticket =~ /nearby/;
|
||
|
|
||
|
my @fields = split ',', $ticket;
|
||
|
|
||
|
@fields = map { possibilities($_,\%fields) } @fields;
|
||
|
|
||
|
next if grep { not $_->size } @fields;
|
||
|
|
||
|
if(!@global) {
|
||
|
@global = @fields;
|
||
|
}
|
||
|
else {
|
||
|
@global = pairmap { $a*$b } zip @global, @fields;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
use DDP; say join " ", @$_ for @global;
|
||
|
|
||
|
my %indexes;
|
||
|
|
||
|
LOOP: while() {
|
||
|
for( 0..$#global ) {
|
||
|
if( $global[$_]->size == 1 ) {
|
||
|
my $e = $global[$_];
|
||
|
$indexes{$global[$_][0]} = $_;
|
||
|
@global = map { $_ - $e } @global;
|
||
|
redo LOOP;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
last LOOP;
|
||
|
}
|
||
|
|
||
|
p %indexes;
|
||
|
|
||
|
my @myt = $myticket =~ /(\d+)/g;
|
||
|
|
||
|
return product
|
||
|
@myt[
|
||
|
map { $indexes{$_} }
|
||
|
grep { /departure/ } keys %indexes ];
|
||
|
|
||
|
}
|
||
|
|
||
|
1;
|