day11
This commit is contained in:
parent
b851d2bbe6
commit
e27c10d3b0
7 changed files with 625 additions and 5 deletions
|
@ -4,8 +4,6 @@ version = "0.1.0"
|
||||||
authors = ["Stefan Schwarz <stefan@f2o.io>"]
|
authors = ["Stefan Schwarz <stefan@f2o.io>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "day1"
|
name = "day1"
|
||||||
path = "src/day1/main.rs"
|
path = "src/day1/main.rs"
|
||||||
|
@ -38,6 +36,10 @@ path = "src/day9/main.rs"
|
||||||
name = "day10"
|
name = "day10"
|
||||||
path = "src/day10/main.rs"
|
path = "src/day10/main.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "day11"
|
||||||
|
path = "src/day11/main.rs"
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "day12"
|
name = "day12"
|
||||||
path = "src/day12/main.rs"
|
path = "src/day12/main.rs"
|
||||||
|
|
1
README.md
Normal file
1
README.md
Normal file
|
@ -0,0 +1 @@
|
||||||
|
# Advent of Code 2019
|
1
input11
Normal file
1
input11
Normal file
|
@ -0,0 +1 @@
|
||||||
|
3,8,1005,8,320,1106,0,11,0,0,0,104,1,104,0,3,8,1002,8,-1,10,101,1,10,10,4,10,1008,8,1,10,4,10,102,1,8,29,2,1005,1,10,1006,0,11,3,8,1002,8,-1,10,101,1,10,10,4,10,108,0,8,10,4,10,102,1,8,57,1,8,15,10,1006,0,79,1,6,3,10,3,8,102,-1,8,10,101,1,10,10,4,10,108,0,8,10,4,10,101,0,8,90,2,103,18,10,1006,0,3,2,105,14,10,3,8,102,-1,8,10,1001,10,1,10,4,10,108,0,8,10,4,10,101,0,8,123,2,9,2,10,3,8,102,-1,8,10,1001,10,1,10,4,10,1008,8,1,10,4,10,1001,8,0,150,1,2,2,10,2,1009,6,10,1,1006,12,10,1006,0,81,3,8,102,-1,8,10,1001,10,1,10,4,10,1008,8,1,10,4,10,102,1,8,187,3,8,102,-1,8,10,1001,10,1,10,4,10,1008,8,0,10,4,10,101,0,8,209,3,8,1002,8,-1,10,1001,10,1,10,4,10,1008,8,1,10,4,10,101,0,8,231,1,1008,11,10,1,1001,4,10,2,1104,18,10,3,8,102,-1,8,10,1001,10,1,10,4,10,108,1,8,10,4,10,1001,8,0,264,1,8,14,10,1006,0,36,3,8,1002,8,-1,10,1001,10,1,10,4,10,108,0,8,10,4,10,101,0,8,293,1006,0,80,1006,0,68,101,1,9,9,1007,9,960,10,1005,10,15,99,109,642,104,0,104,1,21102,1,846914232732,1,21102,1,337,0,1105,1,441,21102,1,387512115980,1,21101,348,0,0,1106,0,441,3,10,104,0,104,1,3,10,104,0,104,0,3,10,104,0,104,1,3,10,104,0,104,1,3,10,104,0,104,0,3,10,104,0,104,1,21102,209533824219,1,1,21102,1,395,0,1106,0,441,21101,0,21477985303,1,21102,406,1,0,1106,0,441,3,10,104,0,104,0,3,10,104,0,104,0,21101,868494234468,0,1,21101,429,0,0,1106,0,441,21102,838429471080,1,1,21102,1,440,0,1106,0,441,99,109,2,21201,-1,0,1,21101,0,40,2,21102,472,1,3,21101,0,462,0,1106,0,505,109,-2,2106,0,0,0,1,0,0,1,109,2,3,10,204,-1,1001,467,468,483,4,0,1001,467,1,467,108,4,467,10,1006,10,499,1102,1,0,467,109,-2,2106,0,0,0,109,4,2101,0,-1,504,1207,-3,0,10,1006,10,522,21101,0,0,-3,21202,-3,1,1,22101,0,-2,2,21102,1,1,3,21102,541,1,0,1106,0,546,109,-4,2105,1,0,109,5,1207,-3,1,10,1006,10,569,2207,-4,-2,10,1006,10,569,22102,1,-4,-4,1105,1,637,22102,1,-4,1,21201,-3,-1,2,21202,-2,2,3,21102,588,1,0,1105,1,546,22101,0,1,-4,21102,1,1,-1,2207,-4,-2,10,1006,10,607,21101,0,0,-1,22202,-2,-1,-2,2107,0,-3,10,1006,10,629,21201,-1,0,1,21102,629,1,0,105,1,504,21202,-2,-1,-2,22201,-4,-2,-4,109,-5,2105,1,0
|
186
src/day11/main.rs
Normal file
186
src/day11/main.rs
Normal file
|
@ -0,0 +1,186 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::env;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io;
|
||||||
|
|
||||||
|
use aoc2019::intcode;
|
||||||
|
|
||||||
|
#[derive(Hash, Default, PartialEq, Eq, Clone)]
|
||||||
|
struct Panel {
|
||||||
|
x: isize,
|
||||||
|
y: isize,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Color {
|
||||||
|
Black,
|
||||||
|
White,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<isize> for Color {
|
||||||
|
fn from(color: isize) -> Self {
|
||||||
|
match color {
|
||||||
|
0 => Color::Black,
|
||||||
|
1 => Color::White,
|
||||||
|
_ => panic!("invalid color"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<isize> for &Color {
|
||||||
|
fn into(self) -> isize {
|
||||||
|
match self {
|
||||||
|
Color::Black => 0,
|
||||||
|
Color::White => 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Color {
|
||||||
|
fn char(&self) -> char {
|
||||||
|
match self {
|
||||||
|
Color::Black => ' ',
|
||||||
|
Color::White => '\u{2588}',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Direction {
|
||||||
|
Up,
|
||||||
|
Down,
|
||||||
|
Left,
|
||||||
|
Right,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Turn {
|
||||||
|
Left,
|
||||||
|
Right,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<isize> for Turn {
|
||||||
|
fn from(turn: isize) -> Self {
|
||||||
|
match turn {
|
||||||
|
0 => Turn::Left,
|
||||||
|
1 => Turn::Right,
|
||||||
|
_ => panic!("invalid turn direction"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Robot {
|
||||||
|
panel: Panel,
|
||||||
|
direction: Direction,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Robot {
|
||||||
|
fn turn(&mut self, direction: Turn) {
|
||||||
|
self.direction = match self.direction {
|
||||||
|
Direction::Up => match direction {
|
||||||
|
Turn::Left => Direction::Left,
|
||||||
|
Turn::Right => Direction::Right,
|
||||||
|
},
|
||||||
|
Direction::Right => match direction {
|
||||||
|
Turn::Left => Direction::Up,
|
||||||
|
Turn::Right => Direction::Down,
|
||||||
|
},
|
||||||
|
Direction::Down => match direction {
|
||||||
|
Turn::Left => Direction::Right,
|
||||||
|
Turn::Right => Direction::Left,
|
||||||
|
},
|
||||||
|
Direction::Left => match direction {
|
||||||
|
Turn::Left => Direction::Down,
|
||||||
|
Turn::Right => Direction::Up,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn step(&mut self) {
|
||||||
|
self.panel = match self.direction {
|
||||||
|
Direction::Up => Panel {
|
||||||
|
x: self.panel.x,
|
||||||
|
y: self.panel.y + 1,
|
||||||
|
},
|
||||||
|
Direction::Left => Panel {
|
||||||
|
x: self.panel.x + 1,
|
||||||
|
y: self.panel.y,
|
||||||
|
},
|
||||||
|
Direction::Down => Panel {
|
||||||
|
x: self.panel.x,
|
||||||
|
y: self.panel.y - 1,
|
||||||
|
},
|
||||||
|
Direction::Right => Panel {
|
||||||
|
x: self.panel.x - 1,
|
||||||
|
y: self.panel.y,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> io::Result<()> {
|
||||||
|
let filename = env::args().nth(1).expect("provide file as first param");
|
||||||
|
let mut computer = intcode::Computer::from(File::open(filename)?);
|
||||||
|
|
||||||
|
let mut canvas: HashMap<Panel, Color> = HashMap::new();
|
||||||
|
canvas.insert(Panel { x: 0, y: 0 }, Color::White);
|
||||||
|
let mut robot = Robot {
|
||||||
|
panel: Panel::default(),
|
||||||
|
direction: Direction::Up,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut input: isize = canvas
|
||||||
|
.get(&robot.panel)
|
||||||
|
.or_else(|| Some(&Color::Black))
|
||||||
|
.unwrap()
|
||||||
|
.into();
|
||||||
|
while let Some(output) = computer.run_io(input) {
|
||||||
|
canvas.insert(robot.panel.clone(), Color::from(output));
|
||||||
|
|
||||||
|
let output = computer.run_must_output();
|
||||||
|
robot.turn(Turn::from(output));
|
||||||
|
robot.step();
|
||||||
|
|
||||||
|
input = canvas
|
||||||
|
.get(&robot.panel)
|
||||||
|
.or_else(|| Some(&Color::Black))
|
||||||
|
.unwrap()
|
||||||
|
.into();
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut xmin: isize = 0;
|
||||||
|
let mut xmax: isize = 0;
|
||||||
|
let mut ymin: isize = 0;
|
||||||
|
let mut ymax: isize = 0;
|
||||||
|
let painted = canvas
|
||||||
|
.iter()
|
||||||
|
.map(|(k, _)| {
|
||||||
|
if k.x < xmin {
|
||||||
|
xmin = k.x;
|
||||||
|
}
|
||||||
|
if k.x > xmax {
|
||||||
|
xmax = k.x;
|
||||||
|
}
|
||||||
|
if k.y < ymin {
|
||||||
|
ymin = k.y;
|
||||||
|
}
|
||||||
|
if k.y > ymax {
|
||||||
|
ymax = k.y;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.count();
|
||||||
|
println!("painted: {}", painted);
|
||||||
|
println!("canvas: x:{}-{} y:{}-{}", xmin, xmax, ymin, ymax);
|
||||||
|
|
||||||
|
for y in (ymin..=ymax).rev() {
|
||||||
|
for x in (xmin..=xmax).rev() {
|
||||||
|
print!(
|
||||||
|
"{}",
|
||||||
|
canvas
|
||||||
|
.get(&Panel { x, y })
|
||||||
|
.unwrap_or_else(|| &Color::Black)
|
||||||
|
.char()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
println!()
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
432
src/intcode.rs
Normal file
432
src/intcode.rs
Normal file
|
@ -0,0 +1,432 @@
|
||||||
|
use std::collections::VecDeque;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::{BufRead, BufReader};
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
enum Var {
|
||||||
|
A = 1,
|
||||||
|
B,
|
||||||
|
C,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
enum Mode {
|
||||||
|
Position,
|
||||||
|
Immediate,
|
||||||
|
Relative,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Mode {
|
||||||
|
fn default() -> Self {
|
||||||
|
Mode::Position
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<isize> for Mode {
|
||||||
|
fn from(b: isize) -> Self {
|
||||||
|
match b {
|
||||||
|
0 => Mode::Position,
|
||||||
|
1 => Mode::Immediate,
|
||||||
|
2 => Mode::Relative,
|
||||||
|
_ => panic!("invalid mode {}", b),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Default, Debug)]
|
||||||
|
struct Modes {
|
||||||
|
a: Mode,
|
||||||
|
b: Mode,
|
||||||
|
c: Mode,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Modes {
|
||||||
|
fn mode_for(&self, v: &Var) -> Mode {
|
||||||
|
match v {
|
||||||
|
Var::A => self.a,
|
||||||
|
Var::B => self.b,
|
||||||
|
Var::C => self.c,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<(Mode, Mode, Mode)> for Modes {
|
||||||
|
fn from(modes: (Mode, Mode, Mode)) -> Self {
|
||||||
|
Modes {
|
||||||
|
a: modes.0,
|
||||||
|
b: modes.1,
|
||||||
|
c: modes.2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&ModedOpcode> for Modes {
|
||||||
|
fn from(mo: &ModedOpcode) -> Self {
|
||||||
|
mo.modes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
enum Opcode {
|
||||||
|
Add,
|
||||||
|
Multiply,
|
||||||
|
Input,
|
||||||
|
Output,
|
||||||
|
JumpIfTrue,
|
||||||
|
JumpIfFalse,
|
||||||
|
LessThan,
|
||||||
|
Equals,
|
||||||
|
RelativeAdj,
|
||||||
|
Halt,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&ModedOpcode> for Opcode {
|
||||||
|
fn from(mo: &ModedOpcode) -> Self {
|
||||||
|
mo.op
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<isize> for Opcode {
|
||||||
|
fn from(i: isize) -> Self {
|
||||||
|
match i {
|
||||||
|
1 => Opcode::Add,
|
||||||
|
2 => Opcode::Multiply,
|
||||||
|
3 => Opcode::Input,
|
||||||
|
4 => Opcode::Output,
|
||||||
|
5 => Opcode::JumpIfTrue,
|
||||||
|
6 => Opcode::JumpIfFalse,
|
||||||
|
7 => Opcode::LessThan,
|
||||||
|
8 => Opcode::Equals,
|
||||||
|
9 => Opcode::RelativeAdj,
|
||||||
|
99 => Opcode::Halt,
|
||||||
|
_ => panic!("invalid opcode {}", i),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ModedOpcode {
|
||||||
|
modes: Modes,
|
||||||
|
op: Opcode,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<isize> for ModedOpcode {
|
||||||
|
fn from(i: isize) -> Self {
|
||||||
|
let code = i % 100;
|
||||||
|
let modes = i / 100;
|
||||||
|
let a = (modes % 10) / 1;
|
||||||
|
let b = (modes % 100) / 10;
|
||||||
|
let c = (modes % 1000) / 100;
|
||||||
|
let modes = (Mode::from(a), Mode::from(b), Mode::from(c));
|
||||||
|
ModedOpcode {
|
||||||
|
modes: Modes::from(modes),
|
||||||
|
op: Opcode::from(code),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Computer {
|
||||||
|
pos: usize,
|
||||||
|
rel: isize,
|
||||||
|
program: Vec<isize>,
|
||||||
|
modes: Modes,
|
||||||
|
inputs: VecDeque<isize>,
|
||||||
|
outputs: VecDeque<isize>,
|
||||||
|
halted: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Clone for Computer {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Computer::from(self.program.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<File> for Computer {
|
||||||
|
fn from(f: File) -> Self {
|
||||||
|
let f = BufReader::new(f);
|
||||||
|
let program: Vec<isize> = f
|
||||||
|
.split(b',')
|
||||||
|
.map(|o| {
|
||||||
|
let o = o.unwrap();
|
||||||
|
let mut o = o.iter().peekable();
|
||||||
|
let sign = if o.peek() == Some(&&b'-') { -1 } else { 1 };
|
||||||
|
o.filter(|i| **i >= b'0' && **i <= b'9')
|
||||||
|
.fold(0, |s, i| ((i - b'0') as isize + 10 * s))
|
||||||
|
* sign
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
Computer::from(program)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Vec<isize>> for Computer {
|
||||||
|
fn from(program: Vec<isize>) -> Self {
|
||||||
|
Computer {
|
||||||
|
pos: 0,
|
||||||
|
rel: 0,
|
||||||
|
program,
|
||||||
|
modes: Default::default(),
|
||||||
|
inputs: VecDeque::new(),
|
||||||
|
outputs: VecDeque::new(),
|
||||||
|
halted: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Computer {
|
||||||
|
pub fn get_outputs(&self) -> &VecDeque<isize> {
|
||||||
|
&self.outputs
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pop_output(&mut self) -> Option<isize> {
|
||||||
|
self.outputs.pop_front()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clone_with_modified_program(&self, u: Vec<(usize, isize)>) -> Computer {
|
||||||
|
let mut computer = self.clone();
|
||||||
|
for (pos, val) in u {
|
||||||
|
computer.program[pos] = val;
|
||||||
|
}
|
||||||
|
computer
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clone_with_input(&self, input: Vec<isize>) -> Computer {
|
||||||
|
let mut computer = self.clone();
|
||||||
|
computer.inputs = VecDeque::from(input);
|
||||||
|
computer
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run(&mut self) {
|
||||||
|
while !self.halted {
|
||||||
|
self.step();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run_until_output(&mut self) -> Option<isize> {
|
||||||
|
loop {
|
||||||
|
self.step();
|
||||||
|
if self.outputs.len() > 0 {
|
||||||
|
return self.outputs.pop_front();
|
||||||
|
}
|
||||||
|
if self.halted {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run_must_output(&mut self) -> isize {
|
||||||
|
self.run_until_output()
|
||||||
|
.expect("computer halted without output")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run_io(&mut self, input: isize) -> Option<isize> {
|
||||||
|
self.inputs.push_back(input);
|
||||||
|
self.run_until_output()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn step(&mut self) {
|
||||||
|
let instruction = self.program[self.pos];
|
||||||
|
let instruction = ModedOpcode::from(instruction);
|
||||||
|
self.modes = Modes::from(&instruction);
|
||||||
|
let advance = match Opcode::from(&instruction) {
|
||||||
|
Opcode::Add => self.add(),
|
||||||
|
Opcode::Multiply => self.multiply(),
|
||||||
|
Opcode::Input => self.input(),
|
||||||
|
Opcode::Output => self.output(),
|
||||||
|
Opcode::JumpIfTrue => self.jump_if_true(),
|
||||||
|
Opcode::JumpIfFalse => self.jump_if_false(),
|
||||||
|
Opcode::LessThan => self.less_than(),
|
||||||
|
Opcode::Equals => self.equals(),
|
||||||
|
Opcode::RelativeAdj => self.relative_adj(),
|
||||||
|
Opcode::Halt => self.halt(),
|
||||||
|
};
|
||||||
|
self.pos += advance;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_pos(&self, pos: usize) -> isize {
|
||||||
|
*self.program.get(pos).unwrap_or(&0)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get(&self, v: &Var) -> isize {
|
||||||
|
let want = self.pos + *v as usize;
|
||||||
|
let want = match self.modes.mode_for(v) {
|
||||||
|
Mode::Position => self.get_pos(want as usize) as usize,
|
||||||
|
Mode::Immediate => want,
|
||||||
|
Mode::Relative => (self.rel + self.get_pos(want)) as usize,
|
||||||
|
};
|
||||||
|
self.get_pos(want)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_a(&self) -> isize {
|
||||||
|
self.get(&Var::A)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_b(&self) -> isize {
|
||||||
|
self.get(&Var::B)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set(&mut self, v: &Var, value: isize) {
|
||||||
|
let length = self.program.len();
|
||||||
|
let want = self.pos + *v as usize;
|
||||||
|
let want = match self.modes.mode_for(v) {
|
||||||
|
Mode::Position => self.get_pos(want) as usize,
|
||||||
|
Mode::Immediate => want,
|
||||||
|
Mode::Relative => (self.rel + self.get_pos(want)) as usize,
|
||||||
|
};
|
||||||
|
if length < want {
|
||||||
|
let missing = (want - length) + 10000;
|
||||||
|
self.program.extend_from_slice(&vec![0; missing])
|
||||||
|
}
|
||||||
|
self.program[want] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_a(&mut self, value: isize) {
|
||||||
|
self.set(&Var::A, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_c(&mut self, value: isize) {
|
||||||
|
self.set(&Var::C, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add(&mut self) -> usize {
|
||||||
|
self.set_c(self.get_a() + self.get_b());
|
||||||
|
4
|
||||||
|
}
|
||||||
|
|
||||||
|
fn multiply(&mut self) -> usize {
|
||||||
|
self.set_c(self.get_a() * self.get_b());
|
||||||
|
4
|
||||||
|
}
|
||||||
|
|
||||||
|
fn input(&mut self) -> usize {
|
||||||
|
let value = self.inputs.pop_front().expect("no input provided");
|
||||||
|
self.set_a(value);
|
||||||
|
2
|
||||||
|
}
|
||||||
|
|
||||||
|
fn output(&mut self) -> usize {
|
||||||
|
self.outputs.push_back(self.get_a());
|
||||||
|
2
|
||||||
|
}
|
||||||
|
|
||||||
|
fn jump_if_true(&mut self) -> usize {
|
||||||
|
if self.get_a() > 0 {
|
||||||
|
self.pos = self.get_b() as usize;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
3
|
||||||
|
}
|
||||||
|
|
||||||
|
fn jump_if_false(&mut self) -> usize {
|
||||||
|
if self.get_a() == 0 {
|
||||||
|
self.pos = self.get_b() as usize;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
3
|
||||||
|
}
|
||||||
|
|
||||||
|
fn less_than(&mut self) -> usize {
|
||||||
|
if self.get_a() < self.get_b() {
|
||||||
|
self.set_c(1)
|
||||||
|
} else {
|
||||||
|
self.set_c(0)
|
||||||
|
}
|
||||||
|
4
|
||||||
|
}
|
||||||
|
|
||||||
|
fn equals(&mut self) -> usize {
|
||||||
|
if self.get_a() == self.get_b() {
|
||||||
|
self.set_c(1)
|
||||||
|
} else {
|
||||||
|
self.set_c(0)
|
||||||
|
}
|
||||||
|
4
|
||||||
|
}
|
||||||
|
|
||||||
|
fn relative_adj(&mut self) -> usize {
|
||||||
|
self.rel = self.rel + self.get_a();
|
||||||
|
2
|
||||||
|
}
|
||||||
|
|
||||||
|
fn halt(&mut self) -> usize {
|
||||||
|
self.halted = true;
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn example1() {
|
||||||
|
let program = vec![
|
||||||
|
109, 1, 204, -1, 1001, 100, 1, 100, 1008, 100, 16, 101, 1006, 101, 0, 99,
|
||||||
|
];
|
||||||
|
let mut computer = Computer::from(program.clone());
|
||||||
|
computer.run();
|
||||||
|
assert_eq!(computer.get_outputs().iter().eq(program.iter()), true)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn example2() {
|
||||||
|
assert_eq!(
|
||||||
|
Computer::from(vec![1102, 34915192, 34915192, 7, 4, 7, 99, 0]).run_must_output(),
|
||||||
|
1219070632396864
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn example3() {
|
||||||
|
assert_eq!(
|
||||||
|
Computer::from(vec![104, 1125899906842624, 99]).run_must_output(),
|
||||||
|
1125899906842624
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn day5exampe1() {
|
||||||
|
let computer = Computer::from(vec![3, 9, 8, 9, 10, 9, 4, 9, 99, -1, 8]);
|
||||||
|
assert_eq!(computer.clone_with_input(vec![1]).run_must_output(), 0);
|
||||||
|
assert_eq!(computer.clone_with_input(vec![8]).run_must_output(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn day5exampe2() {
|
||||||
|
let computer = Computer::from(vec![3, 3, 1108, -1, 8, 3, 4, 3, 99]);
|
||||||
|
assert_eq!(computer.clone_with_input(vec![1]).run_must_output(), 0);
|
||||||
|
assert_eq!(computer.clone_with_input(vec![8]).run_must_output(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn day5exampe3() {
|
||||||
|
let computer = Computer::from(vec![
|
||||||
|
3, 12, 6, 12, 15, 1, 13, 14, 13, 4, 13, 99, -1, 0, 1, 9,
|
||||||
|
]);
|
||||||
|
assert_eq!(computer.clone_with_input(vec![0]).run_must_output(), 0);
|
||||||
|
assert_eq!(computer.clone_with_input(vec![8]).run_must_output(), 1);
|
||||||
|
let computer = Computer::from(vec![3, 3, 1105, -1, 9, 1101, 0, 0, 12, 4, 12, 99, 1]);
|
||||||
|
assert_eq!(computer.clone_with_input(vec![0]).run_must_output(), 0);
|
||||||
|
assert_eq!(computer.clone_with_input(vec![8]).run_must_output(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn day5exampe4() {
|
||||||
|
let computer = Computer::from(vec![
|
||||||
|
3, 21, 1008, 21, 8, 20, 1005, 20, 22, 107, 8, 21, 20, 1006, 20, 31, 1106, 0, 36, 98, 0,
|
||||||
|
0, 1002, 21, 125, 20, 4, 20, 1105, 1, 46, 104, 999, 1105, 1, 46, 1101, 1000, 1, 20, 4,
|
||||||
|
20, 1105, 1, 46, 98, 99,
|
||||||
|
]);
|
||||||
|
assert_eq!(computer.clone_with_input(vec![0]).run_must_output(), 999);
|
||||||
|
assert_eq!(computer.clone_with_input(vec![8]).run_must_output(), 1000);
|
||||||
|
assert_eq!(computer.clone_with_input(vec![9]).run_must_output(), 1001);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn day9part1() {
|
||||||
|
let computer = Computer::from(File::open("input9").unwrap());
|
||||||
|
assert_eq!(
|
||||||
|
computer.clone_with_input(vec![1]).run_must_output(),
|
||||||
|
3063082071
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
1
src/lib.rs
Normal file
1
src/lib.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
pub mod intcode;
|
|
@ -1,3 +0,0 @@
|
||||||
fn main() {
|
|
||||||
println!("Hello, world!");
|
|
||||||
}
|
|
Loading…
Add table
Add a link
Reference in a new issue