From 5a4efd75dbbaf4e53306a4f6786143a931243a43 Mon Sep 17 00:00:00 2001 From: Matej Focko Date: Fri, 26 Jan 2024 13:35:04 +0100 Subject: [PATCH] =?UTF-8?q?rs:=20add=20=C2=AB576.=20Out=20of=20Boundary=20?= =?UTF-8?q?Paths=C2=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matej Focko --- rs/out-of-boundary-paths.rs | 58 +++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 rs/out-of-boundary-paths.rs diff --git a/rs/out-of-boundary-paths.rs b/rs/out-of-boundary-paths.rs new file mode 100644 index 0000000..5e0f234 --- /dev/null +++ b/rs/out-of-boundary-paths.rs @@ -0,0 +1,58 @@ +use std::collections::HashMap; + +const CAP: i64 = 1000000007; + +struct DPSolver { + m: i32, + n: i32, + max_move: i32, + dp: Vec>, +} + +impl DPSolver { + pub fn new(m: i32, n: i32, max_move: i32) -> Self { + let dp = vec![HashMap::new(); (m as usize) * (n as usize)]; + Self { m, n, max_move, dp } + } + + fn index(&self, y: i32, x: i32) -> usize { + (y * self.n + x) as usize + } + + fn dfs(&mut self, y: i32, x: i32, moves: i32) -> i64 { + if y < 0 || y >= self.m || x < 0 || x >= self.n { + // BASE: we got out of the bounds + return 1; + } + + if moves <= 0 { + // BASE: all moves were used or there are no moves left + return 0; + } + + let idx = self.index(y, x); + + if let Some(paths) = self.dp[idx].get(&moves) { + return *paths; + } + + let mut options = 0; + for (dx, dy) in [(0, 1), (1, 0), (0, -1), (-1, 0)] { + options = (options + self.dfs(y + dy, x + dx, moves - 1)) % CAP; + } + + self.dp[idx].insert(moves, options); + options + } + + pub fn get(&mut self, y0: i32, x0: i32) -> i32 { + self.dfs(y0, x0, self.max_move) as i32 + } +} + +struct Solution {} +impl Solution { + pub fn find_paths(m: i32, n: i32, max_move: i32, start_row: i32, start_column: i32) -> i32 { + DPSolver::new(m, n, max_move).get(start_row, start_column) + } +}