--- /dev/null
+3,8,1005,8,305,1106,0,11,0,0,0,104,1,104,0,3,8,1002,8,-1,10,101,1,10,10,4,10,1008,8,0,10,4,10,1002,8,1,29,3,8,102,-1,8,10,1001,10,1,10,4,10,108,1,8,10,4,10,1002,8,1,50,1,104,20,10,1,1102,6,10,1006,0,13,3,8,102,-1,8,10,101,1,10,10,4,10,108,1,8,10,4,10,102,1,8,83,1,1102,0,10,1006,0,96,2,1004,19,10,3,8,1002,8,-1,10,101,1,10,10,4,10,108,0,8,10,4,10,101,0,8,116,3,8,1002,8,-1,10,1001,10,1,10,4,10,108,1,8,10,4,10,102,1,8,138,1006,0,60,1,1008,12,10,3,8,102,-1,8,10,101,1,10,10,4,10,1008,8,0,10,4,10,102,1,8,168,1006,0,14,1006,0,28,3,8,1002,8,-1,10,1001,10,1,10,4,10,108,0,8,10,4,10,101,0,8,195,2,1005,9,10,1006,0,29,3,8,1002,8,-1,10,101,1,10,10,4,10,108,1,8,10,4,10,1002,8,1,224,2,1009,8,10,1,3,5,10,3,8,1002,8,-1,10,101,1,10,10,4,10,108,1,8,10,4,10,102,1,8,254,3,8,102,-1,8,10,1001,10,1,10,4,10,1008,8,0,10,4,10,1002,8,1,277,1,1003,18,10,1,1104,1,10,101,1,9,9,1007,9,957,10,1005,10,15,99,109,627,104,0,104,1,21101,0,666681062292,1,21102,322,1,0,1105,1,426,21101,847073883028,0,1,21102,333,1,0,1105,1,426,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,21101,0,179356855319,1,21102,1,380,0,1105,1,426,21102,1,179356998696,1,21102,1,391,0,1105,1,426,3,10,104,0,104,0,3,10,104,0,104,0,21101,0,988669698816,1,21101,0,414,0,1106,0,426,21102,1,868494500628,1,21102,425,1,0,1106,0,426,99,109,2,21202,-1,1,1,21102,1,40,2,21102,457,1,3,21102,1,447,0,1105,1,490,109,-2,2105,1,0,0,1,0,0,1,109,2,3,10,204,-1,1001,452,453,468,4,0,1001,452,1,452,108,4,452,10,1006,10,484,1102,0,1,452,109,-2,2105,1,0,0,109,4,1201,-1,0,489,1207,-3,0,10,1006,10,507,21102,0,1,-3,22101,0,-3,1,21202,-2,1,2,21101,1,0,3,21102,1,526,0,1106,0,531,109,-4,2105,1,0,109,5,1207,-3,1,10,1006,10,554,2207,-4,-2,10,1006,10,554,22101,0,-4,-4,1106,0,622,21201,-4,0,1,21201,-3,-1,2,21202,-2,2,3,21102,573,1,0,1106,0,531,21202,1,1,-4,21101,1,0,-1,2207,-4,-2,10,1006,10,592,21102,1,0,-1,22202,-2,-1,-2,2107,0,-3,10,1006,10,614,22101,0,-1,1,21102,614,1,0,105,1,489,21202,-2,-1,-2,22201,-4,-2,-4,109,-5,2105,1,0
\ No newline at end of file
\r
{\r
fs::read_to_string(file).unwrap().split(sep).map(|line| line.parse::<T>().unwrap()).collect()\r
+}\r
+\r
+pub fn layer_to_printable_string(layer: &[u8], width: usize) -> String {\r
+ let mut result = String::new();\r
+ let mut i = 0;\r
+\r
+ loop {\r
+ for _ in 0 .. width {\r
+ if layer[i] == 0 {\r
+ result += " ";\r
+ } else {\r
+ result += "█";\r
+ }\r
+ i += 1;\r
+ if i >= layer.len() { return result }\r
+ }\r
+ result += "\n";\r
+ }\r
}
\ No newline at end of file
1 => code[code[cursor + 3] as usize] = code[code[cursor + 1] as usize] + code[code[cursor + 2] as usize],\r
2 => code[code[cursor + 3] as usize] = code[code[cursor + 1] as usize] * code[code[cursor + 2] as usize],\r
99 => return code[0],\r
- _ => panic!("Unkown code: {}", code[cursor])\r
+ _ => panic!("Unknown code: {}", code[cursor])\r
}\r
cursor += 4;\r
}\r
+++ /dev/null
-// 'true' -> immediate mode, 'false' -> position mode.\r
-fn read_op_and_modes(mut code: i32) -> (i32, [bool; 3]) {\r
- let mut modes: [bool; 3] = [ false, false, false ];\r
-\r
- if code >= 10_000 {\r
- modes[2] = true;\r
- code -= 10_000;\r
- }\r
-\r
- if code >= 1_000 {\r
- modes[1] = true;\r
- code -= 1_000;\r
- }\r
-\r
- if code >= 100 {\r
- modes[0] = true;\r
- code -= 100;\r
- }\r
-\r
- (code, modes)\r
-}\r
-\r
-pub fn execute_op_code(code: &mut [i32], input: &[i32]) -> Vec<i32> {\r
- let mut cursor = 0;\r
- let mut input_cursor = 0;\r
- let mut output = Vec::<i32>::new();\r
-\r
- fn read(position: usize, code: &[i32], mode: bool) -> i32 {\r
- if mode { code[position] } else { code[code[position] as usize] }\r
- };\r
-\r
- fn jump_if(cond: bool, cursor: usize, code: &[i32], modes: [bool; 3]) -> usize {\r
- let value = read(cursor + 1, &code, modes[0]);\r
- if cond == (value != 0) {\r
- read(cursor + 2, &code, modes[1]) as usize\r
- } else {\r
- cursor + 3\r
- }\r
- };\r
-\r
- loop {\r
- let (op, modes) = read_op_and_modes(code[cursor]);\r
-\r
- match op {\r
- // Sum.\r
- 1 => {\r
- code[code[cursor + 3] as usize] = read(cursor + 1, &code, modes[0]) + read(cursor + 2, &code, modes[1]);\r
- cursor += 4;\r
- },\r
-\r
- // Multiply.\r
- 2 => {\r
- code[code[cursor + 3] as usize] = read(cursor + 1, &code, modes[0]) * read(cursor + 2, &code, modes[1]);\r
- cursor += 4;\r
- },\r
-\r
- // Input.\r
- 3 => {\r
- code[code[cursor + 1] as usize] = input[input_cursor];\r
- input_cursor += 1;\r
- cursor += 2;\r
- }\r
-\r
- // Output.\r
- 4 => {\r
- output.push(read(cursor + 1, &code, modes[0]));\r
- cursor += 2;\r
- }\r
-\r
- // Jump-if-true.\r
- 5 => cursor = jump_if(true, cursor, &code, modes),\r
-\r
- // Jump-if-false.\r
- 6 => cursor = jump_if(false, cursor, &code, modes),\r
-\r
- // Less than.\r
- 7 => {\r
- code[code[cursor + 3] as usize] =\r
- if read(cursor + 1, &code, modes[0]) < read(cursor + 2, &code, modes[1]) { 1 } else { 0 };\r
- cursor += 4;\r
- },\r
-\r
- // Equals.\r
- 8 => {\r
- code[code[cursor + 3] as usize] =\r
- if read(cursor + 1, &code, modes[0]) == read(cursor + 2, &code, modes[1]) { 1 } else { 0 };\r
- cursor += 4;\r
- },\r
-\r
- 99 => break,\r
- _ => panic!("Unkown code: {}", code[cursor])\r
- }\r
- }\r
- output\r
-}\r
-\r
-#[cfg(test)]\r
-mod tests {\r
- use super::*;\r
-\r
- #[test]\r
- fn part1() {\r
- let mut c = [1002, 4, 3, 4, 33];\r
- let _ = execute_op_code(&mut c, &Vec::new());\r
- assert_eq!(c[4], 99);\r
- }\r
-\r
- #[test]\r
- fn part2() {\r
- 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];\r
-\r
- let mut c1 = c;\r
- let r1 = execute_op_code(&mut c1, &[7]);\r
- assert_eq!(r1[0], 999);\r
-\r
- let mut c2 = c;\r
- let r2 = execute_op_code(&mut c2, &[8]);\r
- assert_eq!(r2[0], 1000);\r
-\r
- let mut c3 = c;\r
- let r3 = execute_op_code(&mut c3, &[9]);\r
- assert_eq!(r3[0], 1001);\r
- }\r
-}
\ No newline at end of file
}
#[cfg(test)]
-mod test {
+mod tests {
use super::*;
#[test]
+\r
+\r
+\r
+#[cfg(test)]\r
+mod tests {\r
+\r
+ #[test]\r
+ fn part1 () {\r
+\r
+ }\r
+}
\ No newline at end of file
result
}
-pub fn layer_to_printable_string(layer: &[u8], width: u32) -> String {
- let mut result = String::new();
- let mut i = 0;
-
- loop {
- for _ in 0 .. width {
- if layer[i] == 0 {
- result += " ";
- } else {
- result += "█";
- }
- i += 1;
- if i >= layer.len() { return result }
- }
- result += "\n";
- }
-}
-
pub fn one_digits_times_two_digits(layer: &[u8]) -> u32 {
count(layer, 1) * count(layer, 2)
}
+++ /dev/null
-#[derive(Copy, Clone, Debug)]\r
-enum Mode {\r
- Position,\r
- Immediate,\r
- Relative\r
-}\r
-\r
-// 'true' -> immediate mode, 'false' -> position mode.\r
-fn read_op_and_modes(mut code: i64) -> (i64, [Mode; 3]) {\r
- let mut modes: [Mode; 3] = [ Mode::Position, Mode::Position, Mode::Position ];\r
-\r
- for i in (2..=4).rev() {\r
- let power = 10i64.pow(i);\r
- if code >= 2 * power {\r
- modes[i as usize - 2] = Mode::Relative;\r
- code -= 2 * power;\r
- } else if code >= power {\r
- modes[i as usize - 2] = Mode::Immediate;\r
- code -= power;\r
- }\r
- }\r
-\r
- (code, modes)\r
-}\r
-\r
-pub fn execute_op_code(code: &[i64], input: &[i64]) -> Vec<i64> {\r
- let mut code = Vec::from(code);\r
- let mut cursor = 0;\r
- let mut input_cursor = 0;\r
- let mut output = Vec::<i64>::new();\r
- let mut relative_base = 0;\r
-\r
- fn read(position: usize, code: &[i64], mode: Mode, relative_base: i64) -> i64 {\r
- if position >= code.len() { return 0 }\r
-\r
- match mode {\r
- Mode::Position => if code[position] as usize >= code.len() { 0 } else { code[code[position] as usize] },\r
- Mode::Immediate => code[position],\r
- Mode::Relative => if (code[position] + relative_base) as usize >= code.len() { 0 } else { code[(code[position] + relative_base) as usize] }\r
- }\r
- };\r
-\r
- fn write(position: usize, value: i64, code: &mut Vec<i64>, mode: Mode, relative_base: i64) {\r
- let ref_position =\r
- match mode {\r
- Mode::Position => code[position] as usize,\r
- Mode::Immediate => panic!("Can't write un immediate mode"),\r
- Mode::Relative => (code[position] + relative_base) as usize\r
- };\r
-\r
- if ref_position >= code.len() {\r
- code.resize(ref_position + 1, 0);\r
- }\r
-\r
- code[ref_position] = value;\r
- }\r
-\r
- fn jump_if(cond: bool, cursor: usize, code: &[i64], modes: [Mode; 3], relative_base: i64) -> usize {\r
- let value = read(cursor + 1, &code, modes[0], relative_base);\r
- if cond == (value != 0) {\r
- read(cursor + 2, &code, modes[1], relative_base) as usize\r
- } else {\r
- cursor + 3\r
- }\r
- };\r
-\r
- loop {\r
- let (op, modes) = read_op_and_modes(code[cursor]);\r
-\r
- match op {\r
- // Sum.\r
- 1 => {\r
- write(cursor + 3, read(cursor + 1, &code, modes[0], relative_base) + read(cursor + 2, &code, modes[1], relative_base), &mut code, modes[2], relative_base);\r
- cursor += 4;\r
- },\r
-\r
- // Multiply.\r
- 2 => {\r
- write(cursor + 3, read(cursor + 1, &code, modes[0], relative_base) * read(cursor + 2, &code, modes[1], relative_base), &mut code, modes[2], relative_base);\r
- cursor += 4;\r
- },\r
-\r
- // Input.\r
- 3 => {\r
- write(cursor + 1, input[input_cursor], &mut code, modes[0], relative_base);\r
- input_cursor += 1;\r
- cursor += 2;\r
- }\r
-\r
- // Output.\r
- 4 => {\r
- output.push(read(cursor + 1, &code, modes[0], relative_base));\r
- cursor += 2;\r
- }\r
-\r
- // Jump-if-true.\r
- 5 => cursor = jump_if(true, cursor, &code, modes, relative_base),\r
-\r
- // Jump-if-false.\r
- 6 => cursor = jump_if(false, cursor, &code, modes, relative_base),\r
-\r
- // Less than.\r
- 7 => {\r
- write(cursor + 3, if read(cursor + 1, &code, modes[0], relative_base) < read(cursor + 2, &code, modes[1], relative_base) { 1 } else { 0 }, &mut code, modes[2], relative_base);\r
- cursor += 4;\r
- },\r
-\r
- // Equals.\r
- 8 => {\r
- write(cursor + 3, if read(cursor + 1, &code, modes[0], relative_base) == read(cursor + 2, &code, modes[1], relative_base) { 1 } else { 0 }, &mut code, modes[2], relative_base);\r
- cursor += 4;\r
- },\r
-\r
- // Change relative base.\r
- 9 => {\r
- relative_base += read(cursor + 1, &code, modes[0], relative_base);\r
- cursor += 2;\r
- }\r
-\r
- 99 => break,\r
-\r
- _ => panic!("Unkown code: {}", code[cursor])\r
- }\r
- }\r
- output\r
-}\r
-\r
-#[cfg(test)]\r
-mod tests {\r
- use super::*;\r
-\r
- #[test]\r
- fn copy_of_itself() {\r
- let c = [109,1,204,-1,1001,100,1,100,1008,100,16,101,1006,101,0,99];\r
- let r = execute_op_code(&c, &Vec::new());\r
- assert_eq!(r, c);\r
- }\r
-\r
- #[test]\r
- fn output_big_number() {\r
- let c = [1102,34_915_192,34_915_192,7,4,7,99,0];\r
- let r = execute_op_code(&c, &Vec::new());\r
- assert_eq!(r[0], 1_219_070_632_396_864);\r
- }\r
-\r
- #[test]\r
- fn input_big_number() {\r
- let c = [104,1_125_899_906_842_624,99];\r
- let r = execute_op_code(&c, &Vec::new());\r
- assert_eq!(r[0], 1_125_899_906_842_624);\r
- }\r
-}
\ No newline at end of file
--- /dev/null
+use std::collections::HashMap;\r
+use super::intcode;\r
+\r
+enum NextCommand {\r
+ ColorToPaint,\r
+ Turn\r
+}\r
+\r
+struct Robot {\r
+ next_command: NextCommand,\r
+ current_pos: (i32, i32),\r
+ current_dir: i32, // 0: up, 1: right, 2: down, 3: left.\r
+ panels: HashMap<(i32, i32), i64>\r
+}\r
+\r
+impl Robot {\r
+ fn new() -> Self {\r
+ Robot {\r
+ next_command: NextCommand::ColorToPaint,\r
+ current_pos: (0, 0),\r
+ current_dir: 0,\r
+ panels: HashMap::new()\r
+ }\r
+ }\r
+}\r
+\r
+impl intcode::IO for Robot {\r
+ fn read(&mut self) -> i64 {\r
+ *self.panels.get(&self.current_pos).unwrap_or(&0)\r
+ }\r
+\r
+ fn write(&mut self, value: i64) {\r
+ self.next_command =\r
+ match self.next_command {\r
+ NextCommand::ColorToPaint => { self.panels.insert(self.current_pos, value); NextCommand::Turn },\r
+ NextCommand::Turn => {\r
+ self.current_dir = (self.current_dir + if value == 0 { 3 } else { 1 }) % 4;\r
+ self.current_pos =\r
+ match self.current_dir {\r
+ 0 => (self.current_pos.0, self.current_pos.1 + 1),\r
+ 1 => (self.current_pos.0 + 1, self.current_pos.1),\r
+ 2 => (self.current_pos.0, self.current_pos.1 - 1),\r
+ 3 | _ => (self.current_pos.0 - 1, self.current_pos.1)\r
+ };\r
+ NextCommand::ColorToPaint\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+pub fn run_robot(code: &[i64], initial_value: i64) -> HashMap<(i32, i32), i64> {\r
+ let mut robot = Robot::new();\r
+ if initial_value != 0 {\r
+ robot.panels.insert((0, 0), initial_value);\r
+ }\r
+\r
+ intcode::execute_op_code_with_custom_io(code, &mut robot);\r
+ robot.panels\r
+}\r
+\r
+pub fn panels_to_layer(panels: &HashMap<(i32, i32), i64>) -> (Vec<u8>, usize) {\r
+ let coordinates: Vec<&(i32, i32)> = panels.keys().collect();\r
+ let min_x = coordinates.iter().min_by_key(|(x, _)| x).unwrap().0;\r
+ let max_x = coordinates.iter().max_by_key(|(x, _)| x).unwrap().0;\r
+ let min_y = coordinates.iter().min_by_key(|(_, y)| y).unwrap().1;\r
+ let max_y = coordinates.iter().max_by_key(|(_, y)| y).unwrap().1;\r
+\r
+ let width = (max_x - min_x) as usize + 1;\r
+ let height = (max_y - min_y) as usize + 1;\r
+\r
+ let mut layer = Vec::new();\r
+ layer.resize(width * height, 0);\r
+\r
+ for x in min_x ..= max_x {\r
+ for y in min_y ..= max_y {\r
+ let pos = (x - min_x) + ((height as i32 - y + min_y - 1) * width as i32); // Y axis is down.\r
+ layer[pos as usize] = *panels.get(&(x, y)).unwrap_or(&0) as u8;\r
+ }\r
+ }\r
+\r
+ (layer, width)\r
+}\r
+\r
+#[cfg(test)]\r
+mod tests {\r
+ use super::*;\r
+ use super::intcode::IO;\r
+\r
+ #[test]\r
+ fn part1() {\r
+ let mut robot = Robot::new();\r
+ robot.write(1); // Paint white.\r
+ robot.write(0); // Turn left.\r
+\r
+ robot.write(0); // Paint black.\r
+ robot.write(0); // Turn left.\r
+\r
+ robot.write(1); // Paint white.\r
+ robot.write(0); // Turn left.\r
+\r
+ robot.write(1); // Paint white.\r
+ robot.write(0); // Turn left.\r
+\r
+ robot.write(0); // Paint black.\r
+ robot.write(1); // Turn right.\r
+\r
+ robot.write(1); // Paint white.\r
+ robot.write(0); // Turn left.\r
+\r
+ robot.write(1); // Paint white.\r
+ robot.write(0); // Turn left.\r
+\r
+ assert_eq!(robot.panels.len(), 6);\r
+ }\r
+\r
+}
\ No newline at end of file
--- /dev/null
+#[derive(Copy, Clone, Debug)]\r
+enum Mode {\r
+ Position,\r
+ Immediate,\r
+ Relative\r
+}\r
+\r
+pub trait IO {\r
+ fn read(&mut self) -> i64;\r
+ fn write(&mut self, value: i64);\r
+}\r
+\r
+struct Buffer {\r
+ output: Vec<i64>,\r
+ input: Vec<i64>\r
+}\r
+\r
+impl Buffer {\r
+ fn from(input: &[i64]) -> Self {\r
+ Buffer {\r
+ output: Vec::new(),\r
+ input: Vec::from(input)\r
+ }\r
+ }\r
+}\r
+\r
+impl IO for Buffer {\r
+ fn read(&mut self) -> i64 {\r
+ self.input.remove(0)\r
+ }\r
+\r
+ fn write(&mut self, value: i64) {\r
+ self.output.push(value)\r
+ }\r
+}\r
+\r
+// 'true' -> immediate mode, 'false' -> position mode.\r
+fn read_op_and_modes(mut code: i64) -> (i64, [Mode; 3]) {\r
+ let mut modes: [Mode; 3] = [ Mode::Position, Mode::Position, Mode::Position ];\r
+\r
+ for i in (2..=4).rev() {\r
+ let power = 10i64.pow(i);\r
+ if code >= 2 * power {\r
+ modes[i as usize - 2] = Mode::Relative;\r
+ code -= 2 * power;\r
+ } else if code >= power {\r
+ modes[i as usize - 2] = Mode::Immediate;\r
+ code -= power;\r
+ }\r
+ }\r
+\r
+ (code, modes)\r
+}\r
+\r
+pub fn execute_op_code(code: &[i64], input: &[i64]) -> Vec<i64> {\r
+ let mut buffer = Buffer::from(input);\r
+ execute_op_code_with_custom_io(code, &mut buffer);\r
+ buffer.output\r
+}\r
+\r
+pub fn execute_op_code_with_custom_io(code: &[i64], io: &mut dyn IO) {\r
+ let mut code = Vec::from(code);\r
+ let mut cursor = 0;\r
+ let mut relative_base = 0;\r
+\r
+ fn read(position: usize, code: &[i64], mode: Mode, relative_base: i64) -> i64 {\r
+ if position >= code.len() { return 0 }\r
+\r
+ match mode {\r
+ Mode::Position => if code[position] as usize >= code.len() { 0 } else { code[code[position] as usize] },\r
+ Mode::Immediate => code[position],\r
+ Mode::Relative => if (code[position] + relative_base) as usize >= code.len() { 0 } else { code[(code[position] + relative_base) as usize] }\r
+ }\r
+ };\r
+\r
+ fn write(position: usize, value: i64, code: &mut Vec<i64>, mode: Mode, relative_base: i64) {\r
+ let ref_position =\r
+ match mode {\r
+ Mode::Position => code[position] as usize,\r
+ Mode::Immediate => panic!("Can't write un immediate mode"),\r
+ Mode::Relative => (code[position] + relative_base) as usize\r
+ };\r
+\r
+ if ref_position >= code.len() {\r
+ code.resize(ref_position + 1, 0);\r
+ }\r
+\r
+ code[ref_position] = value;\r
+ }\r
+\r
+ fn jump_if(cond: bool, cursor: usize, code: &[i64], modes: [Mode; 3], relative_base: i64) -> usize {\r
+ let value = read(cursor + 1, &code, modes[0], relative_base);\r
+ if cond == (value != 0) {\r
+ read(cursor + 2, &code, modes[1], relative_base) as usize\r
+ } else {\r
+ cursor + 3\r
+ }\r
+ };\r
+\r
+ loop {\r
+ let (op, modes) = read_op_and_modes(code[cursor]);\r
+\r
+ match op {\r
+ // Sum.\r
+ 1 => {\r
+ write(cursor + 3, read(cursor + 1, &code, modes[0], relative_base) + read(cursor + 2, &code, modes[1], relative_base), &mut code, modes[2], relative_base);\r
+ cursor += 4;\r
+ },\r
+\r
+ // Multiply.\r
+ 2 => {\r
+ write(cursor + 3, read(cursor + 1, &code, modes[0], relative_base) * read(cursor + 2, &code, modes[1], relative_base), &mut code, modes[2], relative_base);\r
+ cursor += 4;\r
+ },\r
+\r
+ // Input.\r
+ 3 => {\r
+ write(cursor + 1, io.read(), &mut code, modes[0], relative_base);\r
+ cursor += 2;\r
+ }\r
+\r
+ // Output.\r
+ 4 => {\r
+ io.write(read(cursor + 1, &code, modes[0], relative_base));\r
+ cursor += 2;\r
+ }\r
+\r
+ // Jump-if-true.\r
+ 5 => cursor = jump_if(true, cursor, &code, modes, relative_base),\r
+\r
+ // Jump-if-false.\r
+ 6 => cursor = jump_if(false, cursor, &code, modes, relative_base),\r
+\r
+ // Less than.\r
+ 7 => {\r
+ write(cursor + 3, if read(cursor + 1, &code, modes[0], relative_base) < read(cursor + 2, &code, modes[1], relative_base) { 1 } else { 0 }, &mut code, modes[2], relative_base);\r
+ cursor += 4;\r
+ },\r
+\r
+ // Equals.\r
+ 8 => {\r
+ write(cursor + 3, if read(cursor + 1, &code, modes[0], relative_base) == read(cursor + 2, &code, modes[1], relative_base) { 1 } else { 0 }, &mut code, modes[2], relative_base);\r
+ cursor += 4;\r
+ },\r
+\r
+ // Change relative base.\r
+ 9 => {\r
+ relative_base += read(cursor + 1, &code, modes[0], relative_base);\r
+ cursor += 2;\r
+ }\r
+\r
+ 99 => break,\r
+\r
+ _ => panic!("Unknown code: {}", code[cursor])\r
+ }\r
+ }\r
+}\r
+\r
+#[cfg(test)]\r
+mod tests_day05 {\r
+ use super::*;\r
+\r
+ #[test]\r
+ fn part2() {\r
+ 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];\r
+\r
+ let r1 = execute_op_code(&c, &[7]);\r
+ assert_eq!(r1[0], 999);\r
+\r
+ let r2 = execute_op_code(&c, &[8]);\r
+ assert_eq!(r2[0], 1000);\r
+\r
+ let r3 = execute_op_code(&c, &[9]);\r
+ assert_eq!(r3[0], 1001);\r
+ }\r
+}\r
+\r
+#[cfg(test)]\r
+mod tests_day09 {\r
+ use super::*;\r
+\r
+ #[test]\r
+ fn copy_of_itself() {\r
+ let c = [109,1,204,-1,1001,100,1,100,1008,100,16,101,1006,101,0,99];\r
+ let r = execute_op_code(&c, &Vec::new());\r
+ assert_eq!(r, c);\r
+ }\r
+\r
+ #[test]\r
+ fn output_big_number() {\r
+ let c = [1102,34_915_192,34_915_192,7,4,7,99,0];\r
+ let r = execute_op_code(&c, &Vec::new());\r
+ assert_eq!(r[0], 1_219_070_632_396_864);\r
+ }\r
+\r
+ #[test]\r
+ fn input_big_number() {\r
+ let c = [104,1_125_899_906_842_624,99];\r
+ let r = execute_op_code(&c, &Vec::new());\r
+ assert_eq!(r[0], 1_125_899_906_842_624);\r
+ }\r
+}
\ No newline at end of file
use std::fs;
use std::time::Instant;
+mod common;
+mod intcode;
mod day01;
mod day02;
mod day03;
-mod day05;
mod day06;
mod day07;
mod day08;
-mod day09;
-mod common;
+mod day11;
fn day01() -> String {
let masses = common::read_list_of_numbers("data/day01.input", "\n");
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]))
+ format!("part1: {:?}, part2: {:?}", intcode::execute_op_code(&code, &[1]), intcode::execute_op_code(&code, &[5]))
}
fn day06() -> String {
let layer = day08::layer_with_fewer_0(&layers[..]);
let merged = day08::merge_layers(&layers[..]);
- format!("part1: {}, part2:\n{}", day08::one_digits_times_two_digits(layer), day08::layer_to_printable_string(&merged, 25))
+ format!("part1: {}, part2:\n{}", day08::one_digits_times_two_digits(layer), common::layer_to_printable_string(&merged, 25))
}
fn day09() -> String {
let code = common::read_list_of_numbers::<&str, i64>("data/day09.input", ",");
- format!("part1: {:?}, part2: {:?}", day09::execute_op_code(&code, &[1]), day09::execute_op_code(&code, &[2]))
+
+ format!("part1: {:?}, part2: {:?}", intcode::execute_op_code(&code, &[1]), intcode::execute_op_code(&code, &[2]))
+}
+
+fn day10() -> String {
+ format!("")
+}
+
+fn day11() -> String {
+ let code = common::read_list_of_numbers::<&str, i64>("data/day11.input", ",");
+ let panels = day11::run_robot(&code, 1);
+ let (layer, width) = day11::panels_to_layer(&panels);
+
+ format!("part1: {:?}, part2:\n{}", day11::run_robot(&code, 0).len(), common::layer_to_printable_string(&layer, width))
}
fn format_micros(t: u128) -> String {
day06,
day07,
day08,
- day09
+ day09,
+ day10,
+ day11
);
let args: Vec<String> = env::args().skip(1).collect();