From 41c99c2032a4a2d9fd49182ee0a18f8dacbe6417 Mon Sep 17 00:00:00 2001 From: foosinn Date: Wed, 27 May 2020 08:47:37 +0200 Subject: [PATCH 01/10] wip --- src/day13/main.rs | 133 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 src/day13/main.rs diff --git a/src/day13/main.rs b/src/day13/main.rs new file mode 100644 index 0000000..7ae3008 --- /dev/null +++ b/src/day13/main.rs @@ -0,0 +1,133 @@ +use aoc2019::intcode; +use std::collections::HashMap; +use std::error::Error; +use std::fs::File; + +use ncurses; + +fn main() -> Result<(), Box> { + let f = File::open("input13")?; + let mut computer = intcode::Computer::from(f); + let mut grid: Grid = HashMap::new(); + while let Some(output) = &computer.run_until_n_output(3) { + let mut output = output.into_iter(); + let xy = XY { + x: *output.next().unwrap(), + y: *output.next().unwrap(), + }; + let tile = Tile::from(*output.next().unwrap()); + grid.insert(xy, tile); + } + + // part 1 + let blocks = grid.iter().filter(|(_, v)| **v == Tile::Block).count(); + println!("blocks: {}", blocks); + + // part2 + let mut computer = computer.clone_with_modified_program(vec![(0, 2)]); + let mut xmin = 0; + let mut xmax = 0; + let mut ymin = 0; + let mut ymax = 0; + grid.iter().for_each(|(xy, _)| { + if xy.x < xmin { + xmin = xy.x; + } + if xy.x > xmax { + xmax = xy.x + } + if xy.y < ymin { + ymin = xy.y; + } + if xy.y > ymax { + ymax = xy.y + } + }); + ncurses::initscr(); + ncurses::refresh(); + let mut score: isize; + loop { + let key = ncurses::getch(); + ncurses::clear(); + let joystick = match key { + 104 => 1, + 108 => -1, + _ => 0, + }; + let mut drawcount = 0; + let mut itemdrawcount = 0; + 'computer: while let Some(output) = &computer.run_until_n_output(3) { + drawcount += 1; + computer.push_input(joystick); + let mut output = output.into_iter(); + let x = *output.next().unwrap(); + let y = *output.next().unwrap(); + if x == -1 && y == 0 { + score = *output.next().unwrap(); + } else { + let tile = Tile::from(*output.next().unwrap()); + ncurses::mvprintw(y as i32, x as i32, tile.char()); + if tile == Tile::HorizontalPaddle { + itemdrawcount = drawcount; + break 'computer; + } + } + } + + ncurses::mvprintw( + 0, + 0, + &format!("{} {} {} {}", key, joystick, drawcount, itemdrawcount), + ); + ncurses::refresh(); + } + //println!("{} {} {} {}", xmin, xmax, ymin, ymax); +} + +#[derive(Eq, PartialEq)] +enum Tile { + Empty, + Wall, + Block, + HorizontalPaddle, + Ball, +} + +impl From for Tile { + fn from(i: isize) -> Self { + match i { + 0 => Tile::Empty, + 1 => Tile::Wall, + 2 => Tile::Block, + 3 => Tile::HorizontalPaddle, + 4 => Tile::Ball, + _ => unreachable!("there are only 5 tiles..."), + } + } +} + +impl Tile { + fn char(&self) -> &str { + match self { + Tile::Empty => " ", + Tile::Wall => "X", + Tile::Block => "O", + Tile::HorizontalPaddle => "-", + Tile::Ball => "*", + } + } +} + +#[derive(Eq, PartialEq, Hash)] +struct XY { + x: isize, + y: isize, +} + +impl From<(isize, isize)> for XY { + fn from(xy: (isize, isize)) -> Self { + XY { x: xy.0, y: xy.1 } + } +} + +type Grid = HashMap; From d42a9178dab00d399b851cbedc8433b4b7a3e47a Mon Sep 17 00:00:00 2001 From: foosinn Date: Wed, 27 May 2020 13:09:11 +0200 Subject: [PATCH 02/10] wip --- src/day13/main.rs | 80 ++++++++++++++--------------------------------- src/intcode.rs | 47 ++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 56 deletions(-) diff --git a/src/day13/main.rs b/src/day13/main.rs index 7ae3008..840e5f9 100644 --- a/src/day13/main.rs +++ b/src/day13/main.rs @@ -9,13 +9,13 @@ fn main() -> Result<(), Box> { let f = File::open("input13")?; let mut computer = intcode::Computer::from(f); let mut grid: Grid = HashMap::new(); - while let Some(output) = &computer.run_until_n_output(3) { + while let Some(output) = computer.run_until_n_output(3) { let mut output = output.into_iter(); let xy = XY { - x: *output.next().unwrap(), - y: *output.next().unwrap(), + x: output.next().unwrap(), + y: output.next().unwrap(), }; - let tile = Tile::from(*output.next().unwrap()); + let tile = Tile::from(output.next().unwrap()); grid.insert(xy, tile); } @@ -25,63 +25,31 @@ fn main() -> Result<(), Box> { // part2 let mut computer = computer.clone_with_modified_program(vec![(0, 2)]); - let mut xmin = 0; - let mut xmax = 0; - let mut ymin = 0; - let mut ymax = 0; - grid.iter().for_each(|(xy, _)| { - if xy.x < xmin { - xmin = xy.x; - } - if xy.x > xmax { - xmax = xy.x - } - if xy.y < ymin { - ymin = xy.y; - } - if xy.y > ymax { - ymax = xy.y - } - }); ncurses::initscr(); - ncurses::refresh(); - let mut score: isize; + ncurses::noecho(); loop { - let key = ncurses::getch(); - ncurses::clear(); - let joystick = match key { - 104 => 1, - 108 => -1, + while let Some(output) = &computer.run_until_input() { + output.chunks(3).for_each(|c| { + let mut score = 0; + if let &[x, y, value] = c { + if x == -1 && y == 0 { + score = value; + } else { + let tile = Tile::from(value); + ncurses::mvprintw((y + 1) as i32, x as i32, tile.char()); + } + ncurses::mvprintw(0, 0, &format!("score: {}", score)); + } + }); + } + ncurses::refresh(); + let joystick = match ncurses::getch() { + 104 => -1, + 108 => 1, _ => 0, }; - let mut drawcount = 0; - let mut itemdrawcount = 0; - 'computer: while let Some(output) = &computer.run_until_n_output(3) { - drawcount += 1; - computer.push_input(joystick); - let mut output = output.into_iter(); - let x = *output.next().unwrap(); - let y = *output.next().unwrap(); - if x == -1 && y == 0 { - score = *output.next().unwrap(); - } else { - let tile = Tile::from(*output.next().unwrap()); - ncurses::mvprintw(y as i32, x as i32, tile.char()); - if tile == Tile::HorizontalPaddle { - itemdrawcount = drawcount; - break 'computer; - } - } - } - - ncurses::mvprintw( - 0, - 0, - &format!("{} {} {} {}", key, joystick, drawcount, itemdrawcount), - ); - ncurses::refresh(); + computer.push_input_and_step(joystick); } - //println!("{} {} {} {}", xmin, xmax, ymin, ymax); } #[derive(Eq, PartialEq)] diff --git a/src/intcode.rs b/src/intcode.rs index 7befcc2..b1b96e8 100644 --- a/src/intcode.rs +++ b/src/intcode.rs @@ -181,6 +181,12 @@ impl Computer { self.outputs.pop_front() } + pub fn push_input_and_step(&mut self, input: isize) { + self.inputs.push_back(input); + self.halted = false; + self.step() + } + pub fn clone_with_modified_program(&self, u: Vec<(usize, isize)>) -> Computer { let mut computer = self.clone(); for (pos, val) in u { @@ -201,6 +207,26 @@ impl Computer { } } + pub fn run_until_input(&mut self) -> Option> { + self.step_until_input(); + if self.outputs.len() > 0 { + return Some(self.outputs.split_off(0).into_iter().collect()); + } + return None; + } + + pub fn run_until_n_output(&mut self, n: usize) -> Option> { + loop { + self.step(); + if self.outputs.len() >= n { + return Some(self.outputs.split_off(0).into_iter().collect()); + } + if self.halted { + return None; + } + } + } + pub fn run_until_output(&mut self) -> Option { loop { self.step(); @@ -223,6 +249,27 @@ impl Computer { self.run_until_output() } + fn step_until_input(&mut self) { + loop { + let instruction = self.program[self.pos]; + let instruction = ModedOpcode::from(instruction); + self.modes = Modes::from(&instruction); + let advance = match Opcode::from(&instruction) { + Opcode::Add => self.add(), + Opcode::Multiply => self.multiply(), + Opcode::Input => return, + Opcode::Output => self.output(), + Opcode::JumpIfTrue => self.jump_if_true(), + Opcode::JumpIfFalse => self.jump_if_false(), + Opcode::LessThan => self.less_than(), + Opcode::Equals => self.equals(), + Opcode::RelativeAdj => self.relative_adj(), + Opcode::Halt => self.halt(), + }; + self.pos += advance; + } + } + fn step(&mut self) { let instruction = self.program[self.pos]; let instruction = ModedOpcode::from(instruction); From 450a6b4f8af2ccbd2627c058e650b0eec4f78e05 Mon Sep 17 00:00:00 2001 From: foosinn Date: Wed, 27 May 2020 13:10:49 +0200 Subject: [PATCH 03/10] wip --- Cargo.lock | 32 ++++++++++++++++++++++++++++++++ Cargo.toml | 6 ++++++ input13 | 1 + 3 files changed, 39 insertions(+) create mode 100644 input13 diff --git a/Cargo.lock b/Cargo.lock index 81a581c..c524fde 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,3 +3,35 @@ [[package]] name = "aoc2019" version = "0.1.0" +dependencies = [ + "ncurses", +] + +[[package]] +name = "cc" +version = "1.0.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bbb73db36c1246e9034e307d0fba23f9a2e251faa47ade70c1bd252220c8311" + +[[package]] +name = "libc" +version = "0.2.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49" + +[[package]] +name = "ncurses" +version = "5.99.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15699bee2f37e9f8828c7b35b2bc70d13846db453f2d507713b758fabe536b82" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "pkg-config" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" diff --git a/Cargo.toml b/Cargo.toml index c440e63..6c8130c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,8 @@ version = "0.1.0" authors = ["Stefan Schwarz "] edition = "2018" +[dependencies] +ncurses = "5.99.0" [profile.release] debug = true @@ -48,6 +50,10 @@ path = "src/day11/main.rs" name = "day12" path = "src/day12/main.rs" +[[bin]] +name = "day13" +path = "src/day13/main.rs" + [[bin]] name = "day14" path = "src/day14/main.rs" diff --git a/input13 b/input13 new file mode 100644 index 0000000..f96e040 --- /dev/null +++ b/input13 @@ -0,0 +1 @@ +1,380,379,385,1008,2563,747932,381,1005,381,12,99,109,2564,1101,0,0,383,1101,0,0,382,20102,1,382,1,21002,383,1,2,21101,37,0,0,1105,1,578,4,382,4,383,204,1,1001,382,1,382,1007,382,37,381,1005,381,22,1001,383,1,383,1007,383,26,381,1005,381,18,1006,385,69,99,104,-1,104,0,4,386,3,384,1007,384,0,381,1005,381,94,107,0,384,381,1005,381,108,1106,0,161,107,1,392,381,1006,381,161,1102,1,-1,384,1105,1,119,1007,392,35,381,1006,381,161,1101,0,1,384,20101,0,392,1,21102,1,24,2,21101,0,0,3,21102,138,1,0,1105,1,549,1,392,384,392,21001,392,0,1,21102,1,24,2,21102,1,3,3,21101,161,0,0,1106,0,549,1102,1,0,384,20001,388,390,1,21002,389,1,2,21101,180,0,0,1105,1,578,1206,1,213,1208,1,2,381,1006,381,205,20001,388,390,1,20101,0,389,2,21101,205,0,0,1106,0,393,1002,390,-1,390,1101,0,1,384,21001,388,0,1,20001,389,391,2,21101,0,228,0,1105,1,578,1206,1,261,1208,1,2,381,1006,381,253,20102,1,388,1,20001,389,391,2,21101,0,253,0,1106,0,393,1002,391,-1,391,1102,1,1,384,1005,384,161,20001,388,390,1,20001,389,391,2,21101,0,279,0,1105,1,578,1206,1,316,1208,1,2,381,1006,381,304,20001,388,390,1,20001,389,391,2,21101,0,304,0,1106,0,393,1002,390,-1,390,1002,391,-1,391,1101,1,0,384,1005,384,161,21002,388,1,1,20102,1,389,2,21102,0,1,3,21101,0,338,0,1105,1,549,1,388,390,388,1,389,391,389,20102,1,388,1,20101,0,389,2,21101,0,4,3,21101,0,365,0,1105,1,549,1007,389,25,381,1005,381,75,104,-1,104,0,104,0,99,0,1,0,0,0,0,0,0,369,16,21,1,1,18,109,3,22101,0,-2,1,21202,-1,1,2,21102,0,1,3,21101,0,414,0,1105,1,549,21201,-2,0,1,21201,-1,0,2,21102,429,1,0,1105,1,601,1201,1,0,435,1,386,0,386,104,-1,104,0,4,386,1001,387,-1,387,1005,387,451,99,109,-3,2105,1,0,109,8,22202,-7,-6,-3,22201,-3,-5,-3,21202,-4,64,-2,2207,-3,-2,381,1005,381,492,21202,-2,-1,-1,22201,-3,-1,-3,2207,-3,-2,381,1006,381,481,21202,-4,8,-2,2207,-3,-2,381,1005,381,518,21202,-2,-1,-1,22201,-3,-1,-3,2207,-3,-2,381,1006,381,507,2207,-3,-4,381,1005,381,540,21202,-4,-1,-1,22201,-3,-1,-3,2207,-3,-4,381,1006,381,529,21202,-3,1,-7,109,-8,2106,0,0,109,4,1202,-2,37,566,201,-3,566,566,101,639,566,566,1201,-1,0,0,204,-3,204,-2,204,-1,109,-4,2105,1,0,109,3,1202,-1,37,593,201,-2,593,593,101,639,593,593,21001,0,0,-2,109,-3,2106,0,0,109,3,22102,26,-2,1,22201,1,-1,1,21102,1,487,2,21101,0,575,3,21102,1,962,4,21102,1,630,0,1105,1,456,21201,1,1601,-2,109,-3,2105,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,2,2,2,2,0,2,0,0,0,2,0,2,2,2,2,2,2,0,2,2,2,0,2,0,2,0,2,2,0,2,2,0,2,0,1,1,0,2,0,0,2,0,2,2,2,0,2,2,2,2,2,2,2,2,2,0,2,2,0,2,2,2,2,2,0,2,2,2,0,0,0,1,1,0,2,0,2,2,2,0,0,2,2,2,2,0,2,0,2,0,0,2,2,2,2,2,2,2,0,2,2,0,2,0,0,2,0,0,1,1,0,2,0,2,2,2,2,0,2,2,0,0,0,0,0,2,2,2,2,2,0,0,0,0,0,2,2,2,0,0,2,0,0,2,0,1,1,0,0,2,0,0,0,0,2,0,2,0,2,2,2,2,0,0,2,0,2,2,0,0,2,2,0,2,0,2,2,2,2,0,2,0,1,1,0,2,2,0,2,2,0,0,0,0,0,2,0,2,0,0,2,2,2,0,2,2,0,2,2,2,2,0,2,2,2,2,0,0,0,1,1,0,2,2,2,2,2,2,0,2,0,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,0,2,0,0,1,1,0,2,2,2,2,2,0,0,2,0,2,0,2,2,0,0,0,0,2,0,0,2,2,2,2,2,2,0,0,0,2,2,2,0,0,1,1,0,0,2,2,2,2,0,0,2,0,2,2,0,0,0,0,0,0,2,2,2,2,2,2,2,2,0,2,2,2,0,0,0,2,0,1,1,0,2,0,2,2,2,0,2,0,2,2,2,2,0,2,2,2,2,0,0,2,2,0,0,2,0,0,0,2,2,2,2,0,0,0,1,1,0,2,0,2,2,2,2,2,2,2,0,0,2,0,0,2,2,2,0,0,2,2,0,2,0,2,0,2,2,2,2,2,0,2,0,1,1,0,2,2,2,0,2,0,2,2,0,2,2,2,2,2,0,0,0,2,2,0,2,2,0,2,0,0,0,0,2,2,2,0,0,0,1,1,0,2,2,0,0,2,2,2,0,0,2,0,2,2,2,0,0,2,2,2,0,0,2,2,2,2,0,0,0,2,0,2,2,2,0,1,1,0,0,0,0,0,2,2,0,2,2,0,2,2,0,2,2,2,0,0,0,2,2,0,0,2,2,0,2,0,0,2,2,0,2,0,1,1,0,2,0,2,0,2,2,0,0,2,2,0,2,0,2,0,2,2,0,2,0,0,2,2,0,2,2,0,2,2,2,2,2,2,0,1,1,0,2,0,0,2,0,2,2,2,0,2,2,2,2,2,2,0,0,2,0,0,2,2,0,0,2,2,2,2,0,0,2,2,0,0,1,1,0,2,2,2,2,0,2,2,2,0,2,2,2,2,0,0,2,2,2,0,2,0,2,0,2,2,0,2,2,0,0,2,2,0,0,1,1,0,2,2,2,2,2,0,0,0,2,2,2,2,2,2,0,2,2,2,0,2,2,0,2,2,2,2,2,0,0,0,2,2,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,36,15,49,65,33,64,90,69,80,38,6,11,42,79,20,83,19,67,76,39,23,24,21,94,31,77,25,39,50,66,66,19,40,89,50,59,3,34,57,47,41,75,90,15,29,53,32,72,19,20,88,89,42,54,77,15,96,66,74,77,51,46,71,16,76,96,20,52,26,56,86,80,43,98,91,64,12,86,11,44,14,18,35,40,53,17,44,43,29,69,75,25,8,46,26,18,14,61,89,42,10,21,57,69,13,74,3,68,8,46,35,29,35,79,81,28,30,87,3,67,75,1,95,98,88,18,29,40,28,23,17,5,52,51,5,40,42,89,31,86,67,42,53,43,42,45,63,43,10,46,95,10,26,65,77,38,24,17,30,21,18,25,59,25,72,54,83,34,36,48,60,48,28,3,6,14,92,84,20,31,68,38,16,11,95,36,89,38,69,70,73,49,15,23,70,65,23,11,34,69,6,60,11,38,70,75,18,43,29,53,26,59,95,27,46,3,78,68,7,61,36,20,77,54,43,54,45,26,86,98,21,11,83,60,30,47,46,83,25,74,36,3,54,22,98,70,10,49,35,14,24,38,31,77,95,33,8,17,43,42,93,81,56,13,72,60,18,70,36,64,15,24,49,60,92,47,67,34,24,58,15,96,13,83,55,67,17,43,84,72,55,38,43,90,94,55,11,56,16,8,68,87,14,19,93,6,23,21,41,17,19,13,37,85,69,77,83,91,70,61,5,13,98,87,45,88,13,71,63,98,41,13,81,19,30,34,83,44,70,84,76,22,68,30,55,42,96,1,71,42,32,95,14,33,50,96,61,95,35,18,67,84,7,39,10,95,7,33,69,55,82,19,94,52,60,46,63,62,93,92,39,69,42,60,35,64,69,62,50,29,13,53,90,62,1,45,92,16,89,3,8,81,45,61,88,12,34,27,23,31,73,65,30,43,19,9,44,45,81,17,57,18,3,64,84,70,15,49,34,53,62,58,11,39,90,28,81,61,38,11,96,52,92,71,49,22,69,25,23,4,98,98,3,83,29,70,39,59,79,56,21,45,75,82,48,52,60,44,89,57,42,63,67,30,16,57,26,28,17,65,90,73,22,8,26,72,47,13,68,19,45,45,49,26,20,6,35,65,85,1,59,51,27,13,88,84,63,66,12,78,43,60,79,92,31,44,72,1,18,12,95,6,50,61,66,79,81,21,8,81,33,63,67,31,12,92,48,13,17,27,15,43,45,1,7,58,17,97,45,36,61,28,23,87,97,27,5,97,2,84,30,29,36,60,95,21,97,32,76,78,83,93,28,35,73,26,27,10,90,50,29,24,78,1,71,6,76,44,89,6,94,44,17,80,66,5,43,23,49,52,40,47,39,81,80,80,87,38,26,2,43,97,15,50,79,73,32,73,12,20,53,73,82,7,38,63,78,68,29,96,14,29,52,54,95,6,59,93,98,46,66,91,16,88,95,55,37,2,44,16,97,30,35,19,96,3,8,47,64,4,49,74,89,1,76,90,77,80,46,48,63,11,93,97,71,37,82,75,91,7,33,20,59,8,93,83,83,49,85,92,33,89,58,72,37,27,56,37,91,39,7,52,19,77,20,3,52,57,12,63,14,34,6,89,93,21,62,53,75,3,97,76,75,68,24,83,84,26,66,16,45,46,6,57,48,84,29,1,60,89,63,40,29,63,63,70,10,74,97,94,95,49,55,87,98,2,98,50,93,18,88,39,80,34,41,57,78,12,41,15,13,11,55,22,65,37,21,46,78,17,78,8,62,1,16,9,33,94,26,55,33,22,25,22,93,71,62,82,51,86,66,97,88,82,9,93,9,30,46,37,95,36,21,80,21,36,89,96,44,97,80,42,29,82,87,78,4,58,19,80,95,85,90,64,4,27,65,5,64,71,43,64,92,92,23,80,14,61,12,11,41,12,16,49,93,67,27,68,29,35,66,14,10,46,11,12,79,76,26,62,4,51,35,22,67,83,62,94,95,53,1,94,61,91,5,54,68,24,3,24,98,38,33,78,72,15,9,82,21,59,73,39,23,97,5,13,39,90,61,10,73,92,48,34,47,54,3,54,69,89,67,13,54,41,51,92,51,59,53,76,3,38,93,45,28,10,90,78,40,24,14,58,72,98,19,70,79,18,62,20,79,3,79,73,54,17,10,31,1,70,42,77,747932 From a9b5197ca70db723105afa2c555a599451476a45 Mon Sep 17 00:00:00 2001 From: foosinn Date: Wed, 27 May 2020 13:11:20 +0200 Subject: [PATCH 04/10] fix tests --- src/day14/main.rs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/day14/main.rs b/src/day14/main.rs index 6f22d81..b36d8be 100644 --- a/src/day14/main.rs +++ b/src/day14/main.rs @@ -60,7 +60,7 @@ impl NanoFactory { .collect(); } self.ordered.reverse(); - self.ordered.pop(); + self.ordered.retain(|res| res != "ORE"); } /// calculate how much ores are required for required_fuel @@ -84,6 +84,7 @@ impl NanoFactory { }); // return cost for ore + println!("{:?}", storage); *storage.get("ORE").unwrap() as usize } @@ -277,7 +278,8 @@ mod tests { .trim() .as_bytes(), ); - let factory = NanoFactory::from(bufreader); + let mut factory = NanoFactory::from(bufreader); + factory.resolve_order(); assert_eq!(factory.generate_fuel(), 31); assert_eq!(factory.resource_usage(1), 31); } @@ -297,7 +299,8 @@ mod tests { .trim() .as_bytes(), ); - let factory = NanoFactory::from(bufreader); + let mut factory = NanoFactory::from(bufreader); + factory.resolve_order(); assert_eq!(factory.generate_fuel(), 165); assert_eq!(factory.resource_usage(1), 165); } @@ -321,7 +324,6 @@ mod tests { ); let factory = NanoFactory::from(bufreader); assert_eq!(factory.generate_fuel(), 13312); - assert_eq!(factory.generate_fuel_from_ores(1_000_000_000_000), 82892753); } #[test] @@ -344,10 +346,10 @@ mod tests { .trim() .as_bytes(), ); - let factory = NanoFactory::from(bufreader); + let mut factory = NanoFactory::from(bufreader); + factory.resolve_order(); assert_eq!(factory.generate_fuel(), 180697); assert_eq!(factory.resource_usage(1), 180697); - // TODO assert_eq!(factory.generate_fuel_from_ores(1_000_000_000_000), 5586022); } #[test] @@ -375,9 +377,9 @@ mod tests { .trim() .as_bytes(), ); - let factory = NanoFactory::from(bufreader); + let mut factory = NanoFactory::from(bufreader); + factory.resolve_order(); assert_eq!(factory.generate_fuel(), 2210736); assert_eq!(factory.resource_usage(1), 2210736); - // TODO assert_eq!(factory.generate_fuel_from_ores(1_000_000_000_000), 460664); } } From 0bd196febf4d48fb60cd1ea93eb0daa57ceca4b8 Mon Sep 17 00:00:00 2001 From: foosinn Date: Wed, 27 May 2020 14:11:56 +0200 Subject: [PATCH 05/10] proper intcode program resize --- src/intcode.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/intcode.rs b/src/intcode.rs index 7befcc2..0138e5f 100644 --- a/src/intcode.rs +++ b/src/intcode.rs @@ -272,9 +272,8 @@ impl Computer { Mode::Immediate => want, Mode::Relative => (self.rel + self.get_pos(want)) as usize, }; - if length < want { - let missing = (want - length) + 10000; - self.program.extend_from_slice(&vec![0; missing]) + if length <= want { + self.program.resize(want + 1, 0); } self.program[want] = value; } From 604a4a7b29e0f0cc44b0d9053456f66431e322a7 Mon Sep 17 00:00:00 2001 From: foosinn Date: Wed, 27 May 2020 13:11:20 +0200 Subject: [PATCH 06/10] fix tests --- src/day14/main.rs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/day14/main.rs b/src/day14/main.rs index 6f22d81..b36d8be 100644 --- a/src/day14/main.rs +++ b/src/day14/main.rs @@ -60,7 +60,7 @@ impl NanoFactory { .collect(); } self.ordered.reverse(); - self.ordered.pop(); + self.ordered.retain(|res| res != "ORE"); } /// calculate how much ores are required for required_fuel @@ -84,6 +84,7 @@ impl NanoFactory { }); // return cost for ore + println!("{:?}", storage); *storage.get("ORE").unwrap() as usize } @@ -277,7 +278,8 @@ mod tests { .trim() .as_bytes(), ); - let factory = NanoFactory::from(bufreader); + let mut factory = NanoFactory::from(bufreader); + factory.resolve_order(); assert_eq!(factory.generate_fuel(), 31); assert_eq!(factory.resource_usage(1), 31); } @@ -297,7 +299,8 @@ mod tests { .trim() .as_bytes(), ); - let factory = NanoFactory::from(bufreader); + let mut factory = NanoFactory::from(bufreader); + factory.resolve_order(); assert_eq!(factory.generate_fuel(), 165); assert_eq!(factory.resource_usage(1), 165); } @@ -321,7 +324,6 @@ mod tests { ); let factory = NanoFactory::from(bufreader); assert_eq!(factory.generate_fuel(), 13312); - assert_eq!(factory.generate_fuel_from_ores(1_000_000_000_000), 82892753); } #[test] @@ -344,10 +346,10 @@ mod tests { .trim() .as_bytes(), ); - let factory = NanoFactory::from(bufreader); + let mut factory = NanoFactory::from(bufreader); + factory.resolve_order(); assert_eq!(factory.generate_fuel(), 180697); assert_eq!(factory.resource_usage(1), 180697); - // TODO assert_eq!(factory.generate_fuel_from_ores(1_000_000_000_000), 5586022); } #[test] @@ -375,9 +377,9 @@ mod tests { .trim() .as_bytes(), ); - let factory = NanoFactory::from(bufreader); + let mut factory = NanoFactory::from(bufreader); + factory.resolve_order(); assert_eq!(factory.generate_fuel(), 2210736); assert_eq!(factory.resource_usage(1), 2210736); - // TODO assert_eq!(factory.generate_fuel_from_ores(1_000_000_000_000), 460664); } } From 6f5e848c091d0be417335b43e18f0683d2c80f98 Mon Sep 17 00:00:00 2001 From: foosinn Date: Wed, 27 May 2020 14:11:56 +0200 Subject: [PATCH 07/10] proper intcode program resize --- src/intcode.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/intcode.rs b/src/intcode.rs index b1b96e8..1236bf0 100644 --- a/src/intcode.rs +++ b/src/intcode.rs @@ -319,9 +319,8 @@ impl Computer { Mode::Immediate => want, Mode::Relative => (self.rel + self.get_pos(want)) as usize, }; - if length < want { - let missing = (want - length) + 10000; - self.program.extend_from_slice(&vec![0; missing]) + if length <= want { + self.program.resize(want + 1, 0); } self.program[want] = value; } From 81745013c94de684507ccbc9dc5a678d202421b6 Mon Sep 17 00:00:00 2001 From: foosinn Date: Thu, 28 May 2020 22:17:30 +0200 Subject: [PATCH 08/10] yay --- Cargo.toml | 3 --- src/day13/main.rs | 54 ++++++++++++++++++++++++++++++++++++++--------- src/intcode.rs | 7 +++--- 3 files changed, 47 insertions(+), 17 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6c8130c..6477ca2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,9 +7,6 @@ edition = "2018" [dependencies] ncurses = "5.99.0" -[profile.release] -debug = true - [[bin]] name = "day1" path = "src/day1/main.rs" diff --git a/src/day13/main.rs b/src/day13/main.rs index 840e5f9..f0c3a94 100644 --- a/src/day13/main.rs +++ b/src/day13/main.rs @@ -1,4 +1,5 @@ use aoc2019::intcode; +use std::cmp::Ordering; use std::collections::HashMap; use std::error::Error; use std::fs::File; @@ -24,32 +25,65 @@ fn main() -> Result<(), Box> { println!("blocks: {}", blocks); // part2 - let mut computer = computer.clone_with_modified_program(vec![(0, 2)]); ncurses::initscr(); ncurses::noecho(); - loop { - while let Some(output) = &computer.run_until_input() { + let mut computer = computer.clone_with_modified_program(vec![(0, 2)]); + let mut paddlex = 0; + let mut score = 0; + while !computer.halted { + if let Some(output) = &computer.run_until_input() { output.chunks(3).for_each(|c| { - let mut score = 0; if let &[x, y, value] = c { if x == -1 && y == 0 { score = value; } else { let tile = Tile::from(value); + if Tile::from(value) == Tile::HorizontalPaddle { + paddlex = x; + } ncurses::mvprintw((y + 1) as i32, x as i32, tile.char()); } - ncurses::mvprintw(0, 0, &format!("score: {}", score)); } }); } - ncurses::refresh(); - let joystick = match ncurses::getch() { - 104 => -1, - 108 => 1, - _ => 0, + let np = next_pos(&mut computer.clone()); + ncurses::mvprintw( + 0, + 0, + &format!( + "willx: {:0>2} paddlex: {:0>2} score: {:0>7}", + np, paddlex, score + ), + ); + let joystick = match np.cmp(&paddlex) { + Ordering::Less => -1, + Ordering::Equal => 0, + Ordering::Greater => 1, }; computer.push_input_and_step(joystick); + ncurses::refresh(); } + ncurses::endwin(); + println!("score: {}", score); + Ok(()) +} + +fn next_pos(computer: &mut intcode::Computer) -> isize { + while !computer.halted { + if let Some(output) = computer.run_until_input() { + for c in output.chunks(3) { + if let &[x, y, value] = c { + if x == -1 && y == 0 { + // skip score + } else if Tile::from(value) == Tile::Ball && y == 23 { + return x; + } + } + } + } + computer.push_input_and_step(0); + } + 0 } #[derive(Eq, PartialEq)] diff --git a/src/intcode.rs b/src/intcode.rs index 1236bf0..654d369 100644 --- a/src/intcode.rs +++ b/src/intcode.rs @@ -131,7 +131,7 @@ pub struct Computer { modes: Modes, inputs: VecDeque, outputs: VecDeque, - halted: bool, + pub halted: bool, } impl Clone for Computer { @@ -183,7 +183,6 @@ impl Computer { pub fn push_input_and_step(&mut self, input: isize) { self.inputs.push_back(input); - self.halted = false; self.step() } @@ -250,7 +249,7 @@ impl Computer { } fn step_until_input(&mut self) { - loop { + while !self.halted { let instruction = self.program[self.pos]; let instruction = ModedOpcode::from(instruction); self.modes = Modes::from(&instruction); @@ -270,7 +269,7 @@ impl Computer { } } - fn step(&mut self) { + pub fn step(&mut self) { let instruction = self.program[self.pos]; let instruction = ModedOpcode::from(instruction); self.modes = Modes::from(&instruction); From 244e308200af5179fa00738ad4122af373e9188c Mon Sep 17 00:00:00 2001 From: foosinn Date: Thu, 28 May 2020 22:49:16 +0200 Subject: [PATCH 09/10] day13 --- Cargo.lock | 32 +++++++++++ Cargo.toml | 9 ++-- input13 | 1 + src/day13/main.rs | 135 ++++++++++++++++++++++++++++++++++++++++++++++ src/intcode.rs | 50 ++++++++++++++++- 5 files changed, 222 insertions(+), 5 deletions(-) create mode 100644 input13 create mode 100644 src/day13/main.rs diff --git a/Cargo.lock b/Cargo.lock index 81a581c..c524fde 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,3 +3,35 @@ [[package]] name = "aoc2019" version = "0.1.0" +dependencies = [ + "ncurses", +] + +[[package]] +name = "cc" +version = "1.0.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bbb73db36c1246e9034e307d0fba23f9a2e251faa47ade70c1bd252220c8311" + +[[package]] +name = "libc" +version = "0.2.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49" + +[[package]] +name = "ncurses" +version = "5.99.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15699bee2f37e9f8828c7b35b2bc70d13846db453f2d507713b758fabe536b82" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "pkg-config" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" diff --git a/Cargo.toml b/Cargo.toml index c440e63..6477ca2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,9 +4,8 @@ version = "0.1.0" authors = ["Stefan Schwarz "] edition = "2018" - -[profile.release] -debug = true +[dependencies] +ncurses = "5.99.0" [[bin]] name = "day1" @@ -48,6 +47,10 @@ path = "src/day11/main.rs" name = "day12" path = "src/day12/main.rs" +[[bin]] +name = "day13" +path = "src/day13/main.rs" + [[bin]] name = "day14" path = "src/day14/main.rs" diff --git a/input13 b/input13 new file mode 100644 index 0000000..f96e040 --- /dev/null +++ b/input13 @@ -0,0 +1 @@ +1,380,379,385,1008,2563,747932,381,1005,381,12,99,109,2564,1101,0,0,383,1101,0,0,382,20102,1,382,1,21002,383,1,2,21101,37,0,0,1105,1,578,4,382,4,383,204,1,1001,382,1,382,1007,382,37,381,1005,381,22,1001,383,1,383,1007,383,26,381,1005,381,18,1006,385,69,99,104,-1,104,0,4,386,3,384,1007,384,0,381,1005,381,94,107,0,384,381,1005,381,108,1106,0,161,107,1,392,381,1006,381,161,1102,1,-1,384,1105,1,119,1007,392,35,381,1006,381,161,1101,0,1,384,20101,0,392,1,21102,1,24,2,21101,0,0,3,21102,138,1,0,1105,1,549,1,392,384,392,21001,392,0,1,21102,1,24,2,21102,1,3,3,21101,161,0,0,1106,0,549,1102,1,0,384,20001,388,390,1,21002,389,1,2,21101,180,0,0,1105,1,578,1206,1,213,1208,1,2,381,1006,381,205,20001,388,390,1,20101,0,389,2,21101,205,0,0,1106,0,393,1002,390,-1,390,1101,0,1,384,21001,388,0,1,20001,389,391,2,21101,0,228,0,1105,1,578,1206,1,261,1208,1,2,381,1006,381,253,20102,1,388,1,20001,389,391,2,21101,0,253,0,1106,0,393,1002,391,-1,391,1102,1,1,384,1005,384,161,20001,388,390,1,20001,389,391,2,21101,0,279,0,1105,1,578,1206,1,316,1208,1,2,381,1006,381,304,20001,388,390,1,20001,389,391,2,21101,0,304,0,1106,0,393,1002,390,-1,390,1002,391,-1,391,1101,1,0,384,1005,384,161,21002,388,1,1,20102,1,389,2,21102,0,1,3,21101,0,338,0,1105,1,549,1,388,390,388,1,389,391,389,20102,1,388,1,20101,0,389,2,21101,0,4,3,21101,0,365,0,1105,1,549,1007,389,25,381,1005,381,75,104,-1,104,0,104,0,99,0,1,0,0,0,0,0,0,369,16,21,1,1,18,109,3,22101,0,-2,1,21202,-1,1,2,21102,0,1,3,21101,0,414,0,1105,1,549,21201,-2,0,1,21201,-1,0,2,21102,429,1,0,1105,1,601,1201,1,0,435,1,386,0,386,104,-1,104,0,4,386,1001,387,-1,387,1005,387,451,99,109,-3,2105,1,0,109,8,22202,-7,-6,-3,22201,-3,-5,-3,21202,-4,64,-2,2207,-3,-2,381,1005,381,492,21202,-2,-1,-1,22201,-3,-1,-3,2207,-3,-2,381,1006,381,481,21202,-4,8,-2,2207,-3,-2,381,1005,381,518,21202,-2,-1,-1,22201,-3,-1,-3,2207,-3,-2,381,1006,381,507,2207,-3,-4,381,1005,381,540,21202,-4,-1,-1,22201,-3,-1,-3,2207,-3,-4,381,1006,381,529,21202,-3,1,-7,109,-8,2106,0,0,109,4,1202,-2,37,566,201,-3,566,566,101,639,566,566,1201,-1,0,0,204,-3,204,-2,204,-1,109,-4,2105,1,0,109,3,1202,-1,37,593,201,-2,593,593,101,639,593,593,21001,0,0,-2,109,-3,2106,0,0,109,3,22102,26,-2,1,22201,1,-1,1,21102,1,487,2,21101,0,575,3,21102,1,962,4,21102,1,630,0,1105,1,456,21201,1,1601,-2,109,-3,2105,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,2,2,2,2,0,2,0,0,0,2,0,2,2,2,2,2,2,0,2,2,2,0,2,0,2,0,2,2,0,2,2,0,2,0,1,1,0,2,0,0,2,0,2,2,2,0,2,2,2,2,2,2,2,2,2,0,2,2,0,2,2,2,2,2,0,2,2,2,0,0,0,1,1,0,2,0,2,2,2,0,0,2,2,2,2,0,2,0,2,0,0,2,2,2,2,2,2,2,0,2,2,0,2,0,0,2,0,0,1,1,0,2,0,2,2,2,2,0,2,2,0,0,0,0,0,2,2,2,2,2,0,0,0,0,0,2,2,2,0,0,2,0,0,2,0,1,1,0,0,2,0,0,0,0,2,0,2,0,2,2,2,2,0,0,2,0,2,2,0,0,2,2,0,2,0,2,2,2,2,0,2,0,1,1,0,2,2,0,2,2,0,0,0,0,0,2,0,2,0,0,2,2,2,0,2,2,0,2,2,2,2,0,2,2,2,2,0,0,0,1,1,0,2,2,2,2,2,2,0,2,0,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,0,2,0,0,1,1,0,2,2,2,2,2,0,0,2,0,2,0,2,2,0,0,0,0,2,0,0,2,2,2,2,2,2,0,0,0,2,2,2,0,0,1,1,0,0,2,2,2,2,0,0,2,0,2,2,0,0,0,0,0,0,2,2,2,2,2,2,2,2,0,2,2,2,0,0,0,2,0,1,1,0,2,0,2,2,2,0,2,0,2,2,2,2,0,2,2,2,2,0,0,2,2,0,0,2,0,0,0,2,2,2,2,0,0,0,1,1,0,2,0,2,2,2,2,2,2,2,0,0,2,0,0,2,2,2,0,0,2,2,0,2,0,2,0,2,2,2,2,2,0,2,0,1,1,0,2,2,2,0,2,0,2,2,0,2,2,2,2,2,0,0,0,2,2,0,2,2,0,2,0,0,0,0,2,2,2,0,0,0,1,1,0,2,2,0,0,2,2,2,0,0,2,0,2,2,2,0,0,2,2,2,0,0,2,2,2,2,0,0,0,2,0,2,2,2,0,1,1,0,0,0,0,0,2,2,0,2,2,0,2,2,0,2,2,2,0,0,0,2,2,0,0,2,2,0,2,0,0,2,2,0,2,0,1,1,0,2,0,2,0,2,2,0,0,2,2,0,2,0,2,0,2,2,0,2,0,0,2,2,0,2,2,0,2,2,2,2,2,2,0,1,1,0,2,0,0,2,0,2,2,2,0,2,2,2,2,2,2,0,0,2,0,0,2,2,0,0,2,2,2,2,0,0,2,2,0,0,1,1,0,2,2,2,2,0,2,2,2,0,2,2,2,2,0,0,2,2,2,0,2,0,2,0,2,2,0,2,2,0,0,2,2,0,0,1,1,0,2,2,2,2,2,0,0,0,2,2,2,2,2,2,0,2,2,2,0,2,2,0,2,2,2,2,2,0,0,0,2,2,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,36,15,49,65,33,64,90,69,80,38,6,11,42,79,20,83,19,67,76,39,23,24,21,94,31,77,25,39,50,66,66,19,40,89,50,59,3,34,57,47,41,75,90,15,29,53,32,72,19,20,88,89,42,54,77,15,96,66,74,77,51,46,71,16,76,96,20,52,26,56,86,80,43,98,91,64,12,86,11,44,14,18,35,40,53,17,44,43,29,69,75,25,8,46,26,18,14,61,89,42,10,21,57,69,13,74,3,68,8,46,35,29,35,79,81,28,30,87,3,67,75,1,95,98,88,18,29,40,28,23,17,5,52,51,5,40,42,89,31,86,67,42,53,43,42,45,63,43,10,46,95,10,26,65,77,38,24,17,30,21,18,25,59,25,72,54,83,34,36,48,60,48,28,3,6,14,92,84,20,31,68,38,16,11,95,36,89,38,69,70,73,49,15,23,70,65,23,11,34,69,6,60,11,38,70,75,18,43,29,53,26,59,95,27,46,3,78,68,7,61,36,20,77,54,43,54,45,26,86,98,21,11,83,60,30,47,46,83,25,74,36,3,54,22,98,70,10,49,35,14,24,38,31,77,95,33,8,17,43,42,93,81,56,13,72,60,18,70,36,64,15,24,49,60,92,47,67,34,24,58,15,96,13,83,55,67,17,43,84,72,55,38,43,90,94,55,11,56,16,8,68,87,14,19,93,6,23,21,41,17,19,13,37,85,69,77,83,91,70,61,5,13,98,87,45,88,13,71,63,98,41,13,81,19,30,34,83,44,70,84,76,22,68,30,55,42,96,1,71,42,32,95,14,33,50,96,61,95,35,18,67,84,7,39,10,95,7,33,69,55,82,19,94,52,60,46,63,62,93,92,39,69,42,60,35,64,69,62,50,29,13,53,90,62,1,45,92,16,89,3,8,81,45,61,88,12,34,27,23,31,73,65,30,43,19,9,44,45,81,17,57,18,3,64,84,70,15,49,34,53,62,58,11,39,90,28,81,61,38,11,96,52,92,71,49,22,69,25,23,4,98,98,3,83,29,70,39,59,79,56,21,45,75,82,48,52,60,44,89,57,42,63,67,30,16,57,26,28,17,65,90,73,22,8,26,72,47,13,68,19,45,45,49,26,20,6,35,65,85,1,59,51,27,13,88,84,63,66,12,78,43,60,79,92,31,44,72,1,18,12,95,6,50,61,66,79,81,21,8,81,33,63,67,31,12,92,48,13,17,27,15,43,45,1,7,58,17,97,45,36,61,28,23,87,97,27,5,97,2,84,30,29,36,60,95,21,97,32,76,78,83,93,28,35,73,26,27,10,90,50,29,24,78,1,71,6,76,44,89,6,94,44,17,80,66,5,43,23,49,52,40,47,39,81,80,80,87,38,26,2,43,97,15,50,79,73,32,73,12,20,53,73,82,7,38,63,78,68,29,96,14,29,52,54,95,6,59,93,98,46,66,91,16,88,95,55,37,2,44,16,97,30,35,19,96,3,8,47,64,4,49,74,89,1,76,90,77,80,46,48,63,11,93,97,71,37,82,75,91,7,33,20,59,8,93,83,83,49,85,92,33,89,58,72,37,27,56,37,91,39,7,52,19,77,20,3,52,57,12,63,14,34,6,89,93,21,62,53,75,3,97,76,75,68,24,83,84,26,66,16,45,46,6,57,48,84,29,1,60,89,63,40,29,63,63,70,10,74,97,94,95,49,55,87,98,2,98,50,93,18,88,39,80,34,41,57,78,12,41,15,13,11,55,22,65,37,21,46,78,17,78,8,62,1,16,9,33,94,26,55,33,22,25,22,93,71,62,82,51,86,66,97,88,82,9,93,9,30,46,37,95,36,21,80,21,36,89,96,44,97,80,42,29,82,87,78,4,58,19,80,95,85,90,64,4,27,65,5,64,71,43,64,92,92,23,80,14,61,12,11,41,12,16,49,93,67,27,68,29,35,66,14,10,46,11,12,79,76,26,62,4,51,35,22,67,83,62,94,95,53,1,94,61,91,5,54,68,24,3,24,98,38,33,78,72,15,9,82,21,59,73,39,23,97,5,13,39,90,61,10,73,92,48,34,47,54,3,54,69,89,67,13,54,41,51,92,51,59,53,76,3,38,93,45,28,10,90,78,40,24,14,58,72,98,19,70,79,18,62,20,79,3,79,73,54,17,10,31,1,70,42,77,747932 diff --git a/src/day13/main.rs b/src/day13/main.rs new file mode 100644 index 0000000..f0c3a94 --- /dev/null +++ b/src/day13/main.rs @@ -0,0 +1,135 @@ +use aoc2019::intcode; +use std::cmp::Ordering; +use std::collections::HashMap; +use std::error::Error; +use std::fs::File; + +use ncurses; + +fn main() -> Result<(), Box> { + let f = File::open("input13")?; + let mut computer = intcode::Computer::from(f); + let mut grid: Grid = HashMap::new(); + while let Some(output) = computer.run_until_n_output(3) { + let mut output = output.into_iter(); + let xy = XY { + x: output.next().unwrap(), + y: output.next().unwrap(), + }; + let tile = Tile::from(output.next().unwrap()); + grid.insert(xy, tile); + } + + // part 1 + let blocks = grid.iter().filter(|(_, v)| **v == Tile::Block).count(); + println!("blocks: {}", blocks); + + // part2 + ncurses::initscr(); + ncurses::noecho(); + let mut computer = computer.clone_with_modified_program(vec![(0, 2)]); + let mut paddlex = 0; + let mut score = 0; + while !computer.halted { + if let Some(output) = &computer.run_until_input() { + output.chunks(3).for_each(|c| { + if let &[x, y, value] = c { + if x == -1 && y == 0 { + score = value; + } else { + let tile = Tile::from(value); + if Tile::from(value) == Tile::HorizontalPaddle { + paddlex = x; + } + ncurses::mvprintw((y + 1) as i32, x as i32, tile.char()); + } + } + }); + } + let np = next_pos(&mut computer.clone()); + ncurses::mvprintw( + 0, + 0, + &format!( + "willx: {:0>2} paddlex: {:0>2} score: {:0>7}", + np, paddlex, score + ), + ); + let joystick = match np.cmp(&paddlex) { + Ordering::Less => -1, + Ordering::Equal => 0, + Ordering::Greater => 1, + }; + computer.push_input_and_step(joystick); + ncurses::refresh(); + } + ncurses::endwin(); + println!("score: {}", score); + Ok(()) +} + +fn next_pos(computer: &mut intcode::Computer) -> isize { + while !computer.halted { + if let Some(output) = computer.run_until_input() { + for c in output.chunks(3) { + if let &[x, y, value] = c { + if x == -1 && y == 0 { + // skip score + } else if Tile::from(value) == Tile::Ball && y == 23 { + return x; + } + } + } + } + computer.push_input_and_step(0); + } + 0 +} + +#[derive(Eq, PartialEq)] +enum Tile { + Empty, + Wall, + Block, + HorizontalPaddle, + Ball, +} + +impl From for Tile { + fn from(i: isize) -> Self { + match i { + 0 => Tile::Empty, + 1 => Tile::Wall, + 2 => Tile::Block, + 3 => Tile::HorizontalPaddle, + 4 => Tile::Ball, + _ => unreachable!("there are only 5 tiles..."), + } + } +} + +impl Tile { + fn char(&self) -> &str { + match self { + Tile::Empty => " ", + Tile::Wall => "X", + Tile::Block => "O", + Tile::HorizontalPaddle => "-", + Tile::Ball => "*", + } + } +} + +#[derive(Eq, PartialEq, Hash)] +struct XY { + x: isize, + y: isize, +} + +impl From<(isize, isize)> for XY { + fn from(xy: (isize, isize)) -> Self { + XY { x: xy.0, y: xy.1 } + } +} + +type Grid = HashMap; diff --git a/src/intcode.rs b/src/intcode.rs index 0138e5f..654d369 100644 --- a/src/intcode.rs +++ b/src/intcode.rs @@ -131,7 +131,7 @@ pub struct Computer { modes: Modes, inputs: VecDeque, outputs: VecDeque, - halted: bool, + pub halted: bool, } impl Clone for Computer { @@ -181,6 +181,11 @@ impl Computer { self.outputs.pop_front() } + pub fn push_input_and_step(&mut self, input: isize) { + self.inputs.push_back(input); + self.step() + } + pub fn clone_with_modified_program(&self, u: Vec<(usize, isize)>) -> Computer { let mut computer = self.clone(); for (pos, val) in u { @@ -201,6 +206,26 @@ impl Computer { } } + pub fn run_until_input(&mut self) -> Option> { + self.step_until_input(); + if self.outputs.len() > 0 { + return Some(self.outputs.split_off(0).into_iter().collect()); + } + return None; + } + + pub fn run_until_n_output(&mut self, n: usize) -> Option> { + loop { + self.step(); + if self.outputs.len() >= n { + return Some(self.outputs.split_off(0).into_iter().collect()); + } + if self.halted { + return None; + } + } + } + pub fn run_until_output(&mut self) -> Option { loop { self.step(); @@ -223,7 +248,28 @@ impl Computer { self.run_until_output() } - fn step(&mut self) { + fn step_until_input(&mut self) { + while !self.halted { + let instruction = self.program[self.pos]; + let instruction = ModedOpcode::from(instruction); + self.modes = Modes::from(&instruction); + let advance = match Opcode::from(&instruction) { + Opcode::Add => self.add(), + Opcode::Multiply => self.multiply(), + Opcode::Input => return, + Opcode::Output => self.output(), + Opcode::JumpIfTrue => self.jump_if_true(), + Opcode::JumpIfFalse => self.jump_if_false(), + Opcode::LessThan => self.less_than(), + Opcode::Equals => self.equals(), + Opcode::RelativeAdj => self.relative_adj(), + Opcode::Halt => self.halt(), + }; + self.pos += advance; + } + } + + pub fn step(&mut self) { let instruction = self.program[self.pos]; let instruction = ModedOpcode::from(instruction); self.modes = Modes::from(&instruction); From 655b99da1b3f39933d979f1af4c51207b0c77972 Mon Sep 17 00:00:00 2001 From: foosinn Date: Wed, 3 Jun 2020 23:21:32 +0200 Subject: [PATCH 10/10] day15 --- Cargo.toml | 4 + input15 | 1 + src/day15/main.rs | 205 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 210 insertions(+) create mode 100644 input15 create mode 100644 src/day15/main.rs diff --git a/Cargo.toml b/Cargo.toml index 6477ca2..32204e2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -54,3 +54,7 @@ path = "src/day13/main.rs" [[bin]] name = "day14" path = "src/day14/main.rs" + +[[bin]] +name = "day15" +path = "src/day15/main.rs" diff --git a/input15 b/input15 new file mode 100644 index 0000000..ca5836c --- /dev/null +++ b/input15 @@ -0,0 +1 @@ +3,1033,1008,1033,1,1032,1005,1032,31,1008,1033,2,1032,1005,1032,58,1008,1033,3,1032,1005,1032,81,1008,1033,4,1032,1005,1032,104,99,1002,1034,1,1039,102,1,1036,1041,1001,1035,-1,1040,1008,1038,0,1043,102,-1,1043,1032,1,1037,1032,1042,1106,0,124,1002,1034,1,1039,1001,1036,0,1041,1001,1035,1,1040,1008,1038,0,1043,1,1037,1038,1042,1105,1,124,1001,1034,-1,1039,1008,1036,0,1041,1001,1035,0,1040,1002,1038,1,1043,101,0,1037,1042,1105,1,124,1001,1034,1,1039,1008,1036,0,1041,102,1,1035,1040,1001,1038,0,1043,101,0,1037,1042,1006,1039,217,1006,1040,217,1008,1039,40,1032,1005,1032,217,1008,1040,40,1032,1005,1032,217,1008,1039,1,1032,1006,1032,165,1008,1040,9,1032,1006,1032,165,1102,1,2,1044,1105,1,224,2,1041,1043,1032,1006,1032,179,1102,1,1,1044,1106,0,224,1,1041,1043,1032,1006,1032,217,1,1042,1043,1032,1001,1032,-1,1032,1002,1032,39,1032,1,1032,1039,1032,101,-1,1032,1032,101,252,1032,211,1007,0,35,1044,1106,0,224,1101,0,0,1044,1105,1,224,1006,1044,247,102,1,1039,1034,1002,1040,1,1035,1002,1041,1,1036,102,1,1043,1038,101,0,1042,1037,4,1044,1105,1,0,1,5,41,19,22,1,39,81,29,20,15,82,33,18,45,30,32,55,28,26,70,13,56,32,28,18,3,59,90,11,95,15,85,8,61,25,59,24,34,1,85,5,25,54,57,18,20,54,80,91,28,65,36,12,44,36,13,92,24,56,13,39,69,29,79,10,41,27,23,25,72,20,3,61,15,51,11,12,12,48,10,45,13,29,49,90,30,17,9,41,21,18,7,30,48,17,83,71,4,10,31,10,96,81,77,9,50,39,21,36,33,72,12,3,23,79,18,4,75,17,58,64,8,7,97,60,72,72,1,94,55,42,2,94,2,21,88,19,82,57,96,19,25,27,41,62,15,40,23,61,86,27,73,61,13,46,52,81,12,34,23,73,23,59,1,30,47,9,99,10,37,17,28,98,5,92,73,8,63,4,86,76,79,7,30,68,28,91,12,12,98,74,4,22,44,10,23,45,37,16,90,76,23,74,75,12,21,38,14,15,76,28,49,71,7,6,6,71,53,33,12,87,15,92,66,21,38,13,53,92,34,49,25,6,67,21,27,89,24,61,25,30,41,30,99,28,19,41,90,51,74,14,33,54,48,10,14,42,2,67,76,10,21,2,67,43,27,69,11,16,78,7,36,9,24,48,63,81,53,29,94,34,25,99,66,47,17,97,33,52,11,62,22,52,30,23,89,95,15,13,50,48,26,10,6,69,78,13,6,94,1,28,67,10,70,16,50,19,24,15,79,50,27,3,19,62,4,31,83,20,17,83,67,5,80,26,36,62,87,3,10,80,22,65,60,10,78,4,20,60,30,11,7,83,10,13,72,81,37,22,14,55,63,51,27,32,77,52,20,50,16,48,2,55,10,53,26,84,6,87,43,37,26,3,85,62,25,78,50,16,10,37,22,54,5,80,24,7,32,49,18,27,12,41,70,82,20,34,91,15,98,77,22,6,79,3,8,54,17,32,4,44,2,97,14,15,65,30,97,14,79,75,11,77,5,61,37,20,91,20,45,74,19,40,2,41,89,12,34,44,18,62,57,17,68,22,96,7,59,63,2,60,70,2,26,75,26,3,53,19,80,16,97,7,34,58,52,66,24,75,25,30,75,42,13,12,89,13,3,84,92,1,75,30,54,43,2,56,15,1,15,84,99,6,98,42,17,29,1,18,26,70,71,29,91,23,21,87,66,18,38,32,18,81,65,2,58,99,12,4,84,24,32,88,30,67,49,29,59,64,18,70,10,24,56,5,27,97,50,4,28,85,65,16,67,83,15,16,61,18,86,8,36,25,36,29,97,45,19,81,41,29,45,30,69,26,57,93,27,72,34,30,99,61,2,48,16,12,76,98,28,14,32,32,90,48,10,30,57,23,39,2,8,39,33,13,88,34,31,74,15,60,8,47,60,31,5,79,1,98,86,33,3,99,33,62,11,96,25,22,38,98,84,3,56,70,49,3,8,56,87,4,29,59,65,26,34,77,7,14,78,26,25,70,49,3,31,45,92,24,95,17,4,9,4,96,64,92,27,67,4,99,6,44,7,16,86,2,75,1,6,68,81,4,1,44,49,7,92,8,40,36,25,81,13,56,99,10,2,30,72,6,43,30,12,43,93,19,20,23,95,10,19,66,63,28,96,40,50,8,15,56,38,13,93,42,71,12,18,87,8,4,21,85,9,2,66,77,10,80,26,61,9,43,20,88,10,39,67,55,31,49,17,58,26,80,20,84,54,49,5,73,11,52,15,63,7,62,24,57,92,61,25,87,56,37,31,38,14,99,0,0,21,21,1,10,1,0,0,0,0,0,0 diff --git a/src/day15/main.rs b/src/day15/main.rs new file mode 100644 index 0000000..8fa0f5a --- /dev/null +++ b/src/day15/main.rs @@ -0,0 +1,205 @@ +use std::collections::HashMap; +use std::error::Error; +use std::fs::File; + +use aoc2019::intcode; + +fn main() -> Result<(), Box> { + let f = File::open("input15")?; + let computer = intcode::Computer::from(f); + let mut map = Map::new(); + let steps = map.walk(&XY { x: 0, y: 0 }, &computer, 0).unwrap(); + + for y in map.ymin..=map.ymax { + for x in map.xmin..=map.xmax { + if x == 0 && y == 0 { + print!("0"); + continue; + } + let status = map.m.get(&XY { x, y }).unwrap_or(&Status::Empty); + let c = match status { + Status::HitWall => "#", + Status::MoveComplete => ".", + Status::Finished => "X", + Status::Empty => " ", + Status::Oxigenated => "o", + }; + print!("{}", c); + } + println!(""); + } + + println!("i walked {} steps", steps); + let steps = map.fill(); + println!("filled with oxygen after {} minutes", steps); + + Ok(()) +} + +#[derive(Default, Debug)] +struct Map { + m: HashMap, + xmin: isize, + xmax: isize, + ymin: isize, + ymax: isize, +} + +impl Map { + fn new() -> Self { + Map::default() + } + + fn walk(&mut self, start: &XY, computer: &intcode::Computer, steps: usize) -> Option { + let steps = steps + 1; + let mut result = None; + for dir in 1..=4 { + let direction = Direction::from(dir); + let xy = start.add((&direction).into()); + if self.m.contains_key(&xy) { + continue; + } + self.update_limits(&xy); + let mut computer = computer.clone(); + if let Some(status) = computer.run_io(dir) { + let status = Status::from(status); + self.m.insert(xy.clone(), status.clone()); + match status { + Status::HitWall => (), + Status::MoveComplete => match self.walk(&xy, &computer, steps) { + Some(i) => result = Some(i + 1), + None => (), + }, + Status::Finished => result = Some(1), + _ => unreachable!("unknown status"), + } + } else { + unreachable!("computer unexpectedly halted"); + } + } + result + } + + fn fill(&mut self) -> usize { + let mut src: Vec = self + .m + .iter() + .filter_map(|(xy, status)| match status { + Status::Finished => Some(xy), + _ => None, + }) + .cloned() + .collect(); + let mut steps = 0; + while src.len() > 0 { + steps += 1; + src.iter() + .for_each(|xy| *self.m.get_mut(xy).unwrap() = Status::Oxigenated); + src = src + .into_iter() + .map(|xy| { + (1..=4) + .map(Direction::from) + .map(move |d| xy.add((&d).into())) + }) + .flatten() + .filter(|xy| match self.m.get(xy) { + Some(Status::MoveComplete) => true, + _ => false, + }) + .collect(); + } + assert_eq!( + self.m + .values() + .filter(|status| match status { + Status::MoveComplete => true, + _ => false, + }) + .count(), + 0 + ); + steps - 1 + } + + fn update_limits(&mut self, xy: &XY) { + if self.xmin > xy.x { + self.xmin = xy.x + } + if self.xmax < xy.x { + self.xmax = xy.x + } + if self.ymin > xy.y { + self.ymin = xy.y + } + if self.ymax < xy.y { + self.ymax = xy.y + } + } +} + +#[derive(Debug)] +enum Direction { + North = 1, + South = 2, + West = 3, + East = 4, +} + +impl From for Direction { + fn from(i: isize) -> Self { + match i { + 1 => Direction::North, + 2 => Direction::South, + 3 => Direction::West, + 4 => Direction::East, + _ => unreachable!("no status for computer output"), + } + } +} + +impl Into<(isize, isize)> for &Direction { + fn into(self) -> (isize, isize) { + match self { + Direction::North => (0, 1), + Direction::South => (0, -1), + Direction::West => (-1, 0), + Direction::East => (1, 0), + } + } +} + +#[derive(Clone, Debug)] +enum Status { + HitWall = 0, + MoveComplete = 1, + Finished = 2, + Empty = 3, + Oxigenated = 4, +} + +impl From for Status { + fn from(i: isize) -> Self { + match i { + 0 => Status::HitWall, + 1 => Status::MoveComplete, + 2 => Status::Finished, + _ => unreachable!("no status for computer output"), + } + } +} + +#[derive(PartialEq, Eq, Hash, Clone, Debug)] +struct XY { + x: isize, + y: isize, +} + +impl XY { + fn add(&self, delta: (isize, isize)) -> XY { + XY { + x: self.x + delta.0, + y: self.y + delta.1, + } + } +}