Add D5P2 in Rust

This commit is contained in:
kageru 2019-12-05 21:43:09 +01:00
parent 4a1063c522
commit f1b4cb6e94
Signed by: kageru
GPG Key ID: 8282A2BEA4ADA3D2

@ -7,6 +7,10 @@ enum Operation {
Multiply { x: i32, y: i32, addr: usize }, Multiply { x: i32, y: i32, addr: usize },
Input { value: i32, addr: usize }, Input { value: i32, addr: usize },
Output { value: i32 }, Output { value: i32 },
JumpIfTrue { value: i32, addr: i32 },
JumpIfFalse { value: i32, addr: i32 },
LessThan { first: i32, second: i32, addr: i32 },
Equals { first: i32, second: i32, addr: i32 },
} }
#[derive(Debug)] #[derive(Debug)]
@ -41,12 +45,10 @@ impl Into<Mode> for &char {
fn get_next(input: &Vec<i32>, pos: &mut i32, mode: Mode) -> i32 { fn get_next(input: &Vec<i32>, pos: &mut i32, mode: Mode) -> i32 {
let value = input[*pos as usize]; let value = input[*pos as usize];
//dbg!(&mode, &pos, value);
let next = match mode { let next = match mode {
Mode::Position => input[value as usize], Mode::Position => input[value as usize],
Mode::Immediate => value, Mode::Immediate => value,
}; };
//dbg!(&next);
*pos += 1; *pos += 1;
next next
} }
@ -55,11 +57,10 @@ fn get_mode(raw_opcode: &Vec<char>, pos: ParameterPosition) -> Mode {
raw_opcode.get::<usize>(pos.into()).unwrap_or(&'0').into() raw_opcode.get::<usize>(pos.into()).unwrap_or(&'0').into()
} }
fn next_operation(input: &Vec<i32>, pos: &mut i32) -> Option<Operation> { fn next_operation(input: &Vec<i32>, pos: &mut i32, inp: i32) -> Option<Operation> {
let next = get_next(input, pos, Mode::Immediate); let next = get_next(input, pos, Mode::Immediate);
let mut raw_opcode: Vec<_> = next.to_string().chars().collect(); let mut raw_opcode: Vec<_> = next.to_string().chars().collect();
raw_opcode.reverse(); raw_opcode.reverse();
//dbg!(&raw_opcode);
match raw_opcode[0] { match raw_opcode[0] {
'1' => Some(Operation::Add { '1' => Some(Operation::Add {
x: get_next(input, pos, get_mode(&raw_opcode, ParameterPosition::First)), x: get_next(input, pos, get_mode(&raw_opcode, ParameterPosition::First)),
@ -72,24 +73,65 @@ fn next_operation(input: &Vec<i32>, pos: &mut i32) -> Option<Operation> {
addr: get_next(input, pos, Mode::Immediate) as usize, addr: get_next(input, pos, Mode::Immediate) as usize,
}), }),
'3' => Some(Operation::Input { '3' => Some(Operation::Input {
value: 1, value: inp,
addr: get_next(input, pos, Mode::Immediate) as usize, addr: get_next(input, pos, Mode::Immediate) as usize,
}), }),
'4' => Some(Operation::Output { '4' => Some(Operation::Output {
value: get_next(input, pos, get_mode(&raw_opcode, ParameterPosition::First)), value: get_next(input, pos, get_mode(&raw_opcode, ParameterPosition::First)),
}), }),
'5' => Some(Operation::JumpIfTrue {
value: get_next(input, pos, get_mode(&raw_opcode, ParameterPosition::First)),
addr: get_next(input, pos, get_mode(&raw_opcode, ParameterPosition::Second)),
}),
'6' => Some(Operation::JumpIfFalse {
value: get_next(input, pos, get_mode(&raw_opcode, ParameterPosition::First)),
addr: get_next(input, pos, get_mode(&raw_opcode, ParameterPosition::Second)),
}),
'7' => Some(Operation::LessThan {
first: get_next(input, pos, get_mode(&raw_opcode, ParameterPosition::First)),
second: get_next(input, pos, get_mode(&raw_opcode, ParameterPosition::Second)),
addr: get_next(input, pos, Mode::Immediate),
}),
'8' => Some(Operation::Equals {
first: get_next(input, pos, get_mode(&raw_opcode, ParameterPosition::First)),
second: get_next(input, pos, get_mode(&raw_opcode, ParameterPosition::Second)),
addr: get_next(input, pos, Mode::Immediate),
}),
'9' => None, '9' => None,
_ => unreachable!(), _ => unreachable!(),
} }
} }
fn execute(op: Operation, input: &mut Vec<i32>) { fn execute(op: Operation, input: &mut Vec<i32>, pos: &mut i32) {
//dbg!(&op);
match op { match op {
Operation::Add { x, y, addr } => input[addr as usize] = x + y, Operation::Add { x, y, addr } => input[addr as usize] = x + y,
Operation::Multiply { x, y, addr } => input[addr as usize] = x * y, Operation::Multiply { x, y, addr } => input[addr as usize] = x * y,
Operation::Input { value, addr } => input[addr] = value, Operation::Input { value, addr } => input[addr] = value,
Operation::Output { value } => println!("{}", value), Operation::Output { value } => {
if value != 0 {
println!("{}", value)
}
}
Operation::JumpIfTrue { value, addr } => {
if value != 0 {
*pos = addr
}
}
Operation::JumpIfFalse { value, addr } => {
if value == 0 {
*pos = addr
}
}
Operation::LessThan {
first,
second,
addr,
} => input[addr as usize] = (first < second) as i32,
Operation::Equals {
first,
second,
addr,
} => input[addr as usize] = (first == second) as i32,
} }
} }
@ -104,9 +146,16 @@ pub fn main() {
.map(|n| n.parse().unwrap()) .map(|n| n.parse().unwrap())
.collect(); .collect();
let mut pos = 0; let mut pos = 0;
//dbg!(&input); let mut part2_input = input.clone();
while let Some(op) = next_operation(&input, &mut pos) { println!("Part 1:");
execute(op, &mut input); while let Some(op) = next_operation(&input, &mut pos, 1) {
execute(op, &mut input, &mut pos);
}
pos = 0;
println!("Part 2:");
while let Some(op) = next_operation(&part2_input, &mut pos, 5) {
execute(op, &mut part2_input, &mut pos);
} }
} }