Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- $input = file('input.txt');
- $units = array();
- $attack_units = array();
- $current_type = '';
- foreach ($input as $line) {
- $line = trim($line);
- if ($line !== '') {
- if ($line === 'Immune System:') {
- $current_type = 'immune';
- } elseif ($line === 'Infection:') {
- $current_type = 'infection';
- } else {
- preg_match_all('/(\d+)\sunits.*?(\d+).*?does\s(\d+)\s(.*?)\s.*?initiative\s(\d+)/', $line, $match);
- preg_match_all('/(immune|weak)\sto\s(.*?)[;|\)]/', $line, $match2);
- $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]);
- $immune = array();
- $weak = array();
- for ($i = 0; $i < count($match2[0]); $i++) {
- if ($match2[1][$i] === 'immune') {
- $immune = explode(', ', $match2[2][$i]);
- } elseif ($match2[1][$i] === 'weak') {
- $weak = explode(', ', $match2[2][$i]);
- }
- }
- $units[] = new Unit($current_type, $data, $immune, $weak);
- }
- }
- }
- $backup_units = $units;
- $reindeer = false;
- $boost = 0;
- while (!$reindeer) {
- $units = $backup_units;
- foreach ($units as $key => $unit) {
- $unit->reset();
- if ($unit->unit_type === 'immune') {
- $units[$key]->damage += $boost;
- }
- }
- $both = true;
- while ($both) {
- $attack_units = array();
- usort($units, 'sort_units');
- foreach ($units as $key => $unit) {
- $best_match = null;
- foreach ($units as $key2 => $unit2) {
- if ($unit2->would_deal_damage($unit) !== false) {
- if (($best_match === null || ($unit2->would_deal_damage($unit) > $best_match->would_deal_damage($unit))) && !in_array($unit2, $attack_units)) {
- $best_match = $unit2;
- }
- }
- }
- if ($best_match !== null) {
- $unit->set_attack($best_match);
- $attack_units[] = $best_match;
- }
- }
- usort($units, 'sort_on_initiative');
- $damage = false;
- foreach ($units as $key => $unit) {
- if ($unit->attack()) {
- $damage = true;
- }
- }
- $im = false;
- $in = false;
- foreach ($units as $key => $unit) {
- if ($unit->get_effective_power() <= 0) {
- unset($units[$key]);
- } else {
- if ($unit->unit_type === 'immune') {
- $im = true;
- } elseif ($unit->unit_type === 'infection') {
- $in = true;
- }
- }
- }
- $both = $im && $in;
- if ($damage === false) {
- $both = false;
- }
- if ($in === false && $im === true) {
- $reindeer = true;
- $count2 = 0;
- foreach ($units as $unit) {
- $count2 += $unit->units;
- }
- break;
- }
- }
- if ($boost === 0) {
- $count = 0;
- foreach ($units as $unit) {
- $count += $unit->units;
- }
- printf('Part 1: %d', $count);
- echo PHP_EOL;
- }
- $boost++;
- }
- printf('Part 2: %d', $count2);
- echo PHP_EOL;
- function sort_units(Unit $a, Unit $b)
- {
- if ($a->get_effective_power() === $b->get_effective_power()) {
- return $a->initiative > $b->initiative ? -1 : 1;
- } elseif ($a->get_effective_power() > $b->get_effective_power()) {
- return -1;
- }
- return 1;
- }
- function sort_on_initiative(Unit $a, Unit $b)
- {
- return $a->initiative > $b->initiative ? -1 : 1;
- }
- class Unit
- {
- public $unit_type = '';
- public $units = 0;
- public $hit_points = 0;
- public $damage = 0;
- public $damage_type = '';
- public $initiative = 0;
- public $weakness = array();
- public $immune = array();
- public $attack_unit = null;
- public $org_data = null;
- public function __construct($type, $data, $immune, $weak)
- {
- $this->org_data = $data;
- $this->unit_type = $type;
- $this->units = $data['units'];
- $this->hit_points = $data['hit_points'];
- $this->damage = $data['damage'];
- $this->damage_type = $data['damage_type'];
- $this->initiative = $data['initiative'];
- $this->weakness = $weak;
- $this->immune = $immune;
- }
- public function reset()
- {
- $data = $this->org_data;
- $this->units = $data['units'];
- $this->hit_points = $data['hit_points'];
- $this->damage = $data['damage'];
- $this->damage_type = $data['damage_type'];
- $this->initiative = $data['initiative'];
- }
- public function would_deal_damage(Unit $unit)
- {
- if ($unit->unit_type === $this->unit_type || $this === $unit) {
- return false;
- }
- $power = $unit->get_effective_power();
- if (in_array($unit->damage_type, $this->immune)) {
- return false;
- } elseif (in_array($unit->damage_type, $this->weakness)) {
- $power *= 2;
- }
- return $power;
- }
- public function get_effective_power()
- {
- if ($this->units <= 0) {
- return 0;
- }
- return $this->units * $this->damage;
- }
- public function deal_damage(Unit $unit)
- {
- $power = $this->would_deal_damage($unit);
- $lost_units = floor($power / $this->hit_points);
- if ($lost_units <= 0) {
- return false;
- }
- $this->units -= $lost_units;
- return true;
- }
- public function set_attack(Unit $unit)
- {
- $this->attack_unit = $unit;
- }
- public function attack()
- {
- if ($this->attack_unit !== null) {
- $att = $this->attack_unit->deal_damage($this);
- $this->attack_unit = null;
- return $att;
- }
- return false;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment