#!/usr/bin/env perl use strict; use warnings; use List::Util qw(first reduce); my @rules = (); while (<>) { last if /^\s*$/; chomp; push @rules, [split /\|/]; } my @correct_order = (); my @incorrect_order = (); while (<>) { next if /^\s*$/; chomp; my @pages = split /,/; my $hit = 1; for my $rule (@rules) { my $a = first { $pages[$_] eq $rule->[0] } 0 .. $#pages; my $b = first { $pages[$_] eq $rule->[1] } 0 .. $#pages; if (defined($a) && defined($b) && $a > $b) { $hit = 0; last; } } if ($hit) { push @correct_order, \@pages; } else { push @incorrect_order, \@pages; } } print "Part 1: ", reduce { $a + $b } map { $_->[@$_/2] } @correct_order; print "\n"; my @fixed_incorrect_order = map { fix_order(@$_) } @incorrect_order; print "Part 2: ", reduce { $a + $b } map { $_->[@$_/2] } @fixed_incorrect_order; print "\n"; sub fix_order { my @pages = @_; my $rule_violated = 1; while ($rule_violated) { $rule_violated = 0; for my $rule (@rules) { my $a = first { $pages[$_] eq $rule->[0] } 0 .. $#pages; my $b = first { $pages[$_] eq $rule->[1] } 0 .. $#pages; if (defined($a) && defined($b) && $a > $b) { @pages[$a, $b] = @pages[$b, $a]; $rule_violated = 1; } } } return \@pages; }