-
Notifications
You must be signed in to change notification settings - Fork 0
/
day15_pt1.R
146 lines (120 loc) · 3.88 KB
/
day15_pt1.R
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
## PART 1 ----------------------------------------------------------------------
# day15 <- readLines("inputs/day15_ex.txt")
day15 <- readLines("inputs/day15.txt")
tic <- Sys.time()
sensors <- stringr::str_match(day15, "at\\s*(.*?)\\s*:")[ ,2]
sensors <- lapply(strsplit(sensors, ","), function(x) as.numeric(gsub("[^-0-9]", "", x)))
beacons <- stringr::str_match(day15, "is at\\s*(.*?)\\s*$")[ ,2]
beacons <- lapply(strsplit(beacons, ","), function(x) as.numeric(gsub("[^-0-9]", "", x)))
# row of interest
# roi <- 10 # example
roi <- 2000000
# Save start and end values of streaks where there are definitely no beacons
no_beacon <- list()
for (sensor in seq_along(sensors)) {
# Distance between sensor and beacon
distance <- sum(abs(sensors[[sensor]] - beacons[[sensor]]))
# min and max row this sensor covers
min_row <- sensors[[sensor]][2] - distance
max_row <- sensors[[sensor]][2] + distance
# Does this sensor cover our roi?
if (roi >= min_row & roi <= max_row) {
# Calculate how many fields the sensor covers at roi.
# Distance to sensor mid row
mid_distance <- abs(sensors[[sensor]][2] - roi)
start_width <- sensors[[sensor]][1] - (distance - mid_distance)
end_width <- sensors[[sensor]][1] + (distance - mid_distance)
# We need to keep track of whether we can merge together previous
# start/end values.
value_adjusted <- FALSE
for (i in seq_along(no_beacon)) {
if (
start_width < no_beacon[[i]][1] &
end_width < no_beacon[[i]][1]
) {
value_adjusted <- FALSE
} else if (
start_width > no_beacon[[i]][2] &
end_width > no_beacon[[i]][2]
) {
value_adjusted <- FALSE
} else if (
start_width <= no_beacon[[i]][1] &
end_width >= no_beacon[[i]][2]
) {
no_beacon[[i]][1] <- start_width
no_beacon[[i]][2] <- end_width
value_adjusted <- TRUE
} else if (
start_width <= no_beacon[[i]][1] &
end_width <= no_beacon[[i]][2]
) {
no_beacon[[i]][1] <- start_width
value_adjusted <- TRUE
} else if (
start_width >= no_beacon[[i]][1] &
end_width >= no_beacon[[i]][2]
) {
no_beacon[[i]][2] <- end_width
value_adjusted <- TRUE
}
}
# If no connection to previous start/end values, safe as new value pair
if (!value_adjusted) {
no_beacon[[length(no_beacon) + 1]] <- c(start_width, end_width)
}
}
}
# Merge overlaps
for (i in seq_along(no_beacon)) {
start_width <- no_beacon[[i]][1]
end_width <- no_beacon[[i]][2]
for (j in seq_along(no_beacon)) {
if (
start_width < no_beacon[[j]][1] &
end_width < no_beacon[[j]][1]
) {
next
} else if (
start_width > no_beacon[[j]][2] &
end_width > no_beacon[[j]][2]
) {
next
} else if (
start_width <= no_beacon[[j]][1] &
end_width >= no_beacon[[j]][2]
) {
no_beacon[[j]][1] <- start_width
no_beacon[[j]][2] <- end_width
} else if (
start_width <= no_beacon[[j]][1] &
end_width <= no_beacon[[j]][2]
) {
no_beacon[[j]][1] <- start_width
} else if (
start_width >= no_beacon[[j]][1] &
end_width >= no_beacon[[j]][2]
) {
no_beacon[[j]][2] <- end_width
}
}
}
no_beacon <- unique(no_beacon)
# Remove all known beacon positions from the list
# Which are in the roi?
boi <- unique(beacons[sapply(beacons, function(x) x[2] == roi)])
beacons_to_exlude <- 0
for (i in seq_along(boi)) {
beacons_to_exlude <-
beacons_to_exlude +
any(sapply(no_beacon, function(x) boi[[i]][1] >= x[1] & boi[[i]][1] <= x[2]))
}
# Count positions where there definitely is no beacon
n_no_beacon <- 0
for (i in seq_along(no_beacon)) {
n_no_beacon <- n_no_beacon + diff(no_beacon[[i]]) + 1
}
# Exclude know beacons
n_no_beacon - beacons_to_exlude
# 5125700
Sys.time() - tic