leetcode

Leetcode problem solutions
git clone https://git.sinitax.com/sinitax/leetcode
Log | Files | Refs | sfeed.txt

commit c54637f6eb8d480a682f85443b13884214c0ac65
parent 38c6242d03f18bd30f775bc02d3e6c452a5d4c3b
Author: Louis Burda <quent.burda@gmail.com>
Date:   Sun, 24 Nov 2024 02:29:03 +0100

Add new helper functions to keep testcases compact

Diffstat:
Msrc/bin/0001-two-sum.rs | 7++++---
Msrc/bin/0004-median-of-two-sorted-arrays.rs | 12++++++++++--
Msrc/bin/0019-remove-nth-node-from-end-of-list.rs | 23++++++++++++-----------
Msrc/bin/0386-lexicographical-numbers.rs | 9+++++++--
Msrc/bin/1574-shortest-subarray-to-be-removed-to-make-array-sorted.rs | 7++++---
Msrc/bin/1671-minimum-number-of-removals-to-make-mountain-array.rs | 5+++--
Msrc/bin/1861-rotating-the-box.rs | 32++++++++------------------------
Msrc/bin/1975-maximum-matrix-sum.rs | 8++++----
Msrc/bin/2064-minimized-maximum-of-products-distributed-to-any-store.rs | 15++++++++-------
Msrc/bin/2070-most-beautiful-item-for-each-query.rs | 24++++++++----------------
Msrc/bin/2257-count-unguarded-cells-in-the-grid.rs | 19++++---------------
Msrc/bin/2461-maximum-sum-of-distinct-subarrays-with-length-k.rs | 8+++-----
Msrc/bin/2463-minimum-total-distance-traveled.rs | 7++++---
Msrc/bin/2491-divide-players-into-teams-of-equal-skill.rs | 8+++++---
Msrc/bin/2563-count-the-number-of-fair-pairs.rs | 7++++---
Msrc/bin/2601-prime-subtraction-operation.rs | 10++++++----
Msrc/bin/3254-find-the-power-of-k-size-subarrays-i.rs | 14++++++--------
Msrc/lib.rs | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
18 files changed, 155 insertions(+), 127 deletions(-)

diff --git a/src/bin/0001-two-sum.rs b/src/bin/0001-two-sum.rs @@ -66,11 +66,12 @@ pub fn main() { #[cfg(test)] mod tests { use crate::Solution; + use leetcode::vi; #[test] fn test() { - assert_eq!(Solution::two_sum(vec![2, 7, 11, 15], 9), vec![0, 1]); - assert_eq!(Solution::two_sum(vec![3, 2, 4], 6), vec![1, 2]); - assert_eq!(Solution::two_sum(vec![3, 3], 6), vec![0, 1]); + assert_eq!(Solution::two_sum(vi("[2,7,11,15]"), 9), vi("[0,1]")); + assert_eq!(Solution::two_sum(vi("[3,2,4]"), 6), vi("[1,2]")); + assert_eq!(Solution::two_sum(vi("[3,3]"), 6), vi("[0,1]")); } } diff --git a/src/bin/0004-median-of-two-sorted-arrays.rs b/src/bin/0004-median-of-two-sorted-arrays.rs @@ -117,9 +117,17 @@ pub fn main() { #[cfg(test)] mod tests { use crate::Solution; + use leetcode::vi; + #[test] fn test() { - assert!(Solution::find_median_sorted_arrays(vec![1, 3], vec![2]) == 2.0); - assert!(Solution::find_median_sorted_arrays(vec![1, 2], vec![3, 4]) == 2.5); + assert_eq!( + Solution::find_median_sorted_arrays(vi("[1,3]"), vi("[2]")), + 2.0 + ); + assert_eq!( + Solution::find_median_sorted_arrays(vi("[1,2]"), vi("[3,4]")), + 2.5 + ); } } diff --git a/src/bin/0019-remove-nth-node-from-end-of-list.rs b/src/bin/0019-remove-nth-node-from-end-of-list.rs @@ -89,21 +89,22 @@ pub fn main() { #[cfg(test)] mod tests { - use crate::{build_list, Solution}; + use crate::build_list; + use crate::ListNode; + use crate::Solution; + use leetcode::vi; + + fn l(s: &str) -> Option<Box<ListNode>> { + build_list(vi(s)) + } #[test] fn test() { assert_eq!( - Solution::remove_nth_from_end(build_list(vec![1, 2, 3, 4, 5]), 2), - build_list(vec![1, 2, 3, 5]) - ); - assert_eq!( - Solution::remove_nth_from_end(build_list(vec![1]), 1), - build_list(vec![]) - ); - assert_eq!( - Solution::remove_nth_from_end(build_list(vec![1, 2]), 1), - build_list(vec![1]) + Solution::remove_nth_from_end(l("[1,2,3,4,5]"), 2), + l("[1,2,3,5]") ); + assert_eq!(Solution::remove_nth_from_end(l("[1]"), 1), l("[]")); + assert_eq!(Solution::remove_nth_from_end(l("[1,2]"), 1), l("[1]")); } } diff --git a/src/bin/0386-lexicographical-numbers.rs b/src/bin/0386-lexicographical-numbers.rs @@ -52,9 +52,14 @@ pub fn main() { #[cfg(test)] mod tests { use crate::Solution; + use leetcode::vi; + #[test] fn examples() { - assert!(Solution::lexical_order(13) == vec![1, 10, 11, 12, 13, 2, 3, 4, 5, 6, 7, 8, 9]); - assert!(Solution::lexical_order(2) == vec![1, 2]); + assert_eq!( + Solution::lexical_order(13), + vi("[1,10,11,12,13,2,3,4,5,6,7,8,9]") + ); + assert_eq!(Solution::lexical_order(2), vi("[1,2]")); } } diff --git a/src/bin/1574-shortest-subarray-to-be-removed-to-make-array-sorted.rs b/src/bin/1574-shortest-subarray-to-be-removed-to-make-array-sorted.rs @@ -81,17 +81,18 @@ pub fn main() { #[cfg(test)] mod tests { use crate::Solution; + use leetcode::vi; #[test] fn test() { assert_eq!( - Solution::find_length_of_shortest_subarray(vec![1, 2, 3, 10, 4, 2, 3, 5]), + Solution::find_length_of_shortest_subarray(vi("[1,2,3,10,4,2,3,5]")), 3 ); assert_eq!( - Solution::find_length_of_shortest_subarray(vec![5, 4, 3, 2, 1]), + Solution::find_length_of_shortest_subarray(vi("[5,4,3,2,1]")), 4 ); - assert_eq!(Solution::find_length_of_shortest_subarray(vec![1, 2, 3]), 0); + assert_eq!(Solution::find_length_of_shortest_subarray(vi("[1,2,3]")), 0); } } diff --git a/src/bin/1671-minimum-number-of-removals-to-make-mountain-array.rs b/src/bin/1671-minimum-number-of-removals-to-make-mountain-array.rs @@ -71,12 +71,13 @@ pub fn main() { #[cfg(test)] mod tests { use crate::Solution; + use leetcode::vi; #[test] fn test() { - assert_eq!(Solution::minimum_mountain_removals(vec![1, 3, 1]), 0); + assert_eq!(Solution::minimum_mountain_removals(vi("[1,3,1]")), 0); assert_eq!( - Solution::minimum_mountain_removals(vec![2, 1, 1, 5, 6, 2, 3, 1]), + Solution::minimum_mountain_removals(vi("[2,1,1,5,6,2,3,1]")), 3 ); } diff --git a/src/bin/1861-rotating-the-box.rs b/src/bin/1861-rotating-the-box.rs @@ -83,43 +83,27 @@ impl Solution { } pub fn main() { - let in_box = arg(1).split("|").map(leetcode::parse).collect(); - println!("{:?}", Solution::rotate_the_box(in_box)); + println!("{:?}", Solution::rotate_the_box(arg_into(1))); } #[cfg(test)] mod tests { use crate::Solution; + use leetcode::vvc; #[test] fn test() { assert_eq!( - Solution::rotate_the_box(vec![vec!['#', '.', '#']]), - vec![vec!['.'], vec!['#'], vec!['#']] + Solution::rotate_the_box(vvc("[[#,.,#]]")), + vvc("[[.],[#],[#]]") ); assert_eq!( - Solution::rotate_the_box(vec![vec!['#', '.', '*', '.'], vec!['#', '#', '*', '.']]), - vec![ - vec!['#', '.'], - vec!['#', '#'], - vec!['*', '*'], - vec!['.', '.'] - ] + Solution::rotate_the_box(vvc("[[#,.,*,.],[#,#,*,.]]")), + vvc("[[#,.],[#,#],[*,*],[.,.]]") ); assert_eq!( - Solution::rotate_the_box(vec![ - vec!['#', '#', '*', '.', '*', '.'], - vec!['#', '#', '#', '*', '.', '.'], - vec!['#', '#', '#', '.', '#', '.'] - ]), - vec![ - vec!['.', '#', '#'], - vec!['.', '#', '#'], - vec!['#', '#', '*'], - vec!['#', '*', '.'], - vec!['#', '.', '*'], - vec!['#', '.', '.'] - ] + Solution::rotate_the_box(vvc("[[#,#,*,.,*,.],[#,#,#,*,.,.],[#,#,#,.,#,.]]")), + vvc("[[.,#,#],[.,#,#],[#,#,*],[#,*,.],[#,.,*],[#,.,.]]") ) } } diff --git a/src/bin/1975-maximum-matrix-sum.rs b/src/bin/1975-maximum-matrix-sum.rs @@ -59,19 +59,19 @@ impl Solution { } pub fn main() { - let matrix = arg(1).split("|").map(leetcode::parse).collect(); - println!("{:?}", Solution::max_matrix_sum(matrix)); + println!("{:?}", Solution::max_matrix_sum(arg_into(1))); } #[cfg(test)] mod tests { use crate::Solution; + use leetcode::vvi; #[test] fn test() { - assert_eq!(Solution::max_matrix_sum(vec![vec![1, -1], vec![-1, 1]]), 4); + assert_eq!(Solution::max_matrix_sum(vvi("[[1,-1],[-1,1]]")), 4); assert_eq!( - Solution::max_matrix_sum(vec![vec![1, 2, 3], vec![-1, -2, -3], vec![1, 2, 3]]), + Solution::max_matrix_sum(vvi("[[1,2,3],[-1,-2,-3],[1,2,3]]")), 16 ); } diff --git a/src/bin/2064-minimized-maximum-of-products-distributed-to-any-store.rs b/src/bin/2064-minimized-maximum-of-products-distributed-to-any-store.rs @@ -94,26 +94,27 @@ pub fn main() { #[cfg(test)] mod tests { use crate::Solution; + use leetcode::vi; #[test] fn test() { - assert_eq!(Solution::minimized_maximum(6, vec![11, 6]), 3); - assert_eq!(Solution::minimized_maximum(7, vec![15, 10, 10]), 5); - assert_eq!(Solution::minimized_maximum(1, vec![100000]), 100000); + assert_eq!(Solution::minimized_maximum(6, vi("[11,6]")), 3); + assert_eq!(Solution::minimized_maximum(7, vi("[15,10,10]")), 5); + assert_eq!(Solution::minimized_maximum(1, vi("[100000]")), 100000); assert_eq!( - Solution::minimized_maximum(15, vec![16, 24, 18, 26, 18, 28, 11, 8, 22, 26, 21, 23]), + Solution::minimized_maximum(15, vi("[16,24,18,26,18,28,11,8,22,26,21,23]")), 24 ); assert_eq!( - Solution::minimized_maximum(22, vec![25, 11, 29, 6, 24, 4, 29, 18, 6, 13, 25, 30]), + Solution::minimized_maximum(22, vi("[25,11,29,6,24,4,29,18,6,13,25,30]")), 13 ); assert_eq!( - Solution::minimized_maximum(14, vec![7, 8, 22, 13, 26, 21, 4, 5, 23, 2, 2]), + Solution::minimized_maximum(14, vi("[7,8,22,13,26,21,4,5,23,2,2]")), 21 ); assert_eq!( - Solution::minimized_maximum(20, vec![8, 7, 13, 27, 3, 2, 29, 2, 17, 2, 3, 13]), + Solution::minimized_maximum(20, vi("[8,7,13,27,3,2,29,2,17,2,3,13]")), 9 ); } diff --git a/src/bin/2070-most-beautiful-item-for-each-query.rs b/src/bin/2070-most-beautiful-item-for-each-query.rs @@ -77,35 +77,27 @@ impl Solution { } pub fn main() { - println!( - "{:?}", - Solution::maximum_beauty(arg(1).split("|").map(parse).collect(), arg_into(2)) - ) + println!("{:?}", Solution::maximum_beauty(arg_into(1), arg_into(2))) } #[cfg(test)] mod tests { use crate::Solution; + use leetcode::{vi, vvi}; #[test] fn test() { assert_eq!( - Solution::maximum_beauty( - vec![vec![1, 2], vec![3, 2], vec![2, 4], vec![5, 6], vec![3, 5]], - vec![1, 2, 3, 4, 5, 6] - ), - vec![2, 4, 5, 5, 6, 6] + Solution::maximum_beauty(vvi("[[1,2],[3,2],[2,4],[5,6],[3,5]]"), vi("[1,2,3,4,5,6]")), + vi("[2,4,5,5,6,6]") ); assert_eq!( - Solution::maximum_beauty( - vec![vec![1, 2], vec![1, 2], vec![1, 3], vec![1, 4]], - vec![1] - ), - vec![4] + Solution::maximum_beauty(vvi("[[1,2],[1,2],[1,3],[1,4]]"), vi("[1]")), + vi("[4]") ); assert_eq!( - Solution::maximum_beauty(vec![vec![10, 1000]], vec![5]), - vec![0] + Solution::maximum_beauty(vvi("[[10,1000]]"), vi("[5]")), + vi("[0]") ); } } diff --git a/src/bin/2257-count-unguarded-cells-in-the-grid.rs b/src/bin/2257-count-unguarded-cells-in-the-grid.rs @@ -107,36 +107,25 @@ impl Solution { } pub fn main() { - let guards = arg(3).split("|").map(leetcode::parse).collect(); - let walls = arg(4).split("|").map(leetcode::parse).collect(); println!( "{}", - Solution::count_unguarded(arg_into(1), arg_into(2), guards, walls) + Solution::count_unguarded(arg_into(1), arg_into(2), arg_into(3), arg_into(4)) ); } #[cfg(test)] mod tests { use crate::Solution; + use leetcode::vvi; #[test] fn test() { assert_eq!( - Solution::count_unguarded( - 4, - 6, - vec![vec![0, 0], vec![1, 1], vec![2, 3]], - vec![vec![0, 1], vec![2, 2], vec![1, 4]] - ), + Solution::count_unguarded(4, 6, vvi("[[0,0],[1,1],[2,3]]"), vvi("[[0,1],[2,2],[1,4]]")), 7 ); assert_eq!( - Solution::count_unguarded( - 3, - 3, - vec![vec![1, 1]], - vec![vec![0, 1], vec![1, 0], vec![2, 1], vec![1, 2]] - ), + Solution::count_unguarded(3, 3, vvi("[[1,1]]"), vvi("[[0,1],[1,0],[2,1],[1,2]]")), 4 ); } diff --git a/src/bin/2461-maximum-sum-of-distinct-subarrays-with-length-k.rs b/src/bin/2461-maximum-sum-of-distinct-subarrays-with-length-k.rs @@ -79,13 +79,11 @@ pub fn main() { #[cfg(test)] mod tests { use crate::Solution; + use leetcode::vi; #[test] fn test() { - assert_eq!( - Solution::maximum_subarray_sum(vec![1, 5, 4, 2, 9, 9, 9], 3), - 15 - ); - assert_eq!(Solution::maximum_subarray_sum(vec![4, 4, 4], 3), 0); + assert_eq!(Solution::maximum_subarray_sum(vi("[1,5,4,2,9,9,9]"), 3), 15); + assert_eq!(Solution::maximum_subarray_sum(vi("[4,4,4]"), 3), 0); } } diff --git a/src/bin/2463-minimum-total-distance-traveled.rs b/src/bin/2463-minimum-total-distance-traveled.rs @@ -129,22 +129,23 @@ impl Solution { pub fn main() { println!( "{:?}", - Solution::minimum_total_distance(arg_into(1), arg(2).split("|").map(parse).collect()) + Solution::minimum_total_distance(arg_into(1), arg_into(2)) ) } #[cfg(test)] mod tests { use crate::Solution; + use leetcode::{vi, vvi}; #[test] fn test() { assert_eq!( - Solution::minimum_total_distance(vec![0, 4, 6], vec![vec![2, 2], vec![6, 2]]), + Solution::minimum_total_distance(vi("[0,4,6]"), vvi("[[2,2],[6,2]]")), 4 ); assert_eq!( - Solution::minimum_total_distance(vec![1, -1], vec![vec![-2, 1], vec![2, 1]]), + Solution::minimum_total_distance(vi("[1,-1]"), vvi("[[-2,1],[2,1]]")), 2 ); } diff --git a/src/bin/2491-divide-players-into-teams-of-equal-skill.rs b/src/bin/2491-divide-players-into-teams-of-equal-skill.rs @@ -77,10 +77,12 @@ fn main() { #[cfg(test)] mod tests { use crate::Solution; + use leetcode::vi; + #[test] fn test() { - assert_eq!(Solution::divide_players(vec![3, 2, 5, 1, 3, 4]), 22); - assert_eq!(Solution::divide_players(vec![3, 4]), 12); - assert_eq!(Solution::divide_players(vec![1, 1, 2, 3]), -1); + assert_eq!(Solution::divide_players(vi("[3,2,5,1,3,4]")), 22); + assert_eq!(Solution::divide_players(vi("[3,4]")), 12); + assert_eq!(Solution::divide_players(vi("[1,1,2,3]")), -1); } } diff --git a/src/bin/2563-count-the-number-of-fair-pairs.rs b/src/bin/2563-count-the-number-of-fair-pairs.rs @@ -70,11 +70,12 @@ pub fn main() { #[cfg(test)] mod tests { use crate::Solution; + use leetcode::vi; #[test] fn test() { - assert_eq!(Solution::count_fair_pairs(vec![0, 1, 7, 4, 4, 5], 3, 6), 6); - assert_eq!(Solution::count_fair_pairs(vec![1, 7, 9, 2, 5], 11, 11), 1); - assert_eq!(Solution::count_fair_pairs(vec![0, 0, 0, 0, 0, 0], 0, 0), 15); + assert_eq!(Solution::count_fair_pairs(vi("[0,1,7,4,4,5]"), 3, 6), 6); + assert_eq!(Solution::count_fair_pairs(vi("[1,7,9,2,5]"), 11, 11), 1); + assert_eq!(Solution::count_fair_pairs(vi("[0,0,0,0,0,0]"), 0, 0), 15); } } diff --git a/src/bin/2601-prime-subtraction-operation.rs b/src/bin/2601-prime-subtraction-operation.rs @@ -91,11 +91,13 @@ fn main() { #[cfg(test)] mod tests { use crate::Solution; + use leetcode::vi; + #[test] fn test() { - assert!(Solution::prime_sub_operation(vec![4, 9, 6, 10])); - assert!(Solution::prime_sub_operation(vec![6, 8, 11, 12])); - assert!(!Solution::prime_sub_operation(vec![5, 8, 3])); - assert!(Solution::prime_sub_operation(vec![998, 2])); + assert!(Solution::prime_sub_operation(vi("[4,9,6,10]"))); + assert!(Solution::prime_sub_operation(vi("[6,8,11,12]"))); + assert!(!Solution::prime_sub_operation(vi("[5,8,3]"))); + assert!(Solution::prime_sub_operation(vi("[998,2]"))); } } diff --git a/src/bin/3254-find-the-power-of-k-size-subarrays-i.rs b/src/bin/3254-find-the-power-of-k-size-subarrays-i.rs @@ -78,20 +78,18 @@ pub fn main() { #[cfg(test)] mod tests { use crate::Solution; + use leetcode::vi; #[test] fn test() { assert_eq!( - Solution::results_array(vec![1, 2, 3, 4, 3, 2, 5], 3), - vec![3, 4, -1, -1, -1] + Solution::results_array(vi("[1,2,3,4,3,2,5]"), 3), + vi("[3,4,-1,-1,-1]") ); + assert_eq!(Solution::results_array(vi("[2,2,2,2,2]"), 4), vi("[-1,-1]")); assert_eq!( - Solution::results_array(vec![2, 2, 2, 2, 2], 4), - vec![-1, -1] - ); - assert_eq!( - Solution::results_array(vec![3, 2, 3, 2, 3, 2], 2), - vec![-1, 3, -1, 3, -1] + Solution::results_array(vi("[3,2,3,2,3,2]"), 2), + vi("[-1,3,-1,3,-1]") ); } } diff --git a/src/lib.rs b/src/lib.rs @@ -1,23 +1,42 @@ use std::env; -use std::fmt::Debug; use std::str::{self, FromStr}; pub trait Parsable { fn parse(s: &str) -> Self; } -impl<T: str::FromStr> Parsable for Vec<T> -where - <T as str::FromStr>::Err: Debug, -{ +impl<T: Parsable> Parsable for Vec<T> { fn parse(s: &str) -> Vec<T> { - s.split(",") - .map(|w| { - w.trim() - .parse() - .unwrap_or_else(|_| panic!("Failed to parse element in argument ({s})")) - }) - .collect() + let mut depth = 0; + let mut sep = Vec::new(); + let s = s + .trim() + .strip_prefix("[") + .expect("Missing [") + .strip_suffix("]") + .expect("Missing ]"); + let mut last = 0; + for (i, c) in s.chars().enumerate() { + if c == '[' { + depth += 1; + } else if c == ']' { + if depth == 0 { + panic!("Invalid array format"); + } + depth -= 1; + } else if c == ',' && depth == 0 { + sep.push((last, i)); + last = i + 1; + } + } + if last != s.len() { + sep.push((last, s.len())); + } + let mut out = Vec::new(); + for (start, end) in sep { + out.push(parse(s[start..end].trim())); + } + out } } @@ -27,10 +46,34 @@ impl Parsable for i32 { } } +impl Parsable for char { + fn parse(s: &str) -> char { + s.chars() + .next() + .unwrap_or_else(|| panic!("Parsing empty string")) + } +} + pub fn parse<T: Parsable>(s: &str) -> T { <T as Parsable>::parse(s) } +pub fn vc(s: &str) -> Vec<char> { + parse(s) +} + +pub fn vvc(s: &str) -> Vec<Vec<char>> { + parse(s) +} + +pub fn vi(s: &str) -> Vec<i32> { + parse(s) +} + +pub fn vvi(s: &str) -> Vec<Vec<i32>> { + parse(s) +} + pub fn arg(n: usize) -> String { env::args() .nth(n)