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
//! # Day 9: Sensor Boost
//!
//! You've just said goodbye to the rebooted rover and left Mars when you receive a faint distress
//! signal coming from the asteroid belt. It must be the Ceres monitoring station!
//!
//! In order to lock on to the signal, you'll need to boost your sensors. The Elves send up the
//! latest **BOOST** program - Basic Operation Of System Test.
//!
//! While BOOST (your puzzle input) is capable of boosting your sensors, for tenuous safety reasons,
//! it refuses to do so until the computer it runs on passes some checks to demonstrate it is a
//! **complete Intcode computer**.
//!
//! [Your existing Intcode computer] is missing one key feature: it needs support for parameters in
//! **relative mode**.
//!
//! Parameters in mode `2`, **relative mode**, behave very similarly to parameters in **position
//! mode**: the parameter is interpreted as a position. Like position mode, parameters in relative
//! mode can be read from or written to.
//!
//! The important difference is that relative mode parameters don't count from address `0`. Instead,
//! they count from a value called the **relative base**. The **relative base** starts at `0`.
//!
//! The address a relative mode parameter refers to is itself **plus** the current **relative
//! base**. When the relative base is `0`, relative mode parameters and position mode parameters
//! with the same value refer to the same address.
//!
//! For example, given a relative base of `50`, a relative mode parameter of `-7` refers to memory
//! address `50 + -7 = 43`.
//!
//! The relative base is modified with the **relative base offset** instruction:
//!
//! - Opcode `9` **adjusts the relative base** by the value of its only parameter. The relative base
//! increases (or decreases, if the value is negative) by the value of the parameter.
//!
//! For example, if the relative base is `2000`, then after the instruction `109,19`, the relative
//! base would be `2019`. If the next instruction were `204,-34`, then the value at address `1985`
//! would be output.
//!
//! Your Intcode computer will also need a few other capabilities:
//!
//! - The computer's available memory should be much larger than the initial program. Memory beyond
//! the initial program starts with the value `0` and can be read or written like any other
//! memory. (It is invalid to try to access memory at a negative address, though.)
//! - The computer should have support for large numbers. Some instructions near the beginning of
//! the BOOST program will verify this capability.
//!
//! Here are some example programs that use these features:
//!
//! - `109,1,204,-1,1001,100,1,100,1008,100,16,101,1006,101,0,99` takes no input and produces a
//! [copy of itself] as output.
//! - `1102,34915192,34915192,7,4,7,99,0` should output a 16-digit number.
//! - `104,1125899906842624,99` should output the large number in the middle.
//!
//! The BOOST program will ask for a single input; run it in test mode by providing it the value
//! `1`. It will perform a series of checks on each opcode, output any opcodes (and the associated
//! parameter modes) that seem to be functioning incorrectly, and finally output a BOOST keycode.
//!
//! Once your Intcode computer is fully functional, the BOOST program should report no
//! malfunctioning opcodes when run in test mode; it should only output a single value, the BOOST
//! keycode. **What BOOST keycode does it produce?**
//!
//! [Your existing Intcode computer]: super::d05
//! [copy of itself]: https://en.wikipedia.org/wiki/Quine_(computing)
//!
//! ## Part Two
//!
//! **You now have a complete Intcode computer.**
//!
//! Finally, you can lock on to the Ceres distress signal! You just need to boost your sensors using
//! the BOOST program.
//!
//! The program runs in sensor boost mode by providing the input instruction the value `2`. Once
//! run, it will boost the sensors automatically, but it might take a few seconds to complete the
//! operation on slower hardware. In sensor boost mode, the program will output a single value:
//! **the coordinates of the distress signal**.
//!
//! Run the BOOST program in sensor boost mode. **What are the coordinates of the distress signal?**
use anyhow::Result;
use super::intcode::{self, Program};
pub const INPUT: &str = include_str!("d09.txt");
pub fn solve_part_one(input: &str) -> Result<i64> {
let cmds = intcode::parse_input(input)?;
Program::new(cmds, &[1]).run(&[])
}
pub fn solve_part_two(input: &str) -> Result<i64> {
let cmds = intcode::parse_input(input)?;
Program::new(cmds, &[2]).run(&[])
}
#[cfg(test)]
mod tests {
use super::{super::intcode::tests::input_to_string, *};
#[test]
fn part_one() {
let input = &[109, 1, 204, -1, 1001, 100, 1, 100, 1008, 100, 16, 101, 1006, 101, 0, 99];
assert_eq!(109, solve_part_one(&input_to_string(input)).unwrap());
let input = &[1102, 34_915_192, 34_915_192, 7, 4, 7, 99, 0];
assert_eq!(1_219_070_632_396_864, solve_part_one(&input_to_string(input)).unwrap());
let input = &[104, 1_125_899_906_842_624, 99];
assert_eq!(1_125_899_906_842_624, solve_part_one(&input_to_string(input)).unwrap());
}
#[test]
fn part_two() {}
}