summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLouis Burda <quent.burda@gmail.com>2024-11-12 21:45:53 +0100
committerLouis Burda <quent.burda@gmail.com>2024-11-12 21:45:53 +0100
commit3abce9917a39b3fe6e1cf093d15cf2e213de5aa1 (patch)
tree36a067a5f9597ab27e9890328a0dcb7a8c7ca084 /src
parent91a7f4626268d7507d0facc30abf8d5aa84f5dec (diff)
downloadleetcode-3abce9917a39b3fe6e1cf093d15cf2e213de5aa1.tar.gz
leetcode-3abce9917a39b3fe6e1cf093d15cf2e213de5aa1.zip
Cleanup input parsing and add problem 1671
Diffstat (limited to 'src')
-rw-r--r--src/bin/0001-two-sum.rs3
-rw-r--r--src/bin/0004-median-of-two-sorted-arrays.rs6
-rw-r--r--src/bin/0019-remove-nth-node-from-end-of-list.rs28
-rw-r--r--src/bin/0386-lexicographical-numbers.rs1
-rw-r--r--src/bin/1671-minimum-number-of-removals-to-make-mountain-array.rs86
-rw-r--r--src/bin/2070-most-beautiful-item-for-each-query.rs45
-rw-r--r--src/bin/2491-divide-players-into-teams-of-equal-skill.rs6
-rw-r--r--src/bin/2601-prime-subtraction-operation.rs5
-rw-r--r--src/lib.rs35
9 files changed, 173 insertions, 42 deletions
diff --git a/src/bin/0001-two-sum.rs b/src/bin/0001-two-sum.rs
index f0244a3..a62b2a9 100644
--- a/src/bin/0001-two-sum.rs
+++ b/src/bin/0001-two-sum.rs
@@ -33,7 +33,6 @@
///
/// Follow-up: Can you come up with an algorithm that is less than O(n2) time
/// complexity?
-
use leetcode::*;
struct Solution {}
@@ -63,7 +62,7 @@ impl Solution {
pub fn main() {
println!(
"{:?}",
- Solution::two_sum(parse_vec(arg(1)), arg(2).parse().unwrap())
+ Solution::two_sum(arg_into(1), arg_into(2))
)
}
diff --git a/src/bin/0004-median-of-two-sorted-arrays.rs b/src/bin/0004-median-of-two-sorted-arrays.rs
index 332336d..91ec522 100644
--- a/src/bin/0004-median-of-two-sorted-arrays.rs
+++ b/src/bin/0004-median-of-two-sorted-arrays.rs
@@ -29,7 +29,7 @@
/// -106 <= nums1[i], nums2[i] <= 106
///
-use leetcode::{arg, parse_vec};
+use leetcode::arg_into;
struct Solution {}
@@ -109,9 +109,7 @@ impl Solution {
}
pub fn main() {
- let nums1 = parse_vec(arg(1));
- let nums2 = parse_vec(arg(2));
- println!("{:?}", Solution::find_median_sorted_arrays(nums1, nums2));
+ println!("{:?}", Solution::find_median_sorted_arrays(arg_into(1), arg_into(2)));
}
#[cfg(test)]
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
index 18f54ce..dfbf7ab 100644
--- a/src/bin/0019-remove-nth-node-from-end-of-list.rs
+++ b/src/bin/0019-remove-nth-node-from-end-of-list.rs
@@ -27,22 +27,18 @@
///
/// *Follow up:* Could you do this in one pass?
///
-
use leetcode::*;
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct ListNode {
pub val: i32,
- pub next: Option<Box<ListNode>>
+ pub next: Option<Box<ListNode>>,
}
impl ListNode {
#[inline]
fn new(val: i32) -> Self {
- ListNode {
- next: None,
- val
- }
+ ListNode { next: None, val }
}
}
@@ -85,7 +81,10 @@ fn build_list(vec: Vec<i32>) -> Option<Box<ListNode>> {
}
pub fn main() {
- println!("{:?}", Solution::remove_nth_from_end(build_list(parse_vec(arg(1))), arg(2).parse().unwrap()))
+ println!(
+ "{:?}",
+ Solution::remove_nth_from_end(build_list(arg_into(1)), arg_into(2))
+ )
}
#[cfg(test)]
@@ -94,8 +93,17 @@ mod tests {
#[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]));
+ 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])
+ );
}
}
diff --git a/src/bin/0386-lexicographical-numbers.rs b/src/bin/0386-lexicographical-numbers.rs
index 04b6e6c..1ee75e8 100644
--- a/src/bin/0386-lexicographical-numbers.rs
+++ b/src/bin/0386-lexicographical-numbers.rs
@@ -20,7 +20,6 @@
///
/// * 1 <= n <= 5 * 104
///
-
use leetcode::arg;
struct Solution {}
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
new file mode 100644
index 0000000..46f75cc
--- /dev/null
+++ b/src/bin/1671-minimum-number-of-removals-to-make-mountain-array.rs
@@ -0,0 +1,86 @@
+/// 1671. Minimum Number of Removals to Make Mountain Array (Hard)
+///
+/// You may recall that an array arr is a *mountain array* if and only if:
+///
+/// * arr.length >= 3
+/// * There exists some index i (*0-indexed*) with 0 < i < arr.length - 1 such
+/// that:
+/// + arr[0] < arr[1] < ... < arr[i - 1] < arr[i]
+/// + arr[i] > arr[i + 1] > ... > arr[arr.length - 1]
+///
+/// Given an integer array nums​​​, return the *minimum* number of elements to
+/// remove to make nums​​​ a *mountain array*.
+///
+/// *Example 1:*
+///
+/// *Input:* nums = [1,3,1]
+/// *Output:* 0
+/// *Explanation:* The array itself is a mountain array so we do not need to
+/// remove any elements.
+///
+/// *Example 2:*
+///
+/// *Input:* nums = [2,1,1,5,6,2,3,1]
+/// *Output:* 3
+/// *Explanation:* One solution is to remove the elements at indices 0, 1, and
+/// 5, making the array nums = [1,5,6,3,1].
+///
+/// *Constraints:*
+///
+/// * 3 <= nums.length <= 1000
+/// * 1 <= nums[i] <= 109
+/// * It is guaranteed that you can make a mountain array out of nums.
+///
+use leetcode::*;
+use std::cmp::max;
+
+struct Solution {}
+
+impl Solution {
+ pub fn minimum_mountain_removals(nums: Vec<i32>) -> i32 {
+ assert!(nums.len() >= 3);
+ let mut left = vec![1; nums.len()];
+ for i in 0..nums.len() {
+ for k in 0..i {
+ if nums[i] > nums[k] {
+ left[i] = max(left[i], left[k] + 1);
+ }
+ }
+ }
+ let mut right = vec![1; nums.len()];
+ for i in (0..nums.len()).rev() {
+ for k in (i + 1..nums.len()).rev() {
+ if nums[i] > nums[k] {
+ right[i] = max(right[i], right[k] + 1);
+ }
+ }
+ }
+ left.iter()
+ .enumerate()
+ .filter(|(i, v)| **v != 1 && right[*i] != 1)
+ .map(|(i, v)| nums.len() as i32 - v - right[i] + 1)
+ .min()
+ .unwrap()
+ }
+}
+
+pub fn main() {
+ println!(
+ "{:?}",
+ Solution::minimum_mountain_removals(arg_into(1))
+ )
+}
+
+#[cfg(test)]
+mod tests {
+ use crate::Solution;
+
+ #[test]
+ fn test() {
+ assert_eq!(Solution::minimum_mountain_removals(vec![1, 3, 1]), 0);
+ assert_eq!(
+ Solution::minimum_mountain_removals(vec![2, 1, 1, 5, 6, 2, 3, 1]),
+ 3
+ );
+ }
+}
diff --git a/src/bin/2070-most-beautiful-item-for-each-query.rs b/src/bin/2070-most-beautiful-item-for-each-query.rs
index cb6fe99..ee6fd93 100644
--- a/src/bin/2070-most-beautiful-item-for-each-query.rs
+++ b/src/bin/2070-most-beautiful-item-for-each-query.rs
@@ -1,3 +1,4 @@
+use leetcode::*;
/// 2070. Most Beautiful Item for Each Query (Medium)
///
/// You are given a 2D integer array items where items[i] = [pricei, beautyi]
@@ -49,23 +50,23 @@
/// * items[i].length == 2
/// * 1 <= pricei, beautyi, queries[j] <= 109
///
-
use std::cmp;
-use leetcode::*;
struct Solution {}
impl Solution {
pub fn maximum_beauty(mut items: Vec<Vec<i32>>, queries: Vec<i32>) -> Vec<i32> {
let mut queries = queries.into_iter().enumerate().collect::<Vec<_>>();
- items.sort_by(|a,b| a[0].cmp(&b[0]));
- queries.sort_by(|(_ia,a),(_ib,b)| a.cmp(b));
+ items.sort_by(|a, b| a[0].cmp(&b[0]));
+ queries.sort_by(|(_ia, a), (_ib, b)| a.cmp(b));
let mut answers = vec![0i32; queries.len()];
let mut iter = items.iter().peekable();
let mut best = 0i32;
- for (i,q) in queries {
+ for (i, q) in queries {
while let Some(item) = iter.peek() {
- if item[0] > q { break; }
+ if item[0] > q {
+ break;
+ }
best = cmp::max(best, item[1]);
iter.next();
}
@@ -76,7 +77,16 @@ impl Solution {
}
pub fn main() {
- println!("{:?}", Solution::maximum_beauty(arg(1).split("|").map(|s| parse_vec(s.to_string())).collect(), parse_vec(arg(2))))
+ println!(
+ "{:?}",
+ Solution::maximum_beauty(
+ arg(1)
+ .split("|")
+ .map(parse)
+ .collect(),
+ arg_into(2)
+ )
+ )
}
#[cfg(test)]
@@ -85,8 +95,23 @@ mod tests {
#[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]);
- assert_eq!(Solution::maximum_beauty(vec![vec![1,2],vec![1,2],vec![1,3],vec![1,4]], vec![1]), vec![4]);
- assert_eq!(Solution::maximum_beauty(vec![vec![10,1000]], vec![5]), vec![0]);
+ 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]
+ );
+ assert_eq!(
+ Solution::maximum_beauty(
+ vec![vec![1, 2], vec![1, 2], vec![1, 3], vec![1, 4]],
+ vec![1]
+ ),
+ vec![4]
+ );
+ assert_eq!(
+ Solution::maximum_beauty(vec![vec![10, 1000]], vec![5]),
+ vec![0]
+ );
}
}
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
index 5f70681..9b6b57c 100644
--- a/src/bin/2491-divide-players-into-teams-of-equal-skill.rs
+++ b/src/bin/2491-divide-players-into-teams-of-equal-skill.rs
@@ -44,8 +44,7 @@
/// 2 <= skill.length <= 105
/// skill.length is even.
/// 1 <= skill[i] <= 1000
-
-use leetcode::{arg, parse_vec};
+use leetcode::arg_into;
struct Solution {}
@@ -72,8 +71,7 @@ impl Solution {
}
fn main() {
- let input = parse_vec(arg(1));
- println!("{}", Solution::divide_players(input));
+ println!("{}", Solution::divide_players(arg_into(1)));
}
#[cfg(test)]
diff --git a/src/bin/2601-prime-subtraction-operation.rs b/src/bin/2601-prime-subtraction-operation.rs
index 9fdc10f..e76a282 100644
--- a/src/bin/2601-prime-subtraction-operation.rs
+++ b/src/bin/2601-prime-subtraction-operation.rs
@@ -44,8 +44,7 @@
/// * 1 <= nums[i] <= 1000
/// * nums.length == n
///
-
-use leetcode::{arg, parse_vec};
+use leetcode::arg_into;
use std::cmp;
struct Solution {}
@@ -86,7 +85,7 @@ impl Solution {
}
fn main() {
- println!("{:?}", Solution::prime_sub_operation(parse_vec(arg(1))));
+ println!("{:?}", Solution::prime_sub_operation(arg_into(1)));
}
#[cfg(test)]
diff --git a/src/lib.rs b/src/lib.rs
index 4a04b3a..613b041 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,15 +1,30 @@
-use std::{env, fmt::Debug, str::FromStr};
+use std::{env, fmt::Debug, str::{self, FromStr}};
-pub fn parse_vec<T: FromStr>(arg: String) -> Vec<T>
-where
- <T as FromStr>::Err: Debug,
-{
- arg.split_whitespace()
+pub trait Parsable {
+ fn parse(s: &str) -> Self;
+}
+
+impl<T: str::FromStr> Parsable for Vec<T>
+where
+ <T as str::FromStr>::Err: Debug {
+ fn parse(s: &str) -> Vec<T> {
+ s.split(",")
.map(|w| {
- w.parse()
- .unwrap_or_else(|_| panic!("Failed to parse element in arugment ({arg})"))
+ w.trim().parse()
+ .unwrap_or_else(|_| panic!("Failed to parse element in argument ({s})"))
})
.collect()
+ }
+}
+
+impl Parsable for i32 {
+ fn parse(s: &str) -> i32 {
+ i32::from_str(s).unwrap_or_else(|_| panic!("Failed to parse integer ({s})"))
+ }
+}
+
+pub fn parse<T: Parsable>(s: &str) -> T {
+ <T as Parsable>::parse(s)
}
pub fn arg(n: usize) -> String {
@@ -17,3 +32,7 @@ pub fn arg(n: usize) -> String {
.nth(n)
.unwrap_or_else(|| panic!("Failed to get argument ({n})"))
}
+
+pub fn arg_into<T: Parsable>(n: usize) -> T {
+ <T as Parsable>::parse(arg(n).as_str())
+}