-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbeacons.php
executable file
·107 lines (87 loc) · 2.31 KB
/
beacons.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
94
95
96
97
98
99
100
101
102
103
104
105
106
#!/usr/bin/php
<?php
class Coordinates {
public int $x;
public int $y;
public function __construct(int $x, int $y) {
$this->x = $x;
$this->y = $y;
}
public function distance(Coordinates $other): int {
return abs($this->x - $other->x) + abs($this->y - $other->y);
}
public function equal(Coordinates $other): bool {
return ($this->x === $other->x) && ($this->y === $other->y);
}
}
class Sensor {
public Coordinates $pos;
public Coordinates $beacon;
public int $distance;
}
function split_string(string $source, string $split): array {
$parts = explode($split, $source);
if(count($parts) !== 2) {
fprintf(STDERR, "Error: invalid input; string \"%s\" not found\n", $split);
die(1);
}
return $parts;
}
function parse_coords(string $str): Coordinates {
[$x, $y] = split_string($str, ", ");
if(!str_starts_with($x, "x=")) {
fprintf(STDERR, "Error: invalid input; expected x= declaration\n");
die(1);
}
$x = intval(substr($x, 2));
if(!str_starts_with($y, "y=")) {
fprintf(STDERR, "Error: invalid input; expected y= declaration\n");
die(1);
}
$y = intval(substr($y, 2));
return new Coordinates($x, $y);
}
function read_input() {
$sensors = [];
while(($line = fgets(STDIN)) !== false) {
$line = trim($line);
if($line === "") continue;
$parts = split_string($line, "Sensor at ");
$line = $parts[1];
[$spos, $bpos] = split_string($line, ": closest beacon is at ");
$s = new Sensor();
$s->pos = parse_coords($spos);
$s->beacon = parse_coords($bpos);
$s->distance = $s->pos->distance($s->beacon);
$sensors[] = $s;
}
return $sensors;
}
# -- read args and input
$sensors = read_input();
$yPos = 2000000;
if(($argc > 1)) $yPos = intval($argv[1]);
# -- script proper
$minX = PHP_INT_MAX;
$maxX = PHP_INT_MIN;
$maxDist = PHP_INT_MIN;
foreach($sensors as $sens) {
if($sens->pos->x < $minX) $minX = $sens->pos->x;
if($sens->pos->x > $maxX) $maxX = $sens->pos->x;
if($sens->distance > $maxDist) $maxDist = $sens->distance;
}
$p1 = 0;
# This is O(n*m), so quite terrible, but eh
for($x = $minX - $maxDist; $x <= $maxX + $maxDist; ++$x) {
$crd = new Coordinates($x, $yPos);
foreach($sensors as $sens) {
if($crd->equal($sens->beacon)) continue 2;
}
foreach($sensors as $sens) {
if($crd->distance($sens->pos) <= $sens->distance) {
++$p1;
break;
}
}
}
echo "Part 1: ", $p1, "\n";