From 6d9f5a16bf6aa8e700b3b518852b50da92db5029 Mon Sep 17 00:00:00 2001 From: EFanZh Date: Thu, 2 May 2024 15:54:01 +0800 Subject: [PATCH] Add problem 1849: Splitting a String Into Descending Consecutive Values --- src/lib.rs | 1 + .../backtracking.rs | 86 +++++++++++++++++++ .../mod.rs | 26 ++++++ 3 files changed, 113 insertions(+) create mode 100644 src/problem_1849_splitting_a_string_into_descending_consecutive_values/backtracking.rs create mode 100644 src/problem_1849_splitting_a_string_into_descending_consecutive_values/mod.rs diff --git a/src/lib.rs b/src/lib.rs index c818c32a..725d24e5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1377,6 +1377,7 @@ pub mod problem_1844_replace_all_digits_with_characters; pub mod problem_1845_seat_reservation_manager; pub mod problem_1846_maximum_element_after_decreasing_and_rearranging; pub mod problem_1848_minimum_distance_to_the_target_element; +pub mod problem_1849_splitting_a_string_into_descending_consecutive_values; pub mod problem_1851_minimum_interval_to_include_each_query; pub mod problem_1854_maximum_population_year; pub mod problem_1855_maximum_distance_between_a_pair_of_values; diff --git a/src/problem_1849_splitting_a_string_into_descending_consecutive_values/backtracking.rs b/src/problem_1849_splitting_a_string_into_descending_consecutive_values/backtracking.rs new file mode 100644 index 00000000..ffc95c03 --- /dev/null +++ b/src/problem_1849_splitting_a_string_into_descending_consecutive_values/backtracking.rs @@ -0,0 +1,86 @@ +pub struct Solution; + +// ------------------------------------------------------ snip ------------------------------------------------------ // + +use std::cmp::Ordering; +use std::str::Bytes; + +impl Solution { + fn check(mut first: u8, mut iter: Bytes, mut expected: u64) -> bool { + while expected != 0 { + let mut value = u64::from(first - b'0'); + + loop { + match value.cmp(&expected) { + Ordering::Less => { + if let Some(next) = iter.next() { + value = value * 10 + u64::from(next - b'0'); + } else { + return false; + } + } + Ordering::Equal => { + if let Some(next) = iter.next() { + first = next; + expected -= 1; + + break; + } + + return true; + } + Ordering::Greater => return false, + } + } + } + + first == b'0' && iter.all(|c| c == b'0') + } + + pub fn split_string(s: String) -> bool { + let mut iter = s.bytes(); + + let mut value = loop { + if let Some(c) = iter.next() { + if c != b'0' { + break u64::from(c - b'0'); + } + } else { + return false; + } + }; + + while let Some(c) = iter.next() { + if Self::check(c, iter.clone(), value - 1) { + return true; + } + + if let Some(next_value) = value + .checked_mul(10) + .and_then(|value| value.checked_add(u64::from(c - b'0'))) + { + value = next_value; + } else { + break; + } + } + + false + } +} + +// ------------------------------------------------------ snip ------------------------------------------------------ // + +impl super::Solution for Solution { + fn split_string(s: String) -> bool { + Self::split_string(s) + } +} + +#[cfg(test)] +mod tests { + #[test] + fn test_solution() { + super::super::tests::run::(); + } +} diff --git a/src/problem_1849_splitting_a_string_into_descending_consecutive_values/mod.rs b/src/problem_1849_splitting_a_string_into_descending_consecutive_values/mod.rs new file mode 100644 index 00000000..4a8d40db --- /dev/null +++ b/src/problem_1849_splitting_a_string_into_descending_consecutive_values/mod.rs @@ -0,0 +1,26 @@ +pub mod backtracking; + +pub trait Solution { + fn split_string(s: String) -> bool; +} + +#[cfg(test)] +mod tests { + use super::Solution; + + pub fn run() { + let test_cases = [ + ("1234", false), + ("050043", true), + ("9080701", false), + ("99999999999999999998", true), + ("00000", false), + ("64424509442147483647", false), + ("10009998", true), + ]; + + for (s, expected) in test_cases { + assert_eq!(S::split_string(s.to_string()), expected); + } + } +}