Skip to content

Commit 94c5e8f

Browse files
committed
Add problem 2381: Shifting Letters II
1 parent fc2b15d commit 94c5e8f

File tree

3 files changed

+105
-0
lines changed

3 files changed

+105
-0
lines changed

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1770,6 +1770,7 @@ pub mod problem_2373_largest_local_values_in_a_matrix;
17701770
pub mod problem_2374_node_with_highest_edge_score;
17711771
pub mod problem_2379_minimum_recolors_to_get_k_consecutive_black_blocks;
17721772
pub mod problem_2380_time_needed_to_rearrange_a_binary_string;
1773+
pub mod problem_2381_shifting_letters_ii;
17731774

17741775
#[cfg(test)]
17751776
mod test_utilities;
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
pub mod sweep_line;
2+
3+
pub trait Solution {
4+
fn shifting_letters(s: String, shifts: Vec<Vec<i32>>) -> String;
5+
}
6+
7+
#[cfg(test)]
8+
mod tests {
9+
use super::Solution;
10+
11+
pub fn run<S: Solution>() {
12+
let test_cases = [
13+
(("abc", &[[0, 1, 0], [1, 2, 1], [0, 2, 1]] as &[_]), "ace"),
14+
(("dztz", &[[0, 0, 0], [1, 1, 1]]), "catz"),
15+
];
16+
17+
for ((s, shifts), expected) in test_cases {
18+
assert_eq!(
19+
S::shifting_letters(s.to_string(), shifts.iter().map(Vec::from).collect()),
20+
expected,
21+
);
22+
}
23+
}
24+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
pub struct Solution;
2+
3+
// ------------------------------------------------------ snip ------------------------------------------------------ //
4+
5+
impl Solution {
6+
fn assign_add(target: &mut u8, value: u8) {
7+
*target += value;
8+
9+
if *target >= 26 {
10+
*target -= 26;
11+
}
12+
}
13+
14+
fn assign_sub(target: &mut u8, value: u8) {
15+
if *target < value {
16+
*target += 26;
17+
}
18+
19+
*target -= value;
20+
}
21+
22+
fn helper(slice: &mut [u8], shifts: &[Vec<i32>]) {
23+
let mut prev = b'a';
24+
25+
for offset in &mut *slice {
26+
let current = *offset;
27+
28+
Self::assign_sub(offset, prev);
29+
30+
prev = current;
31+
}
32+
33+
for shift in shifts {
34+
let [start, end, direction]: [_; 3] = shift.as_slice().try_into().ok().unwrap();
35+
let diff = if direction == 0 { 25 } else { 1 };
36+
37+
Self::assign_add(&mut slice[start as u32 as usize], diff);
38+
39+
if let Some(end) = slice.get_mut(end as u32 as usize + 1) {
40+
Self::assign_sub(end, diff);
41+
}
42+
}
43+
44+
let mut prev = b'a';
45+
46+
for target in slice {
47+
prev += *target;
48+
49+
if prev > b'z' {
50+
prev -= 26;
51+
}
52+
53+
*target = prev;
54+
}
55+
}
56+
57+
pub fn shifting_letters(s: String, shifts: Vec<Vec<i32>>) -> String {
58+
let mut buffer = s.into_bytes();
59+
60+
Self::helper(&mut buffer, &shifts);
61+
62+
String::from_utf8(buffer).unwrap()
63+
}
64+
}
65+
66+
// ------------------------------------------------------ snip ------------------------------------------------------ //
67+
68+
impl super::Solution for Solution {
69+
fn shifting_letters(s: String, shifts: Vec<Vec<i32>>) -> String {
70+
Self::shifting_letters(s, shifts)
71+
}
72+
}
73+
74+
#[cfg(test)]
75+
mod tests {
76+
#[test]
77+
fn test_solution() {
78+
super::super::tests::run::<super::Solution>();
79+
}
80+
}

0 commit comments

Comments
 (0)