2020 Advent of Code solutions in various languages
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

162 lines
4.0 KiB

# --- Day 8: Handheld Halting ---
#
# Your flight to the major airline hub reaches cruising altitude without
# incident. While you consider checking the in-flight menu for one of those
# drinks that come with a little umbrella, you are interrupted by the kid
# sitting next to you.
#
# Their handheld game console won't turn on! They ask if you can take a look.
#
# You narrow the problem down to a strange infinite loop in the boot code
# (your puzzle input) of the device. You should be able to fix it, but first
# you need to be able to run the code in isolation.
#
# The boot code is represented as a text file with one instruction per line of
# text. Each instruction consists of an operation (acc, jmp, or nop) and an
# argument (a signed number like +4 or -20).
#
# acc increases or decreases a single global value called the accumulator by
# the value given in the argument. For example, acc +7 would increase the
# accumulator by 7. The accumulator starts at 0. After an acc instruction,
# the instruction immediately below it is executed next.
# jmp jumps to a new instruction relative to itself. The next instruction to
# execute is found using the argument as an offset from the jmp instruction;
# for example, jmp +2 would skip the next instruction, jmp +1 would
# continue to the instruction immediately below it, and jmp -20 would
# cause the instruction 20 lines above to be executed next.
# nop stands for No OPeration - it does nothing. The instruction immediately
# below it is executed next.
#
# For example, consider the following program:
#
# nop +0
# acc +1
# jmp +4
# acc +3
# jmp -3
# acc -99
# acc +1
# jmp -4
# acc +6
#
# These instructions are visited in this order:
#
# nop +0 | 1
# acc +1 | 2, 8(!)
# jmp +4 | 3
# acc +3 | 6
# jmp -3 | 7
# acc -99 |
# acc +1 | 4
# jmp -4 | 5
# acc +6 |
#
# First, the nop +0 does nothing. Then, the accumulator is increased from
# 0 to 1 (acc +1) and jmp +4 sets the next instruction to the other acc +1
# near the bottom. After it increases the accumulator from 1 to 2, jmp -4
# executes, setting the next instruction to the only acc +3. It sets the
# accumulator to 5, and jmp -3 causes the program to continue back at the
# first acc +1.
#
# This is an infinite loop: with this sequence of jumps, the program will
# run forever. The moment the program tries to run any instruction a second
# time, you know it will never terminate.
#
# Immediately before the program would run an instruction a second time, the
# value in the accumulator is 5.
#
# Run your copy of the boot code. Immediately before any instruction is
# executed a second time, what value is in the accumulator?
library(tidyverse)
input <- "../input/08-01.txt"
read_delim(
file = input,
delim = " ",
col_names = c("instr", "value"),
col_types = "cd"
) %>%
mutate(
visits = 0
) -> asm
curr <- 1
accumulator <- 0
while (all(asm$visits < 2)) {
asm$visits[curr] <- asm$visits[curr] + 1
switch(
asm$instr[curr],
"nop" = curr + 1,
"acc" = curr + 1,
"jmp" = curr + asm[curr,]$value
) -> nxt
if (nxt > nrow(asm)) break
if ((asm$visits[curr] < 2) && (asm$instr[curr] == "acc")) {
accumulator <- accumulator + asm$value[curr]
}
curr <- nxt
}
# 08-02 -------------------------------------------------------------------
read_delim(
file = input,
delim = " ",
col_names = c("instr", "value"),
col_types = "cd"
) %>%
mutate(
visits = 0
) -> asm
orig_program <- asm
for (run in seq_len(nrow(asm))) {
asm <- orig_program
curr <- 1
accumulator <- 0
switch(
asm$instr[run],
"acc" = "acc",
"nop" = "jmp",
"jmp" = "nop"
) -> asm$instr[run]
while (all(asm$visits < 2)) {
asm$visits[curr] <- asm$visits[curr] + 1
switch(
asm$instr[curr],
"acc" = curr + 1,
"nop" = curr + 1,
"jmp" = curr + asm[curr,]$value
) -> nxt
if (nxt > nrow(asm)) break
if ((asm$visits[curr] < 2) && (asm$instr[curr] == "acc")) {
accumulator <- accumulator + asm$value[curr]
}
curr <- nxt
}
if (all(asm$visits < 2)) break
}
accumulator