From f1b4cb6e9455e771cb9eff9c0c76d7d46d7c87a5 Mon Sep 17 00:00:00 2001 From: kageru Date: Thu, 5 Dec 2019 21:43:09 +0100 Subject: [PATCH] Add D5P2 in Rust --- 2019/05/src/main.rs | 71 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 60 insertions(+), 11 deletions(-) diff --git a/2019/05/src/main.rs b/2019/05/src/main.rs index ede3f12..def29b7 100644 --- a/2019/05/src/main.rs +++ b/2019/05/src/main.rs @@ -7,6 +7,10 @@ enum Operation { Multiply { x: i32, y: i32, addr: usize }, Input { value: i32, addr: usize }, 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)] @@ -41,12 +45,10 @@ impl Into for &char { fn get_next(input: &Vec, pos: &mut i32, mode: Mode) -> i32 { let value = input[*pos as usize]; - //dbg!(&mode, &pos, value); let next = match mode { Mode::Position => input[value as usize], Mode::Immediate => value, }; - //dbg!(&next); *pos += 1; next } @@ -55,11 +57,10 @@ fn get_mode(raw_opcode: &Vec, pos: ParameterPosition) -> Mode { raw_opcode.get::(pos.into()).unwrap_or(&'0').into() } -fn next_operation(input: &Vec, pos: &mut i32) -> Option { +fn next_operation(input: &Vec, pos: &mut i32, inp: i32) -> Option { let next = get_next(input, pos, Mode::Immediate); let mut raw_opcode: Vec<_> = next.to_string().chars().collect(); raw_opcode.reverse(); - //dbg!(&raw_opcode); match raw_opcode[0] { '1' => Some(Operation::Add { x: get_next(input, pos, get_mode(&raw_opcode, ParameterPosition::First)), @@ -72,24 +73,65 @@ fn next_operation(input: &Vec, pos: &mut i32) -> Option { addr: get_next(input, pos, Mode::Immediate) as usize, }), '3' => Some(Operation::Input { - value: 1, + value: inp, addr: get_next(input, pos, Mode::Immediate) as usize, }), '4' => Some(Operation::Output { 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, _ => unreachable!(), } } -fn execute(op: Operation, input: &mut Vec) { - //dbg!(&op); +fn execute(op: Operation, input: &mut Vec, pos: &mut i32) { match op { Operation::Add { 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::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()) .collect(); let mut pos = 0; - //dbg!(&input); + let mut part2_input = input.clone(); - while let Some(op) = next_operation(&input, &mut pos) { - execute(op, &mut input); + println!("Part 1:"); + 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); } }