-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcrabs.php
executable file
·81 lines (66 loc) · 1.44 KB
/
crabs.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
#!/usr/bin/php
<?php
function calc_p1(&$count, $dest) {
$cost = 0;
foreach($count as $pos => $val) {
$cost += $val * abs($dest - $pos);
}
return $cost;
}
function calc_p2(&$count, $dest) {
$cost = 0;
foreach($count as $pos => $val) {
$dist = abs($dest - $pos);
$cost += $val * ($dist * ($dist + 1) / 2);
}
return $cost;
}
$count = [];
$positions = [];
while(($line = fgets(STDIN)) !== false) {
foreach(explode(',', trim($line)) as $num) {
if(!isset($count[$num]))
$count[$num] = 1;
else
++$count[$num];
$positions[] = $num;
}
}
// Part1: move to median
sort($positions);
if(count($positions) % 2) {
$index = (int)(count($positions) / 2);
$cost = calc_cost($count, $positions[$index]);
} else {
$i1 = (int)(count($positions) / 2);
$c1 = calc_p1($count, $positions[$i1]);
$i2 = $i1 + 1;
$c2 = calc_p1($count, $positions[$i2]);
if($c1 < $c2) {
$index = $i1;
$cost = $c1;
} else {
$index = $i2;
$cost = $c2;
}
}
echo "Part1: move to {$positions[$index]} at cost of {$cost}\n";
// Part2: move to average
$sum = 0;
$total = 0;
foreach($count as $pos => $val) {
$sum += ($pos * $val);
$total += $val;
}
$best_pos = null;
$best_cost = PHP_INT_MAX;
$average = round($sum / $total);
for($offset = -1; $offset <= +1; ++$offset) {
$pos = $average + $offset;
$cost = calc_p2($count, $pos);
if($cost < $best_cost) {
$best_cost = $cost;
$best_pos = $pos;
}
}
echo "Part2: move to {$best_pos} at cost of {$best_cost}\n";