Guest User

Untitled

a guest
Dec 24th, 2018
49
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 6.18 KB | None | 0 0
  1. <?php
  2. $input = file('input.txt');
  3.  
  4. $units = array();
  5. $attack_units = array();
  6.  
  7. $current_type = '';
  8.  
  9. foreach ($input as $line) {
  10.     $line = trim($line);
  11.  
  12.     if ($line !== '') {
  13.  
  14.         if ($line === 'Immune System:') {
  15.             $current_type = 'immune';
  16.         } elseif ($line === 'Infection:') {
  17.             $current_type = 'infection';
  18.         } else {
  19.             preg_match_all('/(\d+)\sunits.*?(\d+).*?does\s(\d+)\s(.*?)\s.*?initiative\s(\d+)/', $line, $match);
  20.             preg_match_all('/(immune|weak)\sto\s(.*?)[;|\)]/', $line, $match2);
  21.  
  22.  
  23.             $data = array('units' => (int)$match[1][0], 'hit_points' => (int)$match[2][0], 'damage' => (int)$match[3][0], 'damage_type' => trim($match[4][0]), 'initiative' => (int)$match[5][0]);
  24.  
  25.  
  26.             $immune = array();
  27.             $weak = array();
  28.  
  29.             for ($i = 0; $i < count($match2[0]); $i++) {
  30.                 if ($match2[1][$i] === 'immune') {
  31.                     $immune = explode(', ', $match2[2][$i]);
  32.                 } elseif ($match2[1][$i] === 'weak') {
  33.                     $weak = explode(', ', $match2[2][$i]);
  34.                 }
  35.             }
  36.  
  37.             $units[] = new Unit($current_type, $data, $immune, $weak);
  38.         }
  39.     }
  40. }
  41.  
  42. $backup_units = $units;
  43. $reindeer = false;
  44. $boost = 0;
  45.  
  46. while (!$reindeer) {
  47.  
  48.     $units = $backup_units;
  49.  
  50.     foreach ($units as $key => $unit) {
  51.         $unit->reset();
  52.         if ($unit->unit_type === 'immune') {
  53.             $units[$key]->damage += $boost;
  54.         }
  55.     }
  56.     $both = true;
  57.  
  58.     while ($both) {
  59.  
  60.         $attack_units = array();
  61.  
  62.         usort($units, 'sort_units');
  63.  
  64.         foreach ($units as $key => $unit) {
  65.             $best_match = null;
  66.  
  67.             foreach ($units as $key2 => $unit2) {
  68.                 if ($unit2->would_deal_damage($unit) !== false) {
  69.                     if (($best_match === null || ($unit2->would_deal_damage($unit) > $best_match->would_deal_damage($unit))) && !in_array($unit2, $attack_units)) {
  70.                         $best_match = $unit2;
  71.                     }
  72.                 }
  73.             }
  74.             if ($best_match !== null) {
  75.                 $unit->set_attack($best_match);
  76.                 $attack_units[] = $best_match;
  77.             }
  78.         }
  79.  
  80.         usort($units, 'sort_on_initiative');
  81.  
  82.         $damage = false;
  83.         foreach ($units as $key => $unit) {
  84.             if ($unit->attack()) {
  85.                 $damage = true;
  86.             }
  87.  
  88.         }
  89.  
  90.         $im = false;
  91.         $in = false;
  92.         foreach ($units as $key => $unit) {
  93.             if ($unit->get_effective_power() <= 0) {
  94.                 unset($units[$key]);
  95.             } else {
  96.                 if ($unit->unit_type === 'immune') {
  97.                     $im = true;
  98.                 } elseif ($unit->unit_type === 'infection') {
  99.                     $in = true;
  100.                 }
  101.             }
  102.         }
  103.  
  104.         $both = $im && $in;
  105.  
  106.         if ($damage === false) {
  107.             $both = false;
  108.         }
  109.  
  110.         if ($in === false && $im === true) {
  111.             $reindeer = true;
  112.             $count2 = 0;
  113.             foreach ($units as $unit) {
  114.                 $count2 += $unit->units;
  115.             }
  116.             break;
  117.         }
  118.     }
  119.  
  120.     if ($boost === 0) {
  121.         $count = 0;
  122.         foreach ($units as $unit) {
  123.             $count += $unit->units;
  124.         }
  125.  
  126.         printf('Part 1: %d', $count);
  127.         echo PHP_EOL;
  128.     }
  129.  
  130.     $boost++;
  131. }
  132.  
  133. printf('Part 2: %d', $count2);
  134. echo PHP_EOL;
  135.  
  136.  
  137. function sort_units(Unit $a, Unit $b)
  138. {
  139.     if ($a->get_effective_power() === $b->get_effective_power()) {
  140.         return $a->initiative > $b->initiative ? -1 : 1;
  141.     } elseif ($a->get_effective_power() > $b->get_effective_power()) {
  142.         return -1;
  143.     }
  144.     return 1;
  145. }
  146.  
  147. function sort_on_initiative(Unit $a, Unit $b)
  148. {
  149.     return $a->initiative > $b->initiative ? -1 : 1;
  150. }
  151.  
  152. class Unit
  153. {
  154.  
  155.     public $unit_type = '';
  156.     public $units = 0;
  157.     public $hit_points = 0;
  158.     public $damage = 0;
  159.     public $damage_type = '';
  160.     public $initiative = 0;
  161.     public $weakness = array();
  162.     public $immune = array();
  163.  
  164.     public $attack_unit = null;
  165.  
  166.     public $org_data = null;
  167.  
  168.     public function __construct($type, $data, $immune, $weak)
  169.     {
  170.         $this->org_data = $data;
  171.  
  172.         $this->unit_type = $type;
  173.         $this->units = $data['units'];
  174.         $this->hit_points = $data['hit_points'];
  175.         $this->damage = $data['damage'];
  176.         $this->damage_type = $data['damage_type'];
  177.         $this->initiative = $data['initiative'];
  178.  
  179.         $this->weakness = $weak;
  180.         $this->immune = $immune;
  181.     }
  182.  
  183.     public function reset()
  184.     {
  185.         $data = $this->org_data;
  186.         $this->units = $data['units'];
  187.         $this->hit_points = $data['hit_points'];
  188.         $this->damage = $data['damage'];
  189.         $this->damage_type = $data['damage_type'];
  190.         $this->initiative = $data['initiative'];
  191.     }
  192.  
  193.     public function would_deal_damage(Unit $unit)
  194.     {
  195.         if ($unit->unit_type === $this->unit_type || $this === $unit) {
  196.             return false;
  197.         }
  198.  
  199.         $power = $unit->get_effective_power();
  200.  
  201.         if (in_array($unit->damage_type, $this->immune)) {
  202.             return false;
  203.         } elseif (in_array($unit->damage_type, $this->weakness)) {
  204.             $power *= 2;
  205.         }
  206.  
  207.         return $power;
  208.     }
  209.  
  210.     public function get_effective_power()
  211.     {
  212.         if ($this->units <= 0) {
  213.             return 0;
  214.         }
  215.         return $this->units * $this->damage;
  216.     }
  217.  
  218.     public function deal_damage(Unit $unit)
  219.     {
  220.         $power = $this->would_deal_damage($unit);
  221.         $lost_units = floor($power / $this->hit_points);
  222.         if ($lost_units <= 0) {
  223.             return false;
  224.         }
  225.         $this->units -= $lost_units;
  226.  
  227.         return true;
  228.     }
  229.  
  230.     public function set_attack(Unit $unit)
  231.     {
  232.         $this->attack_unit = $unit;
  233.     }
  234.  
  235.     public function attack()
  236.     {
  237.         if ($this->attack_unit !== null) {
  238.             $att = $this->attack_unit->deal_damage($this);
  239.             $this->attack_unit = null;
  240.             return $att;
  241.         }
  242.         return false;
  243.  
  244.     }
  245. }
Advertisement
Add Comment
Please, Sign In to add comment