diff --git a/src/lib.rs b/src/lib.rs index bc1f4612..132fc4af 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1414,6 +1414,7 @@ pub mod problem_1889_minimum_space_wasted_from_packaging; pub mod problem_1893_check_if_all_the_integers_in_a_range_are_covered; pub mod problem_1894_find_the_student_that_will_replace_the_chalk; pub mod problem_1895_largest_magic_square; +pub mod problem_1896_minimum_cost_to_change_the_final_value_of_expression; pub mod problem_1897_redistribute_characters_to_make_all_strings_equal; pub mod problem_1898_maximum_number_of_removable_characters; pub mod problem_1899_merge_triplets_to_form_target_triplet; diff --git a/src/problem_1896_minimum_cost_to_change_the_final_value_of_expression/mod.rs b/src/problem_1896_minimum_cost_to_change_the_final_value_of_expression/mod.rs new file mode 100644 index 00000000..e2e0b6c6 --- /dev/null +++ b/src/problem_1896_minimum_cost_to_change_the_final_value_of_expression/mod.rs @@ -0,0 +1,18 @@ +pub mod recursive; + +pub trait Solution { + fn min_operations_to_flip(expression: String) -> i32; +} + +#[cfg(test)] +mod tests { + use super::Solution; + + pub fn run() { + let test_cases = [("1&(0|1)", 1), ("(0&0)&(0&0&0)", 3), ("(0|(1|0&1))", 1)]; + + for (expression, expected) in test_cases { + assert_eq!(S::min_operations_to_flip(expression.to_string()), expected); + } + } +} diff --git a/src/problem_1896_minimum_cost_to_change_the_final_value_of_expression/recursive.rs b/src/problem_1896_minimum_cost_to_change_the_final_value_of_expression/recursive.rs new file mode 100644 index 00000000..5db08723 --- /dev/null +++ b/src/problem_1896_minimum_cost_to_change_the_final_value_of_expression/recursive.rs @@ -0,0 +1,55 @@ +pub struct Solution; + +// ------------------------------------------------------ snip ------------------------------------------------------ // + +use std::str::Bytes; + +impl Solution { + fn parse_term(iter: &mut Bytes) -> (bool, u32) { + match iter.next().unwrap() { + b'(' => Self::parse_expression(iter), + c => (c != b'0', 1), + } + } + + fn parse_expression(iter: &mut Bytes) -> (bool, u32) { + let mut lhs = Self::parse_term(iter); + + while let Some(operator) = iter.next() { + if operator == b')' { + break; + } + + let rhs = Self::parse_term(iter); + let is_or = operator == b'|'; + + lhs = match (lhs.0 == is_or, rhs.0 == is_or) { + (false, false) => (!is_or, lhs.1.min(rhs.1)), + (true, false) | (false, true) => (is_or, 1), + (true, true) => (is_or, lhs.1.min(rhs.1) + 1), + }; + } + + lhs + } + + pub fn min_operations_to_flip(expression: String) -> i32 { + Self::parse_expression(&mut expression.bytes()).1 as _ + } +} + +// ------------------------------------------------------ snip ------------------------------------------------------ // + +impl super::Solution for Solution { + fn min_operations_to_flip(expression: String) -> i32 { + Self::min_operations_to_flip(expression) + } +} + +#[cfg(test)] +mod tests { + #[test] + fn test_solution() { + super::super::tests::run::(); + } +}