-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
79ce632
commit bf8480f
Showing
10 changed files
with
176 additions
and
102 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
1102,34463338,34463338,63,1007,63,34463338,63,1005,63,53,1101,3,0,1000,109,988,209,12,9,1000,209,6,209,3,203,0,1008,1000,1,63,1005,63,65,1008,1000,2,63,1005,63,904,1008,1000,0,63,1005,63,58,4,25,104,0,99,4,0,104,0,99,4,17,104,0,99,0,0,1101,27,0,1014,1101,286,0,1023,1102,1,35,1018,1102,20,1,1000,1101,26,0,1010,1101,0,289,1022,1102,1,30,1019,1102,734,1,1025,1102,1,31,1012,1101,25,0,1001,1102,1,1,1021,1101,0,36,1002,1101,0,527,1028,1101,895,0,1026,1102,1,23,1016,1101,21,0,1003,1102,22,1,1011,1102,1,522,1029,1102,1,892,1027,1102,1,0,1020,1102,1,28,1015,1102,38,1,1006,1101,0,32,1008,1101,743,0,1024,1101,0,37,1007,1102,1,24,1013,1102,1,33,1009,1102,39,1,1004,1102,1,34,1005,1102,1,29,1017,109,19,21102,40,1,-3,1008,1016,40,63,1005,63,203,4,187,1106,0,207,1001,64,1,64,1002,64,2,64,109,-7,2101,0,-7,63,1008,63,32,63,1005,63,227,1106,0,233,4,213,1001,64,1,64,1002,64,2,64,109,-3,2108,37,-2,63,1005,63,255,4,239,1001,64,1,64,1105,1,255,1002,64,2,64,109,11,21108,41,40,-6,1005,1014,275,1001,64,1,64,1106,0,277,4,261,1002,64,2,64,109,10,2105,1,-7,1105,1,295,4,283,1001,64,1,64,1002,64,2,64,109,-27,1201,-2,0,63,1008,63,25,63,1005,63,321,4,301,1001,64,1,64,1105,1,321,1002,64,2,64,109,15,21107,42,41,0,1005,1018,341,1001,64,1,64,1106,0,343,4,327,1002,64,2,64,109,-25,2108,20,10,63,1005,63,359,1105,1,365,4,349,1001,64,1,64,1002,64,2,64,109,12,2107,35,0,63,1005,63,385,1001,64,1,64,1106,0,387,4,371,1002,64,2,64,109,4,21101,43,0,6,1008,1015,43,63,1005,63,409,4,393,1106,0,413,1001,64,1,64,1002,64,2,64,109,9,21101,44,0,-8,1008,1010,46,63,1005,63,437,1001,64,1,64,1106,0,439,4,419,1002,64,2,64,109,5,21108,45,45,-4,1005,1019,457,4,445,1106,0,461,1001,64,1,64,1002,64,2,64,109,-22,2102,1,7,63,1008,63,33,63,1005,63,481,1106,0,487,4,467,1001,64,1,64,1002,64,2,64,109,14,21102,46,1,-1,1008,1014,43,63,1005,63,507,1106,0,513,4,493,1001,64,1,64,1002,64,2,64,109,12,2106,0,1,4,519,1106,0,531,1001,64,1,64,1002,64,2,64,109,-17,1205,10,547,1001,64,1,64,1106,0,549,4,537,1002,64,2,64,109,-8,1202,-2,1,63,1008,63,17,63,1005,63,569,1105,1,575,4,555,1001,64,1,64,1002,64,2,64,109,23,1206,-5,593,4,581,1001,64,1,64,1105,1,593,1002,64,2,64,109,-14,1208,-8,24,63,1005,63,613,1001,64,1,64,1105,1,615,4,599,1002,64,2,64,109,-2,1207,-1,33,63,1005,63,633,4,621,1105,1,637,1001,64,1,64,1002,64,2,64,109,2,21107,47,48,5,1005,1016,659,4,643,1001,64,1,64,1105,1,659,1002,64,2,64,109,-11,1208,8,32,63,1005,63,681,4,665,1001,64,1,64,1106,0,681,1002,64,2,64,109,2,2101,0,0,63,1008,63,36,63,1005,63,703,4,687,1106,0,707,1001,64,1,64,1002,64,2,64,109,12,1206,7,719,1106,0,725,4,713,1001,64,1,64,1002,64,2,64,109,2,2105,1,8,4,731,1001,64,1,64,1106,0,743,1002,64,2,64,109,-21,2102,1,9,63,1008,63,39,63,1005,63,769,4,749,1001,64,1,64,1105,1,769,1002,64,2,64,109,11,1201,-3,0,63,1008,63,24,63,1005,63,793,1001,64,1,64,1105,1,795,4,775,1002,64,2,64,109,20,1205,-5,809,4,801,1105,1,813,1001,64,1,64,1002,64,2,64,109,-23,1207,4,36,63,1005,63,833,1001,64,1,64,1105,1,835,4,819,1002,64,2,64,109,-3,2107,33,5,63,1005,63,853,4,841,1106,0,857,1001,64,1,64,1002,64,2,64,109,16,1202,-9,1,63,1008,63,37,63,1005,63,879,4,863,1105,1,883,1001,64,1,64,1002,64,2,64,109,12,2106,0,-1,1105,1,901,4,889,1001,64,1,64,4,64,99,21101,0,27,1,21101,0,915,0,1106,0,922,21201,1,48476,1,204,1,99,109,3,1207,-2,3,63,1005,63,964,21201,-2,-1,1,21101,0,942,0,1105,1,922,21202,1,1,-1,21201,-2,-3,1,21101,0,957,0,1105,1,922,22201,1,-1,-2,1106,0,968,21202,-2,1,-2,109,-3,2106,0,0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
//! # Sensor Boost | ||
//! | ||
//! This problem is essentially an unit test for the canonical full intcode computer | ||
//! used heavily by other days. | ||
use crate::util::parse::*; | ||
use intcode::*; | ||
|
||
pub mod intcode { | ||
use std::sync::mpsc::*; | ||
use std::thread; | ||
|
||
pub struct Computer { | ||
pc: usize, | ||
base: i64, | ||
code: Vec<i64>, | ||
input_rx: Receiver<i64>, | ||
output_tx: Sender<i64>, | ||
} | ||
|
||
impl Computer { | ||
/// Spawns an `IntCode` computer in a new thread, returning an input and output channel | ||
/// for communicating asynchronously with the computer via the opcodes 3 and 4. | ||
pub fn spawn(code: &[i64]) -> (Sender<i64>, Receiver<i64>) { | ||
let pc = 0; | ||
let base = 0; | ||
let code = code.to_vec(); | ||
let (input_tx, input_rx) = channel(); | ||
let (output_tx, output_rx) = channel(); | ||
|
||
let mut computer = Computer { pc, base, code, input_rx, output_tx }; | ||
thread::spawn(move || computer.run()); | ||
|
||
(input_tx, output_rx) | ||
} | ||
|
||
/// Runs until a `99` opcode instruction is encountered. | ||
fn run(&mut self) { | ||
loop { | ||
match self.code[self.pc] % 100 { | ||
// Add | ||
1 => { | ||
let value = self.read(1) + self.read(2); | ||
self.write(3, value); | ||
self.pc += 4; | ||
} | ||
// Multiply | ||
2 => { | ||
let value = self.read(1) * self.read(2); | ||
self.write(3, value); | ||
self.pc += 4; | ||
} | ||
// Read input channel | ||
3 => { | ||
let value = self.input_rx.recv().unwrap(); | ||
self.write(1, value); | ||
self.pc += 2; | ||
} | ||
// Write output channel | ||
4 => { | ||
let value = self.read(1); | ||
let _ = self.output_tx.send(value); | ||
self.pc += 2; | ||
} | ||
// Jump if true | ||
5 => { | ||
let first = self.read(1); | ||
let second = self.read(2); | ||
self.pc = if first == 0 { self.pc + 3 } else { second as usize }; | ||
} | ||
// Jump if false | ||
6 => { | ||
let first = self.read(1); | ||
let second = self.read(2); | ||
self.pc = if first == 0 { second as usize } else { self.pc + 3 }; | ||
} | ||
// Less than | ||
7 => { | ||
let value = self.read(1) < self.read(2); | ||
self.write(3, value as i64); | ||
self.pc += 4; | ||
} | ||
// Equals | ||
8 => { | ||
let value = self.read(1) == self.read(2); | ||
self.write(3, value as i64); | ||
self.pc += 4; | ||
} | ||
// Adjust relative base | ||
9 => { | ||
let value = self.read(1); | ||
self.base += value; | ||
self.pc += 2; | ||
} | ||
_ => break, | ||
} | ||
} | ||
} | ||
|
||
/// Convenience wrapper for reading a value | ||
fn read(&mut self, offset: usize) -> i64 { | ||
let index = self.address(offset); | ||
self.code[index] | ||
} | ||
|
||
/// Convenience wrapper for writing a value | ||
fn write(&mut self, offset: usize, value: i64) { | ||
let index = self.address(offset); | ||
self.code[index] = value; | ||
} | ||
|
||
/// Calculates an address using one of the three possible address modes. | ||
/// If the address exceeds the size of the `code` vector then it is extended with 0 values. | ||
fn address(&mut self, offset: usize) -> usize { | ||
const FACTOR: [i64; 4] = [0, 100, 1000, 10000]; | ||
let mode = self.code[self.pc] / FACTOR[offset]; | ||
|
||
let index = match mode % 10 { | ||
0 => self.code[self.pc + offset] as usize, | ||
1 => self.pc + offset, | ||
2 => (self.base + self.code[self.pc + offset]) as usize, | ||
_ => unreachable!(), | ||
}; | ||
|
||
if index >= self.code.len() { | ||
self.code.resize(index + 1, 0); | ||
} | ||
|
||
index | ||
} | ||
} | ||
} | ||
|
||
pub fn parse(input: &str) -> Vec<i64> { | ||
input.iter_signed().collect() | ||
} | ||
|
||
pub fn part1(input: &[i64]) -> i64 { | ||
run(input, 1) | ||
} | ||
|
||
pub fn part2(input: &[i64]) -> i64 { | ||
run(input, 2) | ||
} | ||
|
||
fn run(input: &[i64], value: i64) -> i64 { | ||
let (tx, rx) = Computer::spawn(input); | ||
let _ = tx.send(value); | ||
rx.recv().unwrap() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -91,6 +91,7 @@ mod year2019 { | |
mod day06_test; | ||
mod day07_test; | ||
mod day08_test; | ||
mod day09_test; | ||
} | ||
|
||
mod year2015 { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
use aoc::year2019::day09::*; | ||
|
||
const FIRST_EXAMPLE: &str = "109,1,204,-1,1001,100,1,100,1008,100,16,101,1006,101,0,99"; | ||
const SECOND_EXAMPLE: &str = "1102,34915192,34915192,7,4,7,99,0"; | ||
|
||
#[test] | ||
fn part1_test() { | ||
let input = parse(FIRST_EXAMPLE); | ||
assert_eq!(part1(&input), 109); | ||
} | ||
|
||
#[test] | ||
fn part2_test() { | ||
let input = parse(SECOND_EXAMPLE); | ||
assert_eq!(part2(&input), 1219070632396864); | ||
} |