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

141 lines
3.2 KiB
PHP

<?php
$input_file = '../inputs/day12.txt';
if (file_exists($input_file)) {
$input = file_get_contents($input_file);
if ($input != null) {
$instructions = array_map('trim', explode("\n", $input));
print 'Part 1 answer: ' . solve_part_one($instructions) . "\n";
print 'Part 2 answer: ' . solve_part_two($instructions) . "\n";
}
}
function solve_part_one(array $instructions): int
{
$state = new day12_state();
foreach (parse_instructions($instructions) as $instruction) {
$state = move($instruction, $state);
}
return abs($state->v_pos) + abs($state->h_pos);
}
function solve_part_two(array $instructions): int
{
$state = new day12_state();
foreach (parse_instructions($instructions) as $instruction)
$state = move_with_waypoint($instruction, $state);
return abs($state->v_pos) + abs($state->h_pos);
}
function move(array $instruction, day12_state $state): day12_state
{
switch ($instruction[0]) {
case 'N':
$state->v_pos += $instruction[1];
break;
case 'S':
$state->v_pos -= +$instruction[1];
break;
case 'E':
$state->h_pos += $instruction[1];
break;
case 'W':
$state->h_pos -= $instruction[1];
break;
case 'F':
switch ($state->facing_direction % 4) {
case 0:
$state->v_pos += $instruction[1];
break;
case 1:
$state->h_pos += $instruction[1];
break;
case 2:
$state->v_pos -= $instruction[1];
break;
case 3:
$state->h_pos -= $instruction[1];
break;
}
break;
case 'R':
$state->facing_direction += ($instruction[1] / 90);
break;
case 'L':
$state->facing_direction -= ($instruction[1] / 90);
break;
}
if ($state->facing_direction < 0)
$state->facing_direction += 4; // NOT THAT EASY, need to wrap around 0
return $state;
}
function move_with_waypoint(array $instruction, day12_state $state): day12_state
{
switch ($instruction[0]) {
case 'N':
$state->w_v_pos += $instruction[1];
break;
case 'S':
$state->w_v_pos -= +$instruction[1];
break;
case 'E':
$state->w_h_pos += $instruction[1];
break;
case 'W':
$state->w_h_pos -= $instruction[1];
break;
case 'F':
for ($i = 0; $i < $instruction[1]; $i++) {
$state->v_pos += $state->w_v_pos;
$state->h_pos += $state->w_h_pos;
}
break;
case 'R':
for ($i = 0; $i < $instruction[1] / 90; $i++) {
$new_v_pos = -$state->w_h_pos;
$new_h_pos = $state->w_v_pos;
$state->w_v_pos = $new_v_pos;
$state->w_h_pos = $new_h_pos;
}
break;
case 'L':
for ($i = 0; $i < $instruction[1] / 90; $i++) {
$new_v_pos = $state->w_h_pos;
$new_h_pos = -$state->w_v_pos;
$state->w_v_pos = $new_v_pos;
$state->w_h_pos = $new_h_pos;
}
break;
}
return $state;
}
function parse_instructions(array $instructions): array
{
$parsed_instructions = [];
foreach ($instructions as $instruction) {
if (preg_match('/^([NSEWLRF])(\d+)$/', trim($instruction), $matches)) {
[, $inst, $arg] = $matches;
$parsed_instructions[] = [$inst, $arg];
}
}
return $parsed_instructions;
}
class day12_state
{
public int $v_pos = 0;
public int $h_pos = 0;
public int $w_v_pos = 1;
public int $w_h_pos = 10;
public int $facing_direction = 1; // N = 0, E = 1, S = 2, W = 3
}