-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsolution.php
executable file
·94 lines (89 loc) · 3.57 KB
/
solution.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
#!/usr/bin/env php
<?php
include("common.php");
$lines = read_input();
$maxx = Amax(Amap($lines, function($l){ return strlen($l); })); $maxy = count($lines);
printf("Longest: x: %d y: %d\n",$maxx, $maxy);
$tracks=A2Dnew($maxx, $maxy, ' ');
$cars=[]; $n=0;
for($y=0;$y<$maxy;$y++){
$line = $lines[$y]; $nline = strlen($line);
for($x=0;$x<$nline;$x++) {
$c = $line[$x];
if($c==='>'||$c==='<'||$c==='v'||$c==='^') {
$cars[]=[$c,[$x,$y],0,$n++];
if($c==='<'||$c==='>')$c='-';
if($c==='v'||$c==='^')$c='|';
}
$tracks[$y][$x]=$c;
}
}
function showCars($label='cars', $cars){ foreach($cars as $k=>$c) printf("%s car %2d: %s\n", $label, $k, ve($c)); }
//showCars("X Initial", $cars);
//showGridZone($tracks,0,0,$maxx, $maxy,1);exit();
function move(array $tracks, array &$cars, int $maxx, int $maxy): array {
static $move=0;
//printf("Move: %d\n", $move);
$c2v=['>'=>[1,0],'<'=>[-1,0],'v'=>[0,1],'^'=>[0,-1]];
$cturns=['/^'=>'>','/<'=>'v','/>'=>'^','/v'=>'<','\\^'=>'<','\\<'=>'^','\\>'=>'v','\\v'=>'>'];
$cturnsLeft =['>'=>'^','^'=>'<','<'=>'v','v'=>'>'];
$cturnsRight=['>'=>'v','v'=>'<','<'=>'^','^'=>'>'];
$g=$tracks;
uasort($cars, function ($c1, $c2) { return (
$c1[1][1] < $c2[1][1] ||
$c1[1][1] === $c2[1][1] &&
$c1[1][0] <= $c2[1][0]
) ? -1 : 1; });
$crashes=[];
foreach($cars as $k=>$c){
if (!isset($cars[$k])) continue;
//printf(" moving car: %d\n",$k);
[$cx, $cy] = $c[1]; [$vx, $vy] = $c2v[$c[0]]; [$nx, $ny] = [$cx+$vx, $cy+$vy];
$mnx = ($nx>=$maxx) ? $maxx-1 : $nx; if($mnx<0)$mnx=0;
$mny = ($ny>=$maxy) ? $maxy-1 : $ny; if($mny<0)$mny=0;
foreach ($cars as $k2 => $car2) {
if( $car2[1][0] === $nx && $car2[1][1] === $ny ){
$g[$mny][$mnx]='x';
$scoords = sprintf("%d,%d", $mnx, $mny);
unset($cars[$k],$cars[$k2]);
$crashes[]=$scoords;
printf(" move: %6d, crash at: %10s, between cars %s\n", $move, $scoords, ve([$k,$k2]));
continue 2;
}
}
$cars[$k][1] = [$nx,$ny]; // update car position
$np = $tracks[$mny][$mnx];
if('+' === $np){
// on intersections
switch($c[2] % 3){
case 0: $cars[$k][0] = $cturnsLeft[$c[0]]; break;
case 2: $cars[$k][0] =$cturnsRight[$c[0]]; break;
}
$cars[$k][2]++;
}
if('\\' === $np || '/' === $np ){
// update car direction on corners
$nc = "{$np}{$c[0]}";
$cars[$k][0] = $cturns[$nc];
}
$g[$mny][$mnx]=$cars[$k][0];
}
//printf("Move: %6d | cars: %s\n", $move, join(' ', Amap($cars, function($c){ return sprintf("%-22s", ve($cars[$k])); })));
//showCars(" Cars after move: {$move}", $cars);
$move++;
return $crashes;
}
//printf("======================= Initial grid: =============================\n"); showGridZone($tracks, 0,0, 0,0, 1);
while(true){
$crashes=move($tracks, $cars, $maxx, $maxy);
if(count($crashes)>0)break;
}
printf("Part 1 answer (first crash coords): %s\n", $crashes[0]);
while(count($cars)>2){
move($tracks, $cars, $maxx, $maxy);
}
if(0===count($cars)){
printf("X All cars crashed.\n");
}else{
printf("Part 2 answer (coords of remaining car) is: %s\n", join(',', array_pop($cars)[1]) );
}