[php] AOC day 14 both

Viewer

copydownloadembedprintName: AOC day 14 both
  1. #!/usr/local/bin/php
  2. <?php
  3.  
  4. class DockingData {
  5.     private $data;
  6.  
  7.     public function __construct() {
  8.         $this->data = file(__DIR__.'/input.txt');
  9.         $this->data = array_map('trim', $this->data);
  10.     }
  11.  
  12.     public function part1() : int
  13.     {
  14.         $memory = [];
  15.         $mask = '';
  16.         foreach ($this->data as $line) {
  17.             $l_spl = explode(' = ',$line);
  18.             if(str_starts_with($line, 'mask')) {
  19.                 $mask = $l_spl[1];
  20.             } elseif(str_starts_with($line, 'mem')) {
  21.                 $matches = [];
  22.                 preg_match('/\[([\d]+)\]/', $l_spl[0], $matches);
  23.                 $to_mem = decbin(intval($l_spl[1]));
  24.                 // echo ($to_mem.PHP_EOL);
  25.                 $to_mem = $this->apply_mask($mask, $to_mem);
  26.                 $memory[intval($matches[1])] = bindec($to_mem);
  27.             }
  28.         }
  29.         return array_sum($memory);
  30.     }
  31.  
  32.     private function apply_mask(string $mask, string $value) : string
  33.     {
  34.         // echo("value:  ".str_pad($value,36,'0',STR_PAD_LEFT)."\nmask:   $mask\n");
  35.         $mask_arr = str_split($mask);
  36.         $value_arr = str_split(str_pad($value,36,'0',STR_PAD_LEFT));
  37.         foreach ($mask_arr as $digit => $mask_bit) {
  38.             switch ($mask_bit) {
  39.                 case 'X':
  40.                     break;
  41.                 default: // 1 and 0
  42.                     $value_arr[$digit] = $mask_bit;
  43.                     break;
  44.             }
  45.         }
  46.         // echo ("result: ".implode($value_arr).PHP_EOL);
  47.         return implode($value_arr);
  48.     }
  49.  
  50.     public function part2() : int
  51.     {
  52.         $memory = [];
  53.         $mask = '';
  54.         foreach ($this->data as $line) {
  55.             $l_spl = explode(' = ',$line);
  56.             if(str_starts_with($line, 'mask')) {
  57.                 $mask = $l_spl[1];
  58.             } elseif(str_starts_with($line, 'mem')) {
  59.                 $matches = [];
  60.                 preg_match('/\[([\d]+)\]/', $l_spl[0], $matches);
  61.                 $to_mem = intval($l_spl[1]);
  62.                 // echo ($to_mem.PHP_EOL);
  63.                 $addresses = $this->get_mask_possibilities($mask, decbin($matches[1]));
  64.                 foreach ($addresses as $address) {
  65.                     $memory[$address] = $to_mem;
  66.                 }
  67.             }
  68.         }
  69.         return array_sum($memory);
  70.     }
  71.  
  72.     private function get_mask_possibilities(string $mask, string $value) : array
  73.     {
  74.         // echo("address: ".str_pad($value,36,'0',STR_PAD_LEFT)."\nmask:    $mask\n");
  75.         $mask_arr = str_split($mask);
  76.         $value_arr = str_split(str_pad($value,36,'0',STR_PAD_LEFT));
  77.         $num_floating = 0;
  78.         foreach ($mask_arr as $digit => $mask_bit) {
  79.             switch ($mask_bit) {
  80.                 case '0':
  81.                     break;
  82.                 case '1':
  83.                     $value_arr[$digit] = $mask_bit;
  84.                     break;
  85.                 case 'X':
  86.                     $value_arr[$digit] = 'X';
  87.                     $num_floating += 1;
  88.                     break;
  89.             }
  90.         }
  91.         $num_possibilities = bindec(str_pad('', $num_floating, '1'));
  92.         $result = [];
  93.         foreach (range(0,$num_possibilities) as $digits) {
  94.             $digits_arr = str_split(str_pad(decbin($digits),$num_floating,'0',STR_PAD_LEFT));
  95.             $value_arr_copy_str = implode($value_arr);
  96.             foreach ($digits_arr as $digit) {
  97.                 $pos = strpos($value_arr_copy_str, 'X');
  98.                 if ($pos !== false) {
  99.                     $value_arr_copy_str = substr_replace($value_arr_copy_str, $digit, $pos, 1);
  100.                 } else {
  101.                     die('FUCK');
  102.                 }
  103.             }
  104.             // echo ("result:  ".$value_arr_copy_str." (decimal ".bindec($value_arr_copy_str).")".PHP_EOL);
  105.             $result[] = bindec($value_arr_copy_str);
  106.         }
  107.         // echo(PHP_EOL);
  108.         return $result;
  109.     }
  110. }
  111.  
  112. $rr = new DockingData();
  113. $part1 = $rr->part1();
  114. echo("Part 1: $part1\n");
  115. $part2 = $rr->part2();
  116. echo("Part 2: $part2\n");

Editor

You can edit this paste and save as new:


File Description
  • AOC day 14 both
  • Paste Code
  • 14 Dec-2020
  • 4.02 Kb
You can Share it: