AtCoder Beginner Contest 328 D

https://atcoder.jp/contests/abc328/tasks/abc328_d

双方向リストを作って、ABCが現れたら削除します。

// Many Good Tuple Problems
#![allow(non_snake_case)]


//////////////////// library ////////////////////

fn read<T: std::str::FromStr>() -> T {
    let mut line = String::new();
    std::io::stdin().read_line(&mut line).ok();
    line.trim().parse().ok().unwrap()
}


//////////////////// List ////////////////////

struct List {
    cs: Vec<char>,
    prev: Vec<Option<usize>>,
    next: Vec<Option<usize>>
}

impl List {
    fn remove(&mut self, i: usize) -> Option<usize> {
        self.cs[i] = '.';
        if let Some(j) = self.prev[i] {
            self.next[j] = self.next[i]
        }
        if let Some(k) = self.next[i] {
            self.prev[k] = self.prev[i]
        }
        let ret = self.prev[i];
        self.prev[i] = None;
        self.next[i] = None;
        ret
    }
    
    fn string(&mut self) -> String {
        self.cs.iter().filter(|&&c| c != '.').map(|&c| c).collect::<String>()
    }
    
    fn new(cs: Vec<char>) -> List {
        let L = cs.len();
        let prev: Vec<Option<usize>> =
                (0..L).map(|i| if i == 0 { None } else { Some(i-1) }).collect();
        let next: Vec<Option<usize>> =
                (1..L+1).map(|i| if i == L { None } else { Some(i) }).collect();
        List { cs, prev, next }
    }
}


//////////////////// process ////////////////////

fn previous(index: Option<usize>, list: &List) -> Option<usize> {
    match index {
        Some(i) => list.prev[i],
        None    => None
    }
}

fn pos_char(index: Option<usize>, list: &List) -> char {
    match index {
        Some(i) => list.cs[i],
        None    => '.'
    }
}

fn F(S: String) -> String {
    let cs: Vec<char> = S.chars().collect();
    let L = cs.len();
    let mut list = List::new(cs);
    let mut state = 0;
    for i in 0..L {
        if state == 0 {
            if list.cs[i] == 'A' {
                state = 1;
            }
        }
        else if state == 1 {
            if list.cs[i] == 'B' {
                state = 2
            }
            else if list.cs[i] == 'C' {
                state = 0
            }
        }
        else {
            if list.cs[i] == 'A' {
                state = 1;
                continue
            }
            if list.cs[i] == 'B' {
                state = 0;
                continue
            }
            
            let j1 = list.remove(i).unwrap();
            let j2 = list.remove(j1).unwrap();
            let op_j3 = list.remove(j2);
            let op_j4 = previous(op_j3, &list);
            let c3 = pos_char(op_j3, &list);
            let c4 = pos_char(op_j4, &list);
            if c3 == 'A' {
                state = 1
            }
            else if c3 == 'B' && c4 == 'A' {
                state = 2
            }
            else {
                state = 0
            }
        }
    }
    list.string()
}

fn main() {
    let S: String = read();
    println!("{}", F(S))
}