From 0ad72cab715a88424f29f8440496c09767ca9ad0 Mon Sep 17 00:00:00 2001 From: "Dr. Matthias Ratajczak" Date: Tue, 9 Aug 2022 14:15:01 +0200 Subject: [PATCH] add 11 (WIP) --- euler11/Cargo.toml | 8 ++ euler11/grid.txt | 20 +++++ euler11/src/main.rs | 192 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 220 insertions(+) create mode 100644 euler11/Cargo.toml create mode 100644 euler11/grid.txt create mode 100644 euler11/src/main.rs diff --git a/euler11/Cargo.toml b/euler11/Cargo.toml new file mode 100644 index 0000000..2d696df --- /dev/null +++ b/euler11/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "euler11" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/euler11/grid.txt b/euler11/grid.txt new file mode 100644 index 0000000..4ac2451 --- /dev/null +++ b/euler11/grid.txt @@ -0,0 +1,20 @@ +08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08 +49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00 +81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65 +52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91 +22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80 +24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50 +32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70 +67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21 +24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72 +21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95 +78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92 +16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57 +86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58 +19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40 +04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66 +88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69 +04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36 +20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16 +20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54 +01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48 diff --git a/euler11/src/main.rs b/euler11/src/main.rs new file mode 100644 index 0000000..39de157 --- /dev/null +++ b/euler11/src/main.rs @@ -0,0 +1,192 @@ +use std::{fmt::Debug, fs}; + +const LENGTH: usize = 4; + +type Data = u32; +type Neighbours = Vec; + +struct Coordinate { + x: usize, + y: usize, +} + +impl Coordinate { + fn new(x: usize, y: usize) -> Self { + Self { x, y } + } +} + +impl Debug for Coordinate { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let inner = &format!("{},{}", self.x, self.y); + f.write_str(inner) + } +} + +struct Grid { + grid: Vec>, + nx: usize, + ny: usize, + curr_x: usize, + curr_y: usize, + curr_direction: Direction, + done: bool, +} + +impl Grid { + fn from_file(filename: &str) -> Self { + let grid: Vec> = fs::read_to_string(filename) + .unwrap() + .split_terminator('\n') + .map(|line| { + line.split_whitespace() + .map(|cell| cell.parse::().unwrap() as Data) + .collect() + }) + .collect(); + let ny = grid.len(); + let nx = grid[0].len(); + Grid { + grid, + nx, + ny, + curr_x: 0, + curr_y: 0, + curr_direction: Direction::None, + done: false, + } + } + + fn run(&mut self) { + let mut largest = 0; + loop { + if let Some(coordinates) = self.next() { + let value = coordinates.iter().map(|c| self.grid[c.y][c.x]).product(); + if value > largest { + largest = value; + } + } + if self.done { + break; + } + } + println!("{largest}"); + } + + fn advance_index(&mut self) { + if self.curr_x == self.nx - 1 { + self.curr_x = 0; + self.curr_y += 1; + if self.curr_y == self.ny { + self.done = true; + } + } else { + self.curr_x += 1; + } + } + + fn get_neighbours(&self) -> Option { + match self.curr_direction { + Direction::Down => self.get_neighbours_down(), + Direction::Right => self.get_neighbours_right(), + Direction::DiagonalUp => self.get_neighbours_diag_up(), + Direction::DiagonalDown => self.get_neighbours_diag_down(), + Direction::None => unreachable!(), + } + } + + fn get_neighbours_down(&self) -> Option { + let max_y = self.curr_y + LENGTH; + if max_y > self.ny { + None + } else { + Some( + (self.curr_y..max_y) + .map(|y| Coordinate::new(self.curr_x, y)) + .collect(), + ) + } + } + + fn get_neighbours_right(&self) -> Option { + let max_x = self.curr_x + LENGTH; + if max_x > self.nx { + None + } else { + Some( + (self.curr_x..max_x) + .map(|x| Coordinate::new(x, self.curr_y)) + .collect(), + ) + } + } + + fn get_neighbours_diag_up(&self) -> Option { + let max_x = self.curr_x + LENGTH; + let min_y = self.curr_y.wrapping_sub(LENGTH); + if max_x > self.nx || min_y > self.ny { + None + } else { + Some( + (self.curr_x..max_x) + .zip(self.curr_y..min_y) + .map(|(x, y)| Coordinate::new(x, y)) + .collect(), + ) + } + } + + fn get_neighbours_diag_down(&self) -> Option { + let max_x = self.curr_x + LENGTH; + let max_y = self.curr_y + LENGTH; + if max_x > self.nx || max_y > self.ny { + None + } else { + Some( + (self.curr_x..max_x) + .zip(self.curr_y..max_y) + .map(|(x, y)| Coordinate::new(x, y)) + .collect(), + ) + } + } +} + +impl Iterator for Grid { + type Item = Neighbours; + + fn next(&mut self) -> Option { + let has_wrapped; + (self.curr_direction, has_wrapped) = self.curr_direction.next(); + if has_wrapped { + self.advance_index(); + }; + self.get_neighbours() + } +} + +#[derive(Debug)] +enum Direction { + None, + Down, + Right, + DiagonalUp, + DiagonalDown, +} + +impl Direction { + fn next(&self) -> (Self, bool) { + match self { + Direction::None => (Direction::Down, false), + Direction::Down => (Direction::Right, false), + Direction::Right => (Direction::DiagonalUp, false), + Direction::DiagonalUp => (Direction::DiagonalDown, false), + Direction::DiagonalDown => (Direction::Down, true), + } + } +} + +fn main() { + let mut grid = Grid::from_file("grid.txt"); + grid.run(); +}