Skip to content

Commit 397cd06

Browse files
committed
2022 day 15
1 parent d03818b commit 397cd06

File tree

3 files changed

+180
-0
lines changed

3 files changed

+180
-0
lines changed

2022/go/day15/day15.go

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"sort"
7+
"strings"
8+
)
9+
10+
func main() {
11+
input, _ := os.ReadFile("../../input/day15.txt")
12+
sensors := readInput(string(input))
13+
14+
spans, count := spansForY(sensors, 2000000), 0
15+
for _, s := range spans {
16+
count += s.end - s.start
17+
}
18+
19+
fmt.Printf("part1: %v\n", count)
20+
21+
var x, y int
22+
for y = 0; y <= 4000000; y++ {
23+
spans := spansForY(sensors, y)
24+
if len(spans) > 1 {
25+
x = spans[0].end + 1
26+
break
27+
}
28+
}
29+
fmt.Printf("part2: %v\n", x*4000000+y)
30+
}
31+
32+
func spansForY(sensors []sensor, y int) (spans []span) {
33+
for _, s := range sensors {
34+
sbDist, srDist := abs(s.loc.x-s.beacon.x)+abs(s.loc.y-s.beacon.y), abs(s.loc.y-y)
35+
dist := sbDist - srDist
36+
if dist > 0 {
37+
spans = append(spans, span{s.loc.x - dist, s.loc.x + dist})
38+
}
39+
}
40+
return merge(spans)
41+
}
42+
43+
func merge(spans []span) (res []span) {
44+
sort.Sort(byStart(spans))
45+
res = append(res, spans[0])
46+
for _, next := range spans[1:] {
47+
prev := res[len(res)-1]
48+
if prev.end >= next.start-1 {
49+
res[len(res)-1] = span{prev.start, max(prev.end, next.end)}
50+
} else {
51+
res = append(res, next)
52+
}
53+
}
54+
return res
55+
}
56+
57+
func readInput(input string) (res []sensor) {
58+
lines := strings.Split(input, "\n")
59+
for _, l := range lines {
60+
var s sensor
61+
fmt.Sscanf(l, "Sensor at x=%d, y=%d: closest beacon is at x=%d, y=%d",
62+
&s.loc.x, &s.loc.y, &s.beacon.x, &s.beacon.y)
63+
res = append(res, s)
64+
}
65+
return res
66+
}
67+
68+
type span struct{ start, end int }
69+
type sensor struct{ loc, beacon xy }
70+
type xy struct{ x, y int }
71+
type byStart []span
72+
73+
func (a byStart) Len() int { return len(a) }
74+
func (a byStart) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
75+
func (a byStart) Less(i, j int) bool { return a[i].start < a[j].start }
76+
77+
func max(a, b int) int {
78+
if a > b {
79+
return a
80+
}
81+
return b
82+
}
83+
84+
func abs(v int) int {
85+
if v < 0 {
86+
return -v
87+
}
88+
return v
89+
}

2022/input/day15.txt

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
Sensor at x=1555825, y=18926: closest beacon is at x=1498426, y=-85030
2+
Sensor at x=697941, y=3552290: closest beacon is at x=595451, y=3788543
3+
Sensor at x=3997971, y=2461001: closest beacon is at x=3951198, y=2418718
4+
Sensor at x=3818312, y=282332: closest beacon is at x=4823751, y=1061753
5+
Sensor at x=2874142, y=3053631: closest beacon is at x=3074353, y=3516891
6+
Sensor at x=1704479, y=2132468: closest beacon is at x=1749091, y=2000000
7+
Sensor at x=3904910, y=2080560: closest beacon is at x=3951198, y=2418718
8+
Sensor at x=657061, y=3898803: closest beacon is at x=595451, y=3788543
9+
Sensor at x=3084398, y=3751092: closest beacon is at x=3074353, y=3516891
10+
Sensor at x=2582061, y=972407: closest beacon is at x=1749091, y=2000000
11+
Sensor at x=2886721, y=3971936: closest beacon is at x=3074353, y=3516891
12+
Sensor at x=303399, y=548513: closest beacon is at x=-1010425, y=986825
13+
Sensor at x=3426950, y=2290126: closest beacon is at x=3951198, y=2418718
14+
Sensor at x=3132858, y=3592272: closest beacon is at x=3074353, y=3516891
15+
Sensor at x=3773724, y=3751243: closest beacon is at x=3568452, y=3274758
16+
Sensor at x=3987212, y=2416515: closest beacon is at x=3951198, y=2418718
17+
Sensor at x=61559, y=3806326: closest beacon is at x=595451, y=3788543
18+
Sensor at x=2693503, y=2291389: closest beacon is at x=2269881, y=2661753
19+
Sensor at x=3953437, y=2669220: closest beacon is at x=3951198, y=2418718
20+
Sensor at x=763035, y=3997568: closest beacon is at x=595451, y=3788543
21+
Sensor at x=3999814, y=2370103: closest beacon is at x=3951198, y=2418718
22+
Sensor at x=1290383, y=1696257: closest beacon is at x=1749091, y=2000000
23+
Sensor at x=3505508, y=2805537: closest beacon is at x=3568452, y=3274758
24+
Sensor at x=3276207, y=3323122: closest beacon is at x=3568452, y=3274758
25+
Sensor at x=2244609, y=3517499: closest beacon is at x=3074353, y=3516891
26+
Sensor at x=1370860, y=3436382: closest beacon is at x=595451, y=3788543
27+
Sensor at x=3831063, y=3042662: closest beacon is at x=3568452, y=3274758
28+
Sensor at x=551202, y=3971545: closest beacon is at x=595451, y=3788543
29+
Sensor at x=336629, y=2519780: closest beacon is at x=595451, y=3788543
30+
Sensor at x=2033602, y=2882628: closest beacon is at x=2269881, y=2661753
31+
Sensor at x=3939808, y=2478271: closest beacon is at x=3951198, y=2418718
32+
Sensor at x=1958708, y=2370822: closest beacon is at x=1749091, y=2000000
33+
Sensor at x=3039958, y=3574483: closest beacon is at x=3074353, y=3516891

2022/java/Day15.java

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import java.nio.file.*;
2+
import java.util.ArrayList;
3+
import java.util.Arrays;
4+
import java.util.LinkedList;
5+
import java.util.List;
6+
import java.util.regex.Pattern;
7+
import java.util.stream.IntStream;
8+
import java.util.stream.Stream;
9+
10+
class Day15 {
11+
12+
public static void main(String ... args) throws Exception {
13+
var lines = Files.readString(Path.of("../input/day15.txt")).split("\n");
14+
var sensors = Arrays.stream(lines).map(Sensor::parse).toList();
15+
16+
var count = rangesForY(sensors, 2000000).stream().mapToLong(r -> r.end() - r.start()).sum();
17+
System.out.printf("part1: %d\n", count);
18+
19+
var freq = IntStream.range(0, 4000000)
20+
.mapToObj(y -> rangesForY(sensors, y))
21+
.filter(rs -> rs.size() > 1) // find the one hole in the middle, two ranges
22+
.map(rs -> rs.get(0)) // get the first range, location is after it end
23+
.map(r -> (r.end + 1)*4000000+r.y) // calculate the frequency
24+
.findFirst().get();
25+
26+
System.out.printf("part2: %d\n", freq);
27+
}
28+
29+
static List<Range> rangesForY(List<Sensor> sensors, int y) {
30+
var ranges = sensors.stream().flatMap(s -> {
31+
var beaconDist = Math.abs(s.loc.x - s.beacon.x) + Math.abs(s.loc.y - s.beacon.y);
32+
var dist = beaconDist - Math.abs(s.loc.y - y); // x distance for this sensor for this y
33+
return dist > 0 ? Stream.of(new Range(s.loc.x - dist, s.loc.x + dist, y)) : Stream.of();
34+
}).sorted((a,b) -> (int) (a.start()-b.start())).toList(); // sorted ranges
35+
// merge adjoining or overlapping ranges
36+
LinkedList<Range> res = new LinkedList<>(List.of(ranges.get(0)));
37+
for (var next : ranges.subList(1, ranges.size())) {
38+
var prev = res.getLast();
39+
if (prev.end() >= next.start() - 1) {
40+
res.removeLast();
41+
res.add(new Range(prev.start(), Math.max(prev.end(), next.end()), y));
42+
} else {
43+
res.add(next);
44+
}
45+
}
46+
return res;
47+
}
48+
49+
record Range (long start, long end, long y) {}
50+
record XY(long x, long y) {}
51+
record Sensor(XY loc, XY beacon) {
52+
static Sensor parse(String line) {
53+
var m = Pattern.compile("=(-?\\d+)").matcher(line);
54+
var ns = m.results().mapToInt(r -> Integer.parseInt(r.group(1))).toArray();
55+
return new Sensor(new XY(ns[0], ns[1]), new XY(ns[2], ns[3]));
56+
}
57+
}
58+
}

0 commit comments

Comments
 (0)