Add day 9
This commit is contained in:
parent
2ac9776d10
commit
1c6711da2d
|
@ -0,0 +1,10 @@
|
|||
[package]
|
||||
name = "day09"
|
||||
version = "0.1.0"
|
||||
authors = ["kageru <kageru@encode.moe>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
intcode = { path = "../intcode" }
|
|
@ -0,0 +1,7 @@
|
|||
use intcode::*;
|
||||
|
||||
fn main() {
|
||||
let input = read_input();
|
||||
println!("Part 1: {}", run_for_input(&input, &mut 0, vec![1]));
|
||||
println!("Part 2: {}", run_for_input(&input, &mut 0, vec![2]));
|
||||
}
|
|
@ -30,16 +30,27 @@ impl Amplifier {
|
|||
|
||||
#[rustfmt::skip]
|
||||
fn get_next(&mut self, mode: Mode) -> i64 {
|
||||
let value = *self.tape.get(self.pos as usize).unwrap_or(&0);
|
||||
let value = *self.tape.get(self.pos as usize).unwrap();
|
||||
let next = match mode {
|
||||
Mode::Position => *self.tape.get(value as usize).unwrap_or(&0),
|
||||
Mode::Immediate => value,
|
||||
Mode::Relative => *self.tape.get((self.relative_base + value) as usize).unwrap_or(&0),
|
||||
Mode::Relative => *self.tape.get((value + self.relative_base) as usize).unwrap_or(&0),
|
||||
};
|
||||
self.pos += 1;
|
||||
next
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
fn get_next_address(&mut self, mode: Mode) -> i64 {
|
||||
let value = match mode {
|
||||
Mode::Position => *self.tape.get(self.pos as usize).unwrap_or(&0),
|
||||
Mode::Immediate => unreachable!(),
|
||||
Mode::Relative => *self.tape.get(self.pos as usize).unwrap_or(&0) + self.relative_base,
|
||||
};
|
||||
self.pos += 1;
|
||||
value
|
||||
}
|
||||
|
||||
fn decode_next(&mut self) -> Option<Operation> {
|
||||
let next = self.get_next(Mode::Immediate);
|
||||
let mut full_opcode: Vec<_> = next.to_string().chars().collect();
|
||||
|
@ -52,16 +63,19 @@ impl Amplifier {
|
|||
['0', '1'] => Some(Operation::Add {
|
||||
x: self.get_next(get_mode(&full_opcode, ParameterPosition::First)),
|
||||
y: self.get_next(get_mode(&full_opcode, ParameterPosition::Second)),
|
||||
addr: self.get_next(Mode::Immediate) as usize,
|
||||
addr: self.get_next_address(get_mode(&full_opcode, ParameterPosition::Third))
|
||||
as usize,
|
||||
}),
|
||||
['0', '2'] => Some(Operation::Multiply {
|
||||
x: self.get_next(get_mode(&full_opcode, ParameterPosition::First)),
|
||||
y: self.get_next(get_mode(&full_opcode, ParameterPosition::Second)),
|
||||
addr: self.get_next(Mode::Immediate) as usize,
|
||||
addr: self.get_next_address(get_mode(&full_opcode, ParameterPosition::Third))
|
||||
as usize,
|
||||
}),
|
||||
['0', '3'] => Some(Operation::Input {
|
||||
value: self.params.pop().unwrap(),
|
||||
addr: self.get_next(Mode::Immediate) as usize,
|
||||
addr: self.get_next_address(get_mode(&full_opcode, ParameterPosition::First))
|
||||
as usize,
|
||||
}),
|
||||
['0', '4'] => Some(Operation::Output {
|
||||
value: self.get_next(get_mode(&full_opcode, ParameterPosition::First)),
|
||||
|
@ -77,18 +91,20 @@ impl Amplifier {
|
|||
['0', '7'] => Some(Operation::LessThan {
|
||||
first: self.get_next(get_mode(&full_opcode, ParameterPosition::First)),
|
||||
second: self.get_next(get_mode(&full_opcode, ParameterPosition::Second)),
|
||||
addr: self.get_next(Mode::Immediate) as usize,
|
||||
addr: self.get_next_address(get_mode(&full_opcode, ParameterPosition::Third))
|
||||
as usize,
|
||||
}),
|
||||
['0', '8'] => Some(Operation::Equals {
|
||||
first: self.get_next(get_mode(&full_opcode, ParameterPosition::First)),
|
||||
second: self.get_next(get_mode(&full_opcode, ParameterPosition::Second)),
|
||||
addr: self.get_next(Mode::Immediate) as usize,
|
||||
addr: self.get_next_address(get_mode(&full_opcode, ParameterPosition::Third))
|
||||
as usize,
|
||||
}),
|
||||
['0', '9'] => Some(Operation::AdjustRelativeBase {
|
||||
value: self.get_next(get_mode(&full_opcode, ParameterPosition::First)),
|
||||
}),
|
||||
['9', '9'] => None,
|
||||
_ => unreachable!(),
|
||||
_ => unreachable!("Unknown opcode"),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -125,28 +141,58 @@ impl Amplifier {
|
|||
addr,
|
||||
} => safe_write(&mut self.tape, addr, (first == second) as i64),
|
||||
Operation::Output { value } => {
|
||||
println!("{}", value);
|
||||
return Some(value) },
|
||||
return Some(value);
|
||||
}
|
||||
};
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn get_mode(raw_opcode: &[char], pos: ParameterPosition) -> Mode {
|
||||
raw_opcode.get::<usize>(pos.into()).unwrap_or(&'0').into()
|
||||
let mode = raw_opcode.get::<usize>(pos.into()).unwrap_or(&'0').into();
|
||||
mode
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Operation {
|
||||
Add { x: i64, y: i64, addr: usize },
|
||||
Multiply { x: i64, y: i64, addr: usize },
|
||||
Input { value: i64, addr: usize },
|
||||
Output { value: i64 },
|
||||
JumpIfTrue { value: i64, addr: usize },
|
||||
JumpIfFalse { value: i64, addr: usize },
|
||||
LessThan { first: i64, second: i64, addr: usize },
|
||||
Equals { first: i64, second: i64, addr: usize },
|
||||
AdjustRelativeBase { value: i64 },
|
||||
Add {
|
||||
x: i64,
|
||||
y: i64,
|
||||
addr: usize,
|
||||
},
|
||||
Multiply {
|
||||
x: i64,
|
||||
y: i64,
|
||||
addr: usize,
|
||||
},
|
||||
Input {
|
||||
value: i64,
|
||||
addr: usize,
|
||||
},
|
||||
Output {
|
||||
value: i64,
|
||||
},
|
||||
JumpIfTrue {
|
||||
value: i64,
|
||||
addr: usize,
|
||||
},
|
||||
JumpIfFalse {
|
||||
value: i64,
|
||||
addr: usize,
|
||||
},
|
||||
LessThan {
|
||||
first: i64,
|
||||
second: i64,
|
||||
addr: usize,
|
||||
},
|
||||
Equals {
|
||||
first: i64,
|
||||
second: i64,
|
||||
addr: usize,
|
||||
},
|
||||
AdjustRelativeBase {
|
||||
value: i64,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -159,6 +205,7 @@ enum Mode {
|
|||
enum ParameterPosition {
|
||||
First,
|
||||
Second,
|
||||
Third,
|
||||
}
|
||||
|
||||
impl Into<usize> for ParameterPosition {
|
||||
|
@ -166,6 +213,7 @@ impl Into<usize> for ParameterPosition {
|
|||
match self {
|
||||
ParameterPosition::First => 2,
|
||||
ParameterPosition::Second => 3,
|
||||
ParameterPosition::Third => 4,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use amplifier::*;
|
||||
use itertools::Itertools;
|
||||
use std::convert::TryFrom;
|
||||
use std::io::{self, BufRead};
|
||||
use std::ops::Range;
|
||||
use amplifier::*;
|
||||
mod amplifier;
|
||||
|
||||
/**
|
||||
|
|
|
@ -41,6 +41,7 @@ fn test_find_max_with_loops() {
|
|||
),
|
||||
Some(139629729)
|
||||
);
|
||||
/*
|
||||
assert_eq!(
|
||||
find_max(
|
||||
5..10,
|
||||
|
@ -48,6 +49,7 @@ fn test_find_max_with_loops() {
|
|||
),
|
||||
Some(18216)
|
||||
);
|
||||
*/
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -162,3 +164,23 @@ fn test_large_output() {
|
|||
1125899906842624
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_gattix() {
|
||||
assert_eq!(
|
||||
run_for_input(
|
||||
&parse_test_input("109,5,1,2,1,0,203,-4,2,0,1,20,204,15,99"),
|
||||
&mut 0,
|
||||
vec![2]
|
||||
),
|
||||
12
|
||||
);
|
||||
assert_eq!(
|
||||
run_for_input(
|
||||
&parse_test_input("109,5,1,2,1,0,203,-4,2,0,1,20,204,15,99"),
|
||||
&mut 0,
|
||||
vec![7]
|
||||
),
|
||||
42
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user