Advertisement
Guest User

Untitled

a guest
Dec 16th, 2020
145
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 4.36 KB | None | 0 0
  1. #!/usr/bin/perl
  2.  
  3. $filename = "16.txt";
  4.  
  5. open(FILE, $filename);
  6. @data = <FILE>;
  7. close(FILE);
  8.  
  9. %rules = ();
  10. $myticket = "";
  11. @tickets = ();
  12. @validtickets = ();
  13. %ruleorder = ();
  14. @ra = ();
  15.  
  16. # Read the file into variables.
  17.  
  18. foreach $line (@data) {
  19.         $line =~ s/\n//sgi;
  20.         $line =~ s/\r//sgi;
  21.         $line =~ s/\t//sgi;
  22.  
  23.         # Rule description
  24.  
  25.         if ($line =~ m/^([a-z ]*): (\d+)-(\d+) or (\d+)-(\d+)$/) {
  26.                 $rules{$1} = $2."-".$3."-".$4."-".$5;
  27.         }
  28.  
  29.         # A ticket line. If my ticket is not set, the line is first ticket line, thus its MY ticket.
  30.  
  31.         if ($line =~ m/^\d+,\d+,\d+,\d+,\d+,\d+,\d+,\d+,\d+,\d+,\d+,\d+,\d+,\d+,\d+,\d+,\d+,\d+,\d+,\d+$/) {
  32.                 if (length($myticket) < 20) {
  33.                         $myticket = $line;
  34.                 }
  35.                 else
  36.                 {
  37.                         push(@tickets, $line);
  38.                 }
  39.         }
  40. }
  41.  
  42. $scanerror = 0;
  43.  
  44. # Loop through all OTHER tickets.
  45. foreach $ticket (@tickets) {
  46.         @fields = split(",",$ticket);
  47.         $vticket = 1;
  48.  
  49.         foreach $field (@fields) {
  50.  
  51.                 # Loop through all fields in ticket.
  52.                 $valid = 0;
  53.                 foreach $rule (keys %rules) {
  54.                         # Check field against all rules.
  55.                         ($lowa, $higha, $lowb, $highb) = split("-", $rules{$rule});
  56.                         if (((int($field) >= $lowa)&&(int($field) <= $higha)) || ((int($field) >= $lowb)&&(int($field) <= $highb))) {
  57.                                 $valid = 1;
  58.                         }
  59.                 }
  60.                 if ($valid == 0) {
  61.                         # If all rules are invalid, then the field is invalid, add it to scan error rate.
  62.                         $scanerror = $scanerror + int($field);
  63.                         $vticket = 0;
  64.                 }
  65.         }
  66.         if ($vticket == 1) {
  67.                 # Ticket is valid - theres no invalid fields in ticket. Add it to valid ticket tally for part 2.
  68.                 push(@validtickets, $ticket);
  69.         }
  70. }
  71.  
  72. print "P1: $scanerror \n";
  73.  
  74. $totalrulecount = 0;
  75.  
  76. # This is like soduku - multiple rules are valid for fields, but in such a way that if you "spend" the rules in the right order, there will only be one rule that is valid excluding the spent fields.
  77.  
  78. while ($totalrulecount < 20) { # If we found the order for all rules, we are done.
  79.  
  80.         @rulecount = ();
  81.         for ($i = 0; $i < 20; $i++) { # Loop through all fields
  82.                 $foundrule = "";
  83.  
  84.                 foreach $rulename (keys %rules) {
  85.                         if ($ruleorder{$rulename} > 0) {
  86.                                 next; # Rule is spent - skip it.
  87.                         }
  88.                         $validrule = 0;
  89.                         ($lowa, $higha, $lowb, $highb) = split("-", $rules{$rulename});
  90.  
  91.                         foreach $validticket (@validtickets) {
  92.                                 @fields = split(",",$validticket);
  93.                                 if (((int($fields[$i]) >= $lowa)&&(int($fields[$i]) <= $higha)) || ((int($fields[$i]) >= $lowb)&&(int($fields[$i]) <= $highb))) {
  94.                                         $validrule++;
  95.                                 }
  96.                         }
  97.  
  98.                         if ($validrule == ($#validtickets + 1)) { # If rule is valid for all tickets, we add it to rulecount.
  99.                                 $rulecount[$i]++;
  100.                                 $foundrule = $rulename;
  101.                         }
  102.                 }
  103.  
  104.                 if ($rulecount[$i] == 1) { # If there is only one rule that is valid for all tickets, not two or more, add it to ruleorder.
  105.                         $ruleorder{$foundrule} = $i + 1;
  106.                         $totalrulecount++;
  107.                 }
  108.         }
  109. }
  110.  
  111. # Add the fields to @ra - in the order as specified by the %ruleorder hash array.
  112.  
  113. for ($i = 1; $i < 21; $i++) {
  114.         foreach $r (keys %ruleorder) {
  115.                 if ($ruleorder{$r} == $i) {
  116.                         push(@ra, $r);
  117.                 }
  118.         }
  119. }
  120.  
  121. @myticketfields = split(",",$myticket);
  122.  
  123. $totalsum = 1;
  124.  
  125. # Multiple all departure fields
  126.  
  127. for ($i = 0; $i < 20; $i++) {
  128.         if ($ra[$i] =~ m/^departure/) {
  129.                 $totalsum = $totalsum * int($myticketfields[$i]);
  130.         }
  131. }
  132.  
  133. print "P2: $totalsum \n";
  134.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement