Skip to content

Commit

Permalink
Add problem 2086: Minimum Number of Food Buckets to Feed the Hamsters
Browse files Browse the repository at this point in the history
  • Loading branch information
EFanZh committed Jun 21, 2024
1 parent dc38684 commit e58f05f
Show file tree
Hide file tree
Showing 5 changed files with 273 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1512,6 +1512,7 @@ pub mod problem_2074_reverse_nodes_in_even_length_groups;
pub mod problem_2075_decode_the_slanted_ciphertext;
pub mod problem_2078_two_furthest_houses_with_different_colors;
pub mod problem_2085_count_common_words_with_one_occurrence;
pub mod problem_2086_minimum_number_of_food_buckets_to_feed_the_hamsters;
pub mod problem_2089_find_target_indices_after_sorting_array;
pub mod problem_2090_k_radius_subarray_averages;
pub mod problem_2091_removing_minimum_and_maximum_from_array;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
pub mod state_machine;
pub mod state_machine_2;
pub mod state_machine_3;

pub trait Solution {
fn minimum_buckets(hamsters: String) -> i32;
}

#[cfg(test)]
mod tests {
use super::Solution;

pub fn run<S: Solution>() {
let test_cases = [
("H..H", 2),
(".H.H.", 1),
(".HHH.", -1),
("..", 0),
("H", -1),
(".HH.H", 2),
("...HH...H.", 3),
];

for (hamsters, expected) in test_cases {
assert_eq!(S::minimum_buckets(hamsters.to_string()), expected);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
pub struct Solution;

// ------------------------------------------------------ snip ------------------------------------------------------ //

enum State {
Start,
Empty,
Hamster,
EmptyHamster,
Food,
}

impl Solution {
pub fn minimum_buckets(hamsters: String) -> i32 {
let mut result = 0;
let mut state = State::Start;

for c in hamsters.into_bytes() {
let is_empty = c == b'.';

state = match state {
State::Start => {
if is_empty {
State::Empty
} else {
State::Hamster
}
}
State::Empty => {
if is_empty {
State::Empty
} else {
State::EmptyHamster
}
}
State::Hamster => {
if is_empty {
result += 1;

State::Food
} else {
return -1;
}
}
State::EmptyHamster => {
result += 1;

if is_empty {
State::Food
} else {
State::Hamster
}
}
State::Food => {
if is_empty {
State::Empty
} else {
State::Start
}
}
};
}

result += match state {
State::Start | State::Empty | State::Food => 0,
State::Hamster => return -1,
State::EmptyHamster => 1,
};

result
}
}

// ------------------------------------------------------ snip ------------------------------------------------------ //

impl super::Solution for Solution {
fn minimum_buckets(hamsters: String) -> i32 {
Self::minimum_buckets(hamsters)
}
}

#[cfg(test)]
mod tests {
#[test]
fn test_solution() {
super::super::tests::run::<super::Solution>();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
pub struct Solution;

// ------------------------------------------------------ snip ------------------------------------------------------ //

use std::str::Bytes;

struct Context<'a> {
iter: Bytes<'a>,
result: i32,
}

impl Context<'_> {
#[inline(never)]
fn start(&mut self) {
match self.iter.next() {
None => {}
Some(b'.') => self.empty(),
Some(_) => self.hamster(),
}
}

fn empty(&mut self) {
match self.iter.next() {
None => {}
Some(b'.') => self.empty(),
Some(_) => self.empty_hamster(),
}
}

fn hamster(&mut self) {
match self.iter.next() {
Some(b'.') => {
self.result += 1;

self.food();
}
_ => self.result = -1,
}
}

fn empty_hamster(&mut self) {
self.result += 1;

match self.iter.next() {
None => {}
Some(b'.') => self.food(),
Some(_) => self.hamster(),
}
}

fn food(&mut self) {
match self.iter.next() {
None => {}
Some(b'.') => self.empty(),
Some(_) => self.start(),
}
}
}

impl Solution {
pub fn minimum_buckets(hamsters: String) -> i32 {
let mut context = Context {
iter: hamsters.bytes(),
result: 0,
};

context.start();

context.result
}
}

// ------------------------------------------------------ snip ------------------------------------------------------ //

impl super::Solution for Solution {
fn minimum_buckets(hamsters: String) -> i32 {
Self::minimum_buckets(hamsters)
}
}

#[cfg(test)]
mod tests {
#[test]
fn test_solution() {
super::super::tests::run::<super::Solution>();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
pub struct Solution;

// ------------------------------------------------------ snip ------------------------------------------------------ //

use std::str::Bytes;

impl Solution {
#[inline(never)]
fn start(mut iter: Bytes, result: i32) -> i32 {
match iter.next() {
None => result,
Some(b'.') => Self::empty(iter, result),
Some(_) => Self::hamster(iter, result),
}
}

fn empty(mut iter: Bytes, result: i32) -> i32 {
match iter.next() {
None => result,
Some(b'.') => Self::empty(iter, result),
Some(_) => Self::empty_hamster(iter, result),
}
}

fn hamster(mut iter: Bytes, result: i32) -> i32 {
match iter.next() {
Some(b'.') => Self::food(iter, result + 1),
_ => -1,
}
}

fn empty_hamster(mut iter: Bytes, mut result: i32) -> i32 {
result += 1;

match iter.next() {
None => result,
Some(b'.') => Self::food(iter, result),
Some(_) => Self::hamster(iter, result),
}
}

fn food(mut iter: Bytes, result: i32) -> i32 {
match iter.next() {
None => result,
Some(b'.') => Self::empty(iter, result),
Some(_) => Self::start(iter, result),
}
}

pub fn minimum_buckets(hamsters: String) -> i32 {
Self::start(hamsters.bytes(), 0)
}
}

// ------------------------------------------------------ snip ------------------------------------------------------ //

impl super::Solution for Solution {
fn minimum_buckets(hamsters: String) -> i32 {
Self::minimum_buckets(hamsters)
}
}

#[cfg(test)]
mod tests {
#[test]
fn test_solution() {
super::super::tests::run::<super::Solution>();
}
}

0 comments on commit e58f05f

Please sign in to comment.