impl Solution {
    fn can_stamp(stamp: &Vec<char>, tape: &Vec<char>, 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<char>, i: usize) -> bool {
        (i..i + length).all(|j| tape[j] == '?')
    }

    fn stamp_tape(length: usize, tape: &mut Vec<char>, i: usize) {
        (i..i + length).for_each(|j| {
            tape[j] = '?';
        })
    }

    pub fn moves_to_stamp(stamp: String, target: String) -> Vec<i32> {
        // convert stamp to usable interpretation
        let stamp: Vec<char> = stamp.chars().collect();

        // convert target to a mutable array of characters
        let mut tape: Vec<char> = target.chars().collect();

        // keep track of stamped indices
        let mut stamped: Vec<i32> = 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![]
        );
    }
}