-
Notifications
You must be signed in to change notification settings - Fork 0
/
d23.R
64 lines (53 loc) · 1.68 KB
/
d23.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
prog <- read.csv(text = gsub("inc ","inc z ",gsub("dec ", "dec z ",
readLines("../AtariBasic/d23/INPUT.TXT"))), sep = " ", header = FALSE,
col.names = c("op", "arg1", "arg2"))
trans <- data.frame(op1 = c("inc", "dec", "jnz", "cpy", "tgl"),
op2 = c("dec", "inc", "cpy", "jnz", "inc"))
solve <- function(part2 = FALSE, init_a = 7L) {
intish <- function(i) {
!is.na(suppressWarnings(as.integer(i)))
}
inc <- function(b, x, y, delta = 1L) {
b[[y]] <- b[[y]] + delta
b$pc <- b$pc + 1L
b
}
dec <- function(b, x, y) {
inc(b, x, y, -1L)
}
jnz <- function(b, x, y) {
b$pc <- b$pc + ifelse(ifelse(intish(x), as.integer(x), b[[x]]) != 0L,
ifelse(intish(y), as.integer(y), b[[y]]), 1L)
b
}
cpy <- function(b, x, y) {
if (!intish(y)) {
b[[y]] <- ifelse(intish(x), as.integer(x), b[[x]])
}
b$pc <- b$pc + 1L
b
}
tgl <- function(p, b, x) {
adr <- b$pc + ifelse(intish(x), as.integer(x), b[[x]])
if (adr > nrow(p)) {
return(p)
}
p$op[adr] <- trans$op2[trans$op1 == p$op[adr]]
p
}
bunny <- list(pc = 1L, a = init_a, b = 0L, c = ifelse(part2, 1L, 0L), d = 0L)
while (bunny$pc <= nrow(prog)) {
line <- prog[bunny$pc, ]
#message(sprintf("%s %s %s", line$op, line$arg1, line$arg2))
if (line$op == "tgl") {
prog <- tgl(prog, bunny, line$arg1)
bunny$pc <- bunny$pc + 1
} else {
bunny <- do.call(line$op, list(b = bunny, x = line$arg1, y = line$arg2))
}
}
bunny$a
}
# See readme for the Atari part 2 for breakdown
c(solve(), as.integer(factorial(12)) +
(as.integer(prog$arg1[20]) * as.integer(prog$arg1[21])))