impl Solution { fn can_stamp(stamp: &Vec, tape: &Vec, i: usize) -> bool { !Solution::is_fully_stamped_section(stamp.len(), &tape, i) && (0..stamp.len()) .map(|j| (stamp[j], tape[i + j])) .all(|(s, t)| s == t || t == '?') } fn is_fully_stamped_section(length: usize, tape: &Vec, i: usize) -> bool { (i..i + length).all(|j| tape[j] == '?') } fn stamp_tape(length: usize, tape: &mut Vec, i: usize) { (i..i + length).for_each(|j| { tape[j] = '?'; }) } pub fn moves_to_stamp(stamp: String, target: String) -> Vec { // convert stamp to usable interpretation let stamp: Vec = stamp.chars().collect(); // convert target to a mutable array of characters let mut tape: Vec = target.chars().collect(); // keep track of stamped indices let mut stamped: Vec = Vec::new(); // go over and try to stamp while possible let mut has_changed = true; while has_changed && stamped.len() <= 10 * tape.len() { has_changed = false; (0..tape.len() + 1 - stamp.len()).for_each(|i| { if Solution::can_stamp(&stamp, &tape, i) { Solution::stamp_tape(stamp.len(), &mut tape, i); stamped.push(i as i32); has_changed = true; } }); } if stamped.len() > 10 * tape.len() || !Solution::is_fully_stamped_section(tape.len(), &tape, 0) { stamped.clear(); } stamped.reverse(); stamped } } struct Solution {} fn main() { println!("Hello World!"); } #[cfg(test)] mod tests { use super::*; #[test] fn test_example() { assert_eq!( Solution::moves_to_stamp("abc".to_string(), "ababc".to_string()), vec![0, 2] ); } #[test] fn test_another_example() { assert_eq!( Solution::moves_to_stamp("abca".to_string(), "aabcaca".to_string()), vec![0, 3, 1] ); } #[test] fn test_unusable_stamp() { assert_eq!( Solution::moves_to_stamp("stamp".to_string(), "tamps".to_string()), vec![] ); } }