From de9fb772c707aaf3c6cbc3cc24b2a42aeced8920 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Gr=C3=A9gory=20Burri?= Date: Mon, 9 Dec 2019 14:54:35 +0100 Subject: [PATCH] Day 05 --- src/day05.rs | 111 ++++++++++++++++++++++++++++++++++++++++++++++----- src/main.rs | 11 +++++ 2 files changed, 112 insertions(+), 10 deletions(-) diff --git a/src/day05.rs b/src/day05.rs index 1ff5739..61f6203 100644 --- a/src/day05.rs +++ b/src/day05.rs @@ -1,33 +1,124 @@ -fn read_code(code: i32) -> (i32, Vec) { +// 'true' -> immediate mode, 'false' -> position mode. +fn read_op_and_modes(mut code: i32) -> (i32, [bool; 3]) { + let mut modes: [bool; 3] = [ false, false, false ]; + if code >= 10_000 { + modes[2] = true; + code -= 10_000; + } + + if code >= 1_000 { + modes[1] = true; + code -= 1_000; + } + + if code >= 100 { + modes[0] = true; + code -= 100; + } + + (code, modes) } -fn execute_op_code(code: &mut [i32], input: &[i32]) -> Vec { +pub fn execute_op_code(code: &mut [i32], input: &[i32]) -> Vec { let mut cursor = 0; + let mut input_cursor = 0; let mut output = Vec::::new(); + + fn read(position: usize, code: &[i32], mode: bool) -> i32 { + if mode { code[position] } else { code[code[position] as usize] } + }; + + fn jump_if(cond: bool, cursor: usize, code: &[i32], modes: [bool; 3]) -> usize { + let value = read(cursor + 1, &code, modes[0]); + if cond == (value != 0) { + read(cursor + 2, &code, modes[1]) as usize + } else { + cursor + 3 + } + }; + loop { - match code[cursor] { - 1 => code[code[cursor + 3] as usize] = code[code[cursor + 1] as usize] + code[code[cursor + 2] as usize], - 2 => code[code[cursor + 3] as usize] = code[code[cursor + 1] as usize] * code[code[cursor + 2] as usize], - 99 => return code[0], + let (op, modes) = read_op_and_modes(code[cursor]); + + match op { + // Sum. + 1 => { + code[code[cursor + 3] as usize] = read(cursor + 1, &code, modes[0]) + read(cursor + 2, &code, modes[1]); + cursor += 4; + }, + + // Multiply. + 2 => { + code[code[cursor + 3] as usize] = read(cursor + 1, &code, modes[0]) * read(cursor + 2, &code, modes[1]); + cursor += 4; + }, + + // Input. + 3 => { + code[code[cursor + 1] as usize] = input[input_cursor]; + input_cursor += 1; + cursor += 2; + } + + // Output. + 4 => { + output.push(read(cursor + 1, &code, modes[0])); + cursor += 2; + } + + // Jump-if-true. + 5 => cursor = jump_if(true, cursor, &code, modes), + + // Jump-if-false. + 6 => cursor = jump_if(false, cursor, &code, modes), + + // Less than. + 7 => { + code[code[cursor + 3] as usize] = + if read(cursor + 1, &code, modes[0]) < read(cursor + 2, &code, modes[1]) { 1 } else { 0 }; + cursor += 4; + }, + + // Equals. + 8 => { + code[code[cursor + 3] as usize] = + if read(cursor + 1, &code, modes[0]) == read(cursor + 2, &code, modes[1]) { 1 } else { 0 }; + cursor += 4; + }, + + 99 => break, _ => panic!("Unkown code: {}", code[cursor]) } - cursor += 4; } + output } - - - #[cfg(test)] mod tests { use super::*; #[test] fn part1() { + let mut c = [1002, 4, 3, 4, 33]; + let _ = execute_op_code(&mut c, &Vec::new()); + assert_eq!(c[4], 99); } #[test] fn part2() { + let c = [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]; + + let mut c1 = c; + let r1 = execute_op_code(&mut c1, &[7]); + assert_eq!(r1[0], 999); + + let mut c2 = c; + let r2 = execute_op_code(&mut c2, &[8]); + assert_eq!(r2[0], 1000); + + let mut c3 = c; + let r3 = execute_op_code(&mut c3, &[9]); + assert_eq!(r3[0], 1001); } } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index d0dbfc3..eaccb71 100644 --- a/src/main.rs +++ b/src/main.rs @@ -29,6 +29,15 @@ fn day03() -> String { ) } +fn day04() -> String { + format!("") +} + +fn day05() -> String { + let code = common::read_list_of_numbers("data/day05.input", ","); + format!("part1: {:?}, part2: {:?}", day05::execute_op_code(&mut Vec::from(&code[..]), &[1]), day05::execute_op_code(&mut Vec::from(&code[..]), &[5])) +} + fn day06() -> String { let file_content = fs::read_to_string("data/day06.input").unwrap(); let lines: Vec<&str> = file_content.lines().collect(); @@ -58,6 +67,8 @@ fn main() { day01, day02, day03, + day04, + day05, day06 ); -- 2.45.2