-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathday08.php
93 lines (74 loc) · 2.29 KB
/
day08.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
<?php
class Vec2 {
public int $x;
public int $y;
function __construct(int $x = 0, int $y = 0) {
$this->x = $x;
$this->y = $y;
}
function __toString(): string {
return "$this->x,$this->y";
}
function inBounds(int $width, int $height): bool {
return $this->x >= 0 && $this->x < $width && $this->y >= 0 && $this->y < $height;
}
function add(Vec2 $rhs): Vec2 {
return new Vec2($this->x + $rhs->x, $this->y + $rhs->y);
}
function sub(Vec2 $rhs): Vec2 {
return new Vec2($this->x - $rhs->x, $this->y - $rhs->y);
}
function scale(int $factor): Vec2 {
return new Vec2($this->x * $factor, $this->y * $factor);
}
}
function findFrequencyLocations(array $matrix, int $width, int $height): array {
$freqLocs = [];
for ($y = 0; $y < $height; $y++) {
for ($x = 0; $x < $width; $x++) {
$cell = $matrix[$y][$x];
if ($cell != '.') {
$freqLocs[$cell] = [...($freqLocs[$cell] ?? []), new Vec2($x, $y)];
}
}
}
return $freqLocs;
}
function findAntinodes(array $freqLocs, int $width, int $height, bool $includeStart = true, int $maxRepeats = PHP_INT_MAX): array {
$antinodes = [];
foreach ($freqLocs as $freq => $locs) {
for ($i = 0; $i < count($locs); $i++) {
for ($j = $i + 1; $j < count($locs); $j++) {
$diff = $locs[$j]->sub($locs[$i]);
foreach ([-1 => $locs[$i], 1 => $locs[$j]] as $dir => $start) {
if ($includeStart) {
$antinodes["$start"] = true;
}
$delta = $diff->scale($dir);
$pos = $start->add($delta);
$k = 0;
while ($k < $maxRepeats && $pos->inBounds($width, $height)) {
$antinodes["$pos"] = true;
$pos = $pos->add($delta);
$k++;
}
}
}
}
}
return $antinodes;
}
if ($argc <= 1) {
echo "Usage: day08 <path to input>" . PHP_EOL;
exit(1);
}
$filePath = $argv[1];
$raw = file_get_contents($filePath);
$matrix = array_slice(preg_split('/\R/', $raw), 0, -1);
$height = count($matrix);
$width = strlen($matrix[0]);
$freqLocs = findFrequencyLocations($matrix, $width, $height);
$part1 = count(findAntinodes($freqLocs, $width, $height, false, 1));
echo "Part 1: $part1" . PHP_EOL;
$part2 = count(findAntinodes($freqLocs, $width, $height));
echo "Part 2: $part2" . PHP_EOL;