[php] AOC day 16 part 2

Viewer

copydownloadembedprintName: AOC day 16 part 2
  1. #!/usr/local/bin/php
  2. <?php
  3.  
  4. class TicketTranslation {
  5.     public $fields;
  6.     public $my_ticket;
  7.     public $nearby_tickets;
  8.  
  9.     public function __construct() {
  10.         $file = file_get_contents(__DIR__.'/input.txt');
  11.         [$fields, $my_ticket, $nearby_tickets] = explode("\n\n", $file);
  12.  
  13.         $this->fields = [];
  14.         foreach (explode("\n", $fields) as $field) {
  15.             $matches = [];
  16.             // [name]: [n]-[n] or [n]-[n]
  17.             preg_match('/^([\w ]+): ([\d]+)-([\d]+) or ([\d]+)-([\d]+)/', $field, $matches);
  18.             $this->fields[] = [
  19.                 'name' => $matches[1],
  20.                 'ranges' => [
  21.                     [
  22.                         'from' => $matches[2],
  23.                         'to' => $matches[3],
  24.                     ],
  25.                     [
  26.                         'from' => $matches[4],
  27.                         'to' => $matches[5],
  28.                     ],
  29.                 ]
  30.             ];
  31.         }
  32.  
  33.         $my_ticket = explode("\n", $my_ticket)[1];
  34.         $this->my_ticket = explode(',', $my_ticket);
  35.  
  36.         $nearby_tickets = explode("\n", $nearby_tickets);
  37.         $nearby_tickets = array_splice($nearby_tickets, 1);
  38.         $this->nearby_tickets = [];
  39.         foreach ($nearby_tickets as $ticket) {
  40.             $this->nearby_tickets[] = explode(',', $ticket);
  41.         }
  42.     }
  43.  
  44.     public function part1_amended() : int
  45.     {
  46.         $error_rate = 0;
  47.         foreach($this->nearby_tickets as $key => $ticket) {
  48.             $valid_ticket = true;
  49.             foreach ($ticket as $value) {
  50.                 $valid_val = false;
  51.                 foreach ($this->fields as $field) {
  52.                     if ($this->valid_field($value, $field)) {
  53.                         $valid_val = true;
  54.                     }
  55.                 }
  56.                 if (!$valid_val) {
  57.                     $error_rate += $value;
  58.                     $valid_ticket = false;
  59.                 }
  60.             }
  61.             if (!$valid_ticket) {
  62.                 unset($this->nearby_tickets[$key]);
  63.             }
  64.         }
  65.         return $error_rate;
  66.     }
  67.  
  68.     private function valid_field($value, $field) : bool
  69.     {
  70.         $result = false;
  71.         foreach ($field['ranges'] as $range) {
  72.             if ($range['from'] <= $value && $value <= $range['to']) {
  73.                 $result = true;
  74.             }
  75.         }
  76.         return $result;
  77.     }
  78.  
  79.     public function part2() : int
  80.     {
  81.         $avail_fields = $this->fields;
  82.         $known_fields = [];
  83.         while (sizeof($avail_fields) > 0) {
  84.             for ($i=0; $i < sizeof($this->nearby_tickets[0]); $i++) {
  85.                 $fields = $avail_fields;
  86.                 foreach ($this->nearby_tickets as $ticket) {
  87.                     // $ticket[i]
  88.                     $new_fields = [];
  89.                     foreach ($fields as $field) {
  90.                         if ($this->valid_field($ticket[$i],$field)) {
  91.                             $new_fields[] = $field;
  92.                         }
  93.                     }
  94.                     $fields = $new_fields;
  95.                 }
  96.                 if (sizeof($fields) == 1) {
  97.                     $known_fields[$i] = $fields[0]['name'];
  98.                     $pos = array_search($fields[0], $avail_fields, true);
  99.                     unset($avail_fields[$pos]);
  100.                 }
  101.             }
  102.         }
  103.  
  104.         $result = 1;
  105.         foreach ($known_fields as $col => $name) {
  106.             if (str_starts_with($name, 'departure')) {
  107.                 $result *= $this->my_ticket[$col];
  108.             }
  109.         }
  110.         return $result;
  111.     }
  112. }
  113.  
  114. $tt = new TicketTranslation();
  115. $part1 = $tt->part1_amended();
  116. $part2 = $tt->part2();
  117. echo("Part 2: $part2\n");

Editor

You can edit this paste and save as new:


File Description
  • AOC day 16 part 2
  • Paste Code
  • 17 Dec-2020
  • 3.69 Kb
You can Share it: