aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar alecdwm 2019-12-05 15:19:12 +1000
committerGravatar alecdwm 2019-12-05 15:19:30 +1000
commit4c1be48b087358c8b5095ad67881b9c233e24125 (patch)
treeabd77d1c6a695e433d133f98a07f1e3379fb6921
parentceaef713f847d7bc267de6090ba9480c60741bb3 (diff)
moved IntcodeComputer to its own module
-rw-r--r--src/lib.rs3
-rw-r--r--src/year_2019/day2.rs151
-rw-r--r--src/year_2019/intcode_computer.rs148
3 files changed, 153 insertions, 149 deletions
diff --git a/src/lib.rs b/src/lib.rs
index e1b683a..ce2767a 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -26,6 +26,9 @@ pub mod year_2018 {
///
/// Collect stars by solving puzzles. Two puzzles will be made available on each day in the Advent calendar; the second puzzle is unlocked when you complete the first. Each puzzle grants one star. Good luck!
pub mod year_2019 {
+ pub mod intcode_computer;
+ pub use intcode_computer::{IntcodeComputer, IntcodeProgram};
+
pub mod day1;
pub mod day2;
pub mod day3;
diff --git a/src/year_2019/day2.rs b/src/year_2019/day2.rs
index 2b6df51..8cbc82f 100644
--- a/src/year_2019/day2.rs
+++ b/src/year_2019/day2.rs
@@ -1,5 +1,7 @@
//! --- Day 2: 1202 Program Alarm ---
+use super::{IntcodeComputer, IntcodeProgram};
+
/// On the way to your gravity assist around the Moon, your ship computer beeps angrily about a "1202 program alarm". On the radio, an Elf is already explaining how to handle the situation: "Don't worry, that's perfectly norma--" The ship computer bursts into flames.
///
/// You notify the Elves that the computer's magic smoke seems to have escaped. "That computer ran Intcode programs like the gravity assist program it was working on; surely there are enough spare parts up there to build a new Intcode computer!"
@@ -120,155 +122,6 @@ pub fn part2() {
}
}
-#[derive(Debug)]
-pub struct IntcodeComputer {
- pub memory: IntcodeProgram,
- instruction_pointer: usize,
-}
-
-impl IntcodeComputer {
- pub fn load(&mut self, program: &IntcodeProgram) {
- self.memory = program.clone();
- self.instruction_pointer = 0;
- }
-
- pub fn run(mut self) -> Self {
- loop {
- let next_instruction = IntcodeInstruction::from(&self);
-
- match next_instruction {
- IntcodeInstruction::Add(one_address, two_address, output_address) => {
- let one = *self.memory.get(one_address);
- let two = *self.memory.get(two_address);
-
- self.memory.replace(output_address, one + two)
- }
-
- IntcodeInstruction::Multiply(one_address, two_address, output_address) => {
- let one = *self.memory.get(one_address);
- let two = *self.memory.get(two_address);
-
- self.memory.replace(output_address, one * two)
- }
-
- IntcodeInstruction::Halt => break,
- }
-
- self.instruction_pointer += next_instruction.length()
- }
-
- self
- }
-}
-
-impl From<&IntcodeProgram> for IntcodeComputer {
- fn from(program: &IntcodeProgram) -> Self {
- Self {
- memory: program.clone(),
- instruction_pointer: 0,
- }
- }
-}
-
-impl From<&str> for IntcodeComputer {
- fn from(string: &str) -> Self {
- Self {
- memory: IntcodeProgram::from(string),
- instruction_pointer: 0,
- }
- }
-}
-
-#[derive(Debug)]
-enum IntcodeInstruction {
- /// Adds the values from the first two addresses, writes the result to the third address
- Add(usize, usize, usize),
-
- /// Multiplies the values from the first two addresses, writes the result to the third address
- Multiply(usize, usize, usize),
-
- /// Halts the IntcodeComputer
- Halt,
-}
-
-impl IntcodeInstruction {
- pub fn length(&self) -> usize {
- match self {
- Self::Add(..) => 4,
- Self::Multiply(..) => 4,
- Self::Halt => 1,
- }
- }
-}
-
-impl From<&IntcodeComputer> for IntcodeInstruction {
- fn from(state: &IntcodeComputer) -> Self {
- let opcode = state.memory.get(state.instruction_pointer);
-
- match opcode {
- 1 => Self::Add(
- *state.memory.get(state.instruction_pointer + 1),
- *state.memory.get(state.instruction_pointer + 2),
- *state.memory.get(state.instruction_pointer + 3),
- ),
- 2 => Self::Multiply(
- *state.memory.get(state.instruction_pointer + 1),
- *state.memory.get(state.instruction_pointer + 2),
- *state.memory.get(state.instruction_pointer + 3),
- ),
- 99 => Self::Halt,
- other => panic!("Invalid Opcode encountered: {}", other),
- }
- }
-}
-
-#[derive(Debug, Clone)]
-pub struct IntcodeProgram {
- data: Vec<usize>,
-}
-
-impl IntcodeProgram {
- pub fn get(&self, address: usize) -> &usize {
- self.data
- .get(address)
- .unwrap_or_else(|| panic!("Failed to get data at address {}", address))
- }
-
- pub fn replace(&mut self, address: usize, replacement: usize) {
- let integer = self
- .data
- .get_mut(address)
- .unwrap_or_else(|| panic!("Failed to get_mut data at address {}", address));
-
- *integer = replacement;
- }
-
- pub fn data(&self) -> &Vec<usize> {
- &self.data
- }
-
- pub fn data_serialized(&self) -> String {
- self.data
- .iter()
- .map(|integer| integer.to_string())
- .collect::<Vec<String>>()
- .join(",")
- }
-}
-
-impl From<&str> for IntcodeProgram {
- fn from(string: &str) -> Self {
- Self {
- data: string
- .trim()
- .split(",")
- .map(|integer| integer.parse::<usize>())
- .map(|parse_result| parse_result.expect("Failed to parse Intcode integer as usize"))
- .collect(),
- }
- }
-}
-
#[cfg(test)]
mod tests {
use super::*;
diff --git a/src/year_2019/intcode_computer.rs b/src/year_2019/intcode_computer.rs
new file mode 100644
index 0000000..bfb586d
--- /dev/null
+++ b/src/year_2019/intcode_computer.rs
@@ -0,0 +1,148 @@
+#[derive(Debug)]
+pub struct IntcodeComputer {
+ pub memory: IntcodeProgram,
+ instruction_pointer: usize,
+}
+
+impl IntcodeComputer {
+ pub fn load(&mut self, program: &IntcodeProgram) {
+ self.memory = program.clone();
+ self.instruction_pointer = 0;
+ }
+
+ pub fn run(mut self) -> Self {
+ loop {
+ let next_instruction = IntcodeInstruction::from(&self);
+
+ match next_instruction {
+ IntcodeInstruction::Add(one_address, two_address, output_address) => {
+ let one = *self.memory.get(one_address);
+ let two = *self.memory.get(two_address);
+
+ self.memory.replace(output_address, one + two)
+ }
+
+ IntcodeInstruction::Multiply(one_address, two_address, output_address) => {
+ let one = *self.memory.get(one_address);
+ let two = *self.memory.get(two_address);
+
+ self.memory.replace(output_address, one * two)
+ }
+
+ IntcodeInstruction::Halt => break,
+ }
+
+ self.instruction_pointer += next_instruction.length()
+ }
+
+ self
+ }
+}
+
+impl From<&IntcodeProgram> for IntcodeComputer {
+ fn from(program: &IntcodeProgram) -> Self {
+ Self {
+ memory: program.clone(),
+ instruction_pointer: 0,
+ }
+ }
+}
+
+impl From<&str> for IntcodeComputer {
+ fn from(string: &str) -> Self {
+ Self {
+ memory: IntcodeProgram::from(string),
+ instruction_pointer: 0,
+ }
+ }
+}
+
+#[derive(Debug)]
+enum IntcodeInstruction {
+ /// Adds the values from the first two addresses, writes the result to the third address
+ Add(usize, usize, usize),
+
+ /// Multiplies the values from the first two addresses, writes the result to the third address
+ Multiply(usize, usize, usize),
+
+ /// Halts the IntcodeComputer
+ Halt,
+}
+
+impl IntcodeInstruction {
+ pub fn length(&self) -> usize {
+ match self {
+ Self::Add(..) => 4,
+ Self::Multiply(..) => 4,
+ Self::Halt => 1,
+ }
+ }
+}
+
+impl From<&IntcodeComputer> for IntcodeInstruction {
+ fn from(state: &IntcodeComputer) -> Self {
+ let opcode = state.memory.get(state.instruction_pointer);
+
+ match opcode {
+ 1 => Self::Add(
+ *state.memory.get(state.instruction_pointer + 1),
+ *state.memory.get(state.instruction_pointer + 2),
+ *state.memory.get(state.instruction_pointer + 3),
+ ),
+ 2 => Self::Multiply(
+ *state.memory.get(state.instruction_pointer + 1),
+ *state.memory.get(state.instruction_pointer + 2),
+ *state.memory.get(state.instruction_pointer + 3),
+ ),
+ 99 => Self::Halt,
+ other => panic!("Invalid Opcode encountered: {}", other),
+ }
+ }
+}
+
+#[derive(Debug, Clone)]
+pub struct IntcodeProgram {
+ data: Vec<usize>,
+}
+
+impl IntcodeProgram {
+ pub fn get(&self, address: usize) -> &usize {
+ self.data
+ .get(address)
+ .unwrap_or_else(|| panic!("Failed to get data at address {}", address))
+ }
+
+ pub fn replace(&mut self, address: usize, replacement: usize) {
+ let integer = self
+ .data
+ .get_mut(address)
+ .unwrap_or_else(|| panic!("Failed to get_mut data at address {}", address));
+
+ *integer = replacement;
+ }
+
+ pub fn data(&self) -> &Vec<usize> {
+ &self.data
+ }
+
+ pub fn data_serialized(&self) -> String {
+ self.data
+ .iter()
+ .map(|integer| integer.to_string())
+ .collect::<Vec<String>>()
+ .join(",")
+ }
+}
+
+impl From<&str> for IntcodeProgram {
+ fn from(string: &str) -> Self {
+ Self {
+ data: string
+ .trim()
+ .split(",")
+ .map(|integer| integer.parse::<usize>())
+ .map(|parse_result| parse_result.expect("Failed to parse Intcode integer as usize"))
+ .collect(),
+ }
+ }
+}