-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathd18.R
62 lines (51 loc) · 1.55 KB
/
d18.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
parse_input <- function(f) {
d <- read.csv(file = f, sep = " ", col.names = c("dir", "dist", "col"),
header = FALSE)
d$dist2 <- strtoi(paste0("0x", substring(d$col, 3, 7)))
d$dir2 <- c("R", "D", "L", "U")[1 + as.integer(substring(d$col, 8, 8))]
d
}
part1 <- function(d, p2 = FALSE) {
if (p2) {
d$dist <- d$dist2
d$dir <- d$dir2
}
x <- 1
y <- 1
for (i in seq_len(nrow(d))) {
d$x1[i] <- x
d$y1[i] <- y
y <- y + (((d$dir[i] == "D") - (d$dir[i] == "U")) * d$dist[i])
x <- x + (((d$dir[i] == "R") - (d$dir[i] == "L")) * d$dist[i])
d$x2[i] <- x
d$y2[i] <- y
}
# So I had to do some googling...
# Pick's theorem:
# the area of any simple lattice polygon, A, is found by adding the
# number of interior lattice points, I, to half the number of lattice
# points on the boundary, B, minus 1 ( A = I + B/2 − 1 ).
# The Shoelace algorithm we talked about on day 12 gives us the interior
# lattice points I think, when we are giving it pixels, rather than the
# "outside" perimeter of the pixels.
area <- 0
for (i in seq_len(nrow(d))) {
area <- area + (d$y1[i] * d$x2[i]) - (d$x1[i] * d$y2[i])
}
area <- abs(area) %/% 2
# And then this is the perimeter bit.
area <- area + as.integer((sum(d$dist) / 2) + 1)
area
}
part2 <- function(d) {
format(part1(d, TRUE), digits = 14)
}
test <- function() {
d <- parse_input("../inputs/d18-test.txt")
stopifnot(part1(d) == 62)
stopifnot(part2(d) == 952408144115)
}
test()
d <- parse_input("../inputs/d18-input.txt")
part1(d)
part2(d)