179 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			179 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
 | 
						|
$seats = explode("\n", file_get_contents('input.txt'));
 | 
						|
 | 
						|
array_walk($seats, static function(&$seat) {
 | 
						|
    $seat = str_split($seat);
 | 
						|
});
 | 
						|
 | 
						|
function checkAdjacentSeats($seats, $row, $col)
 | 
						|
{
 | 
						|
    $adjacent_seats = [
 | 
						|
        'L' => 0,
 | 
						|
        '.' => 0,
 | 
						|
        '#' => 0,
 | 
						|
    ];
 | 
						|
    // count left
 | 
						|
    $i = $col - 1;
 | 
						|
    while ($i >= 0) {
 | 
						|
        $new_seat = $seats[$row][$i];
 | 
						|
        $adjacent_seats[$new_seat]++;
 | 
						|
        if ('.' !== $new_seat) {
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        $i--;
 | 
						|
    }
 | 
						|
    // count up
 | 
						|
    $i = $row - 1;
 | 
						|
    while ($i >= 0) {
 | 
						|
        $new_seat = $seats[$i][$col];
 | 
						|
        $adjacent_seats[$new_seat]++;
 | 
						|
        if ('.' !== $new_seat) {
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        $i--;
 | 
						|
    }
 | 
						|
    // count right
 | 
						|
    $i = $col + 1;
 | 
						|
    while ($i < count($seats[$row])) {
 | 
						|
        $new_seat = $seats[$row][$i];
 | 
						|
        $adjacent_seats[$new_seat]++;
 | 
						|
        if ('.' !== $new_seat) {
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        $i++;
 | 
						|
    }
 | 
						|
    // count bottom
 | 
						|
    $i = $row + 1;
 | 
						|
    while ($i < count($seats)) {
 | 
						|
        $new_seat = $seats[$i][$col];
 | 
						|
        $adjacent_seats[$new_seat]++;
 | 
						|
        if ('.' !== $new_seat) {
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        $i++;
 | 
						|
    }
 | 
						|
    // diag up left
 | 
						|
    $i = $row - 1;
 | 
						|
    $j = $col - 1;
 | 
						|
    while (array_key_exists($i, $seats) && array_key_exists($j, $seats[$i])) {
 | 
						|
        $new_seat = $seats[$i][$j];
 | 
						|
        $adjacent_seats[$new_seat]++;
 | 
						|
        if ('.' !== $new_seat) {
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        $i--;
 | 
						|
        $j--;
 | 
						|
    }
 | 
						|
    // diag up right
 | 
						|
    $i = $row - 1;
 | 
						|
    $j = $col + 1;
 | 
						|
    while (array_key_exists($i, $seats) && array_key_exists($j, $seats[$i])) {
 | 
						|
        $new_seat = $seats[$i][$j];
 | 
						|
        $adjacent_seats[$new_seat]++;
 | 
						|
        if ('.' !== $new_seat) {
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        $i--;
 | 
						|
        $j++;
 | 
						|
    }
 | 
						|
    // diag bottom right
 | 
						|
    $i = $row + 1;
 | 
						|
    $j = $col + 1;
 | 
						|
    while (array_key_exists($i, $seats) && array_key_exists($j, $seats[$i])) {
 | 
						|
        $new_seat = $seats[$i][$j];
 | 
						|
        $adjacent_seats[$new_seat]++;
 | 
						|
        if ('.' !== $new_seat) {
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        $i++;
 | 
						|
        $j++;
 | 
						|
    }
 | 
						|
    // diag bottom left
 | 
						|
    $i = $row + 1;
 | 
						|
    $j = $col - 1;
 | 
						|
    while (array_key_exists($i, $seats) && array_key_exists($j, $seats[$i])) {
 | 
						|
        $new_seat = $seats[$i][$j];
 | 
						|
        $adjacent_seats[$new_seat]++;
 | 
						|
        if ('.' !== $new_seat) {
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        $i++;
 | 
						|
        $j--;
 | 
						|
    }
 | 
						|
 | 
						|
    return $adjacent_seats;
 | 
						|
}
 | 
						|
 | 
						|
function makeARound($seats)
 | 
						|
{
 | 
						|
    $new_seats = $seats;
 | 
						|
    for ($row = 0, $row_count = count($seats); $row < $row_count; $row++) {
 | 
						|
        for ($col = 0, $col_count = count($seats[0]); $col < $col_count; $col++) {
 | 
						|
            $current = $seats[$row][$col];
 | 
						|
            if ('.' === $current) {
 | 
						|
                continue;
 | 
						|
            }
 | 
						|
 | 
						|
            $adjacent_seats = checkAdjacentSeats($seats, $row, $col);
 | 
						|
            if ('L' === $current) {
 | 
						|
                // check adjacent seat, if all empty => it becomes # else nothing
 | 
						|
                if ($adjacent_seats['#'] === 0) {
 | 
						|
                    $new_seats[$row][$col] = '#';
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            if ('#' === $current) {
 | 
						|
                // check adjacent seat, if count # >= 4 => it becomes L else nothing
 | 
						|
                if ($adjacent_seats['#'] >= 5) {
 | 
						|
                    $new_seats[$row][$col] = 'L';
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
    return $new_seats;
 | 
						|
}
 | 
						|
 | 
						|
function countOccupiedSeats($seats)
 | 
						|
{
 | 
						|
    $occupied_seats_count = 0;
 | 
						|
    foreach ($seats as $row) {
 | 
						|
        $row_values = array_count_values($row);
 | 
						|
        $occupied_seats_count += array_key_exists('#', $row_values) ? $row_values['#'] : 0;
 | 
						|
    }
 | 
						|
    return $occupied_seats_count;
 | 
						|
}
 | 
						|
 | 
						|
function seatsAreIdentical($seats, $new_seats)
 | 
						|
{
 | 
						|
    foreach ($seats as $row_i => $row) {
 | 
						|
        foreach ($row as $cell_i => $cell) {
 | 
						|
            if ($new_seats[$row_i][$cell_i] !== $cell) {
 | 
						|
                return false;
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
function displaySeats($seats)
 | 
						|
{
 | 
						|
    foreach ($seats as $row) {
 | 
						|
        echo implode('', $row). "\n";
 | 
						|
    }
 | 
						|
    echo str_repeat('=', count($seats[0]))."\n";
 | 
						|
}
 | 
						|
 | 
						|
$new_seats = [];
 | 
						|
$count_loop = 0;
 | 
						|
while (true) {
 | 
						|
    $new_seats = makeARound($seats);
 | 
						|
    if (seatsAreIdentical($seats, $new_seats)) {
 | 
						|
        echo sprintf('%u occupied seats found in %u round', countOccupiedSeats($new_seats), $count_loop);
 | 
						|
        exit;
 | 
						|
    }
 | 
						|
    $seats = $new_seats;
 | 
						|
    $count_loop++;
 | 
						|
}
 |