mscha

AoC 2016.10

Dec 10th, 2016
323
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 6 2.65 KB | None | 0 0
  1. #!/usr/bin/env perl6
  2.  
  3. use v6.c;
  4.  
  5. class Bot
  6. {
  7.     has Int $.number;
  8.     has Pair $.low-dest;
  9.     has Pair $.high-dest;
  10.     has Int @.values = ();
  11.  
  12.     my Bot @known-bots;
  13.     my Int @.output;
  14.  
  15.     method bot(Bot:U: Int $number) returns Bot
  16.     {
  17.         @known-bots[$number] //= Bot.new(:$number);
  18.         return @known-bots[$number];
  19.     }
  20.  
  21.     method set-dest(Pair $low-dest, Pair $high-dest)
  22.     {
  23.         $!low-dest = $low-dest;
  24.         $!high-dest = $high-dest;
  25.     }
  26.  
  27.     method add-value(Int $value)
  28.     {
  29.         @!values.push($value);
  30.  
  31.         if (@!values.elems == 2) {
  32.             # Part 1 answer
  33.             # Not very elegant, oh well...
  34.             if min(@!values) == 17 and max(@!values) == 61 {
  35.                 say "Bot $!number is comparing value-61 microchips with value-17 microchips.";
  36.             }
  37.  
  38.             if !$!low-dest || !$!high-dest {
  39.                 die "Bot $!number has two values but no instructions!";
  40.             }
  41.             else {
  42.                 if $!low-dest.key eq 'bot' {
  43.                     Bot.bot($!low-dest.value).add-value(min(@!values));
  44.                 }
  45.                 else {
  46.                     @.output[$!low-dest.value] += min(@!values);
  47.                 }
  48.  
  49.                 if $!high-dest.key eq 'bot' {
  50.                     Bot.bot($!high-dest.value).add-value(max(@!values));
  51.                 }
  52.                 else {
  53.                     @.output[$!high-dest.value] += max(@!values);
  54.                 }
  55.  
  56.                 @!values = ();
  57.             }
  58.         }
  59.     }
  60. }
  61.  
  62. my token num { \d+ }
  63. my token dest { bot || output }
  64. my rule init { ^ value <value=num> goes to bot <bot=num> $ }
  65. my rule instr { ^ bot <bot=num> gives low to <dest-low=dest> <value-low=num>
  66.                             and high to <dest-high=dest> <value-high=num> $ }
  67.  
  68. sub MAIN(IO() $inputfile where *.f)
  69. {
  70.     # Read the input in two passes, first the instructions, then the initializations.
  71.     PASS:
  72.     for ^2 -> $pass {
  73.         LINE:
  74.         for $inputfile.lines -> $line {
  75.             if $line ~~ &init {
  76.                 next LINE if $pass == 0;
  77.                 Bot.bot(+$<bot>).add-value(+$<value>);
  78.             }
  79.             elsif $line ~~ &instr {
  80.                 next LINE if $pass == 1;
  81.                 Bot.bot(+$<bot>).set-dest(~$<dest-low> => +$<value-low>,
  82.                                           ~$<dest-high> => +$<value-high>);
  83.             }
  84.             else {
  85.                 die "Invalid input: $line";
  86.             }
  87.         }
  88.     }
  89.  
  90.     # Part 2 answer
  91.     my @output = Bot.output;
  92.     say "The product of outputs 0, 1 and 2 is @output[^3].join('*') = { [*] @output[^3] }.";
  93. }
Add Comment
Please, Sign In to add comment