Last active
December 5, 2024 12:14
-
-
Save mscha/f92f45bf0560337a447f7bbfab8c8e21 to your computer and use it in GitHub Desktop.
Advent of Code 2024 day 5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env raku | |
| use v6.d; | |
| $*OUT.out-buffer = False; # Autoflush | |
| # Advent of Code 2024 day 5 -- https://adventofcode.com/2024/day/5 | |
| class Printer | |
| { | |
| has $.input; | |
| has %!rules is SetHash; | |
| has @!updates; | |
| # Process the input: store the rules and the updates | |
| submethod TWEAK | |
| { | |
| for $!input.lines -> $l { | |
| # xx|xx is a rule | |
| if $l ~~ / '|' / { | |
| %!rules{$l}++; | |
| } | |
| # Any other line containing numbers is an update | |
| elsif $l ~~ / \d / { | |
| @!updates.push([$l.comb(/\d+/)]); | |
| } | |
| } | |
| } | |
| # Check if a particular update is valid | |
| method is-valid(@update) | |
| { | |
| # Check each combination of 2 pages to see if they're out of order | |
| for @update.combinations(2) -> ($a,$b) { | |
| return False if %!rules{"$b|$a"}; | |
| } | |
| # Everything is in order | |
| return True; | |
| } | |
| # Return all currently valid updates | |
| method valid-updates | |
| { | |
| @!updates.grep(-> @u { self.is-valid(@u) }); | |
| } | |
| # Fix all invalid updates, returning the corrected updates | |
| method fix-updates | |
| { | |
| gather for @!updates.grep({ !self.is-valid($_) }) -> @u { | |
| CHECKVALID: | |
| until self.is-valid(@u) { | |
| # Check all combinations of 2 pages, and if any are | |
| # out of order, fix and re-check | |
| for (^@u).combinations(2) -> ($i,$j) { | |
| my ($a,$b) = @u[$i,$j]; | |
| if %!rules{"$b|$a"} { | |
| @u.splice($j, 1); | |
| @u.splice($i, 0, $b); | |
| redo CHECKVALID; | |
| } | |
| } | |
| } | |
| take @u; | |
| } | |
| } | |
| } | |
| # Return the middle digit of an array/list | |
| sub middle(@arr) { @arr[@arr div 2] } | |
| sub MAIN(IO() $inputfile where *.f = 'aoc05.input') | |
| { | |
| my $printer = Printer.new(:input($inputfile.slurp)); | |
| say "Part 1: ", $printer.valid-updates.map(-> @u { middle(@u) }).sum; | |
| say "Part 2: ", $printer.fix-updates.map(-> @u { middle(@u) }).sum; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment