Skip to content

Commit

Permalink
Add problem 2381: Shifting Letters II
Browse files Browse the repository at this point in the history
  • Loading branch information
EFanZh committed Jan 1, 2025
1 parent fc2b15d commit 94c5e8f
Show file tree
Hide file tree
Showing 3 changed files with 105 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 @@ -1770,6 +1770,7 @@ pub mod problem_2373_largest_local_values_in_a_matrix;
pub mod problem_2374_node_with_highest_edge_score;
pub mod problem_2379_minimum_recolors_to_get_k_consecutive_black_blocks;
pub mod problem_2380_time_needed_to_rearrange_a_binary_string;
pub mod problem_2381_shifting_letters_ii;

#[cfg(test)]
mod test_utilities;
24 changes: 24 additions & 0 deletions src/problem_2381_shifting_letters_ii/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
pub mod sweep_line;

pub trait Solution {
fn shifting_letters(s: String, shifts: Vec<Vec<i32>>) -> String;
}

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

pub fn run<S: Solution>() {
let test_cases = [
(("abc", &[[0, 1, 0], [1, 2, 1], [0, 2, 1]] as &[_]), "ace"),
(("dztz", &[[0, 0, 0], [1, 1, 1]]), "catz"),
];

for ((s, shifts), expected) in test_cases {
assert_eq!(
S::shifting_letters(s.to_string(), shifts.iter().map(Vec::from).collect()),
expected,
);
}
}
}
80 changes: 80 additions & 0 deletions src/problem_2381_shifting_letters_ii/sweep_line.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
pub struct Solution;

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

impl Solution {
fn assign_add(target: &mut u8, value: u8) {
*target += value;

if *target >= 26 {
*target -= 26;
}
}

fn assign_sub(target: &mut u8, value: u8) {
if *target < value {
*target += 26;
}

*target -= value;
}

fn helper(slice: &mut [u8], shifts: &[Vec<i32>]) {
let mut prev = b'a';

for offset in &mut *slice {
let current = *offset;

Self::assign_sub(offset, prev);

prev = current;
}

for shift in shifts {
let [start, end, direction]: [_; 3] = shift.as_slice().try_into().ok().unwrap();
let diff = if direction == 0 { 25 } else { 1 };

Self::assign_add(&mut slice[start as u32 as usize], diff);

if let Some(end) = slice.get_mut(end as u32 as usize + 1) {
Self::assign_sub(end, diff);
}
}

let mut prev = b'a';

for target in slice {
prev += *target;

if prev > b'z' {
prev -= 26;
}

*target = prev;
}
}

pub fn shifting_letters(s: String, shifts: Vec<Vec<i32>>) -> String {
let mut buffer = s.into_bytes();

Self::helper(&mut buffer, &shifts);

String::from_utf8(buffer).unwrap()
}
}

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

impl super::Solution for Solution {
fn shifting_letters(s: String, shifts: Vec<Vec<i32>>) -> String {
Self::shifting_letters(s, shifts)
}
}

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

0 comments on commit 94c5e8f

Please sign in to comment.