1
0
Fork 0
advent-of-code/2020/day11.php

127 lines
2.7 KiB
PHP
Raw Permalink Normal View History

2024-02-08 09:55:40 +01:00
<?php
$input_file = '../inputs/day11.txt';
if (file_exists($input_file)) {
$input = file_get_contents($input_file);
if ($input != null) {
$rows = array_map('trim', explode("\n", $input));
print 'Part 1 answer: ' . solve($rows, false) . "\n";
print 'Part 2 answer: ' . solve($rows, true) . "\n";
}
}
function solve(array $rows, bool $moreTolerant): int
{
$changed = true;
$occupied = 0;
$newState = $rows;
while ($changed) {
$simulation_result = simulate($newState, $moreTolerant);
$changed = $simulation_result->changed;
$occupied = $simulation_result->full;
$newState = $simulation_result->state;
}
return $occupied;
}
function simulate(array $rows, bool $moreTolerant): day11_state
{
$newState = $rows;
$changed = false;
$empty = 0;
$floor = 0;
$full = 0;
for ($i = 0; $i < count($rows); $i++) {
for ($j = 0; $j < strlen($rows[$i]); $j++) {
$adjacent_occupied = get_adjacent_occupied($moreTolerant, $rows, $i, $j);
if ($rows[$i][$j] === 'L' && $adjacent_occupied === 0) {
$changed = true;
$full += 1;
$newState[$i][$j] = '#';
} elseif ($rows[$i][$j] === '#' && $adjacent_occupied >= ($moreTolerant ? 5 : 4)) {
$changed = true;
$empty += 1;
$newState[$i][$j] = 'L';
} else {
if ($rows[$i][$j] === 'L')
$empty += 1;
elseif ($rows[$i][$j] === '#')
$full += 1;
else
$floor += 1;
}
}
}
return new day11_state($newState, $changed, $empty, $floor, $full);
}
function get_adjacent_occupied(bool $moreTolerant, array $state, int $y, int $x): int
{
$occupied = 0;
if ($moreTolerant === false) {
for ($i = $y - 1; $i < $y + 2; $i++) {
if ($i >= 0 && $i < count($state)) {
for ($j = $x - 1; $j < $x + 2; $j++) {
if ($j >= 0 && $j < strlen($state[$i]) && !($i === $y && $j === $x)) {
$occupied += $state[$i][$j] === '#' ? 1 : 0;
}
}
}
}
} else {
$x_dir = -1;
$y_dir = -1;
while (true) {
$x_pos = $x;
$y_pos = $y;
while (true) {
if ($x_dir === 0 && $y_dir === 0)
break;
$x_pos += $x_dir;
$y_pos += $y_dir;
if ($y_pos < 0 || $y_pos >= count($state) || $x_pos < 0 || $x_pos >= strlen($state[$y_pos]))
break;
elseif ($state[$y_pos][$x_pos] === '.')
continue;
else {
$occupied += $state[$y_pos][$x_pos] === '#';
break;
}
}
$y_dir += 1;
if ($y_dir == 2) {
$y_dir = -1;
$x_dir += 1;
}
if ($x_dir == 2)
break;
}
}
return $occupied;
}
class day11_state
{
public array $state;
public bool $changed;
public int $empty;
public int $floor;
public int $full;
function __construct(array $state, bool $changed, int $empty, int $floor, int $full)
{
$this->state = $state;
$this->changed = $changed;
$this->empty = $empty;
$this->floor = $floor;
$this->full = $full;
}
}