AtCoder Beginner Contest 261 B

https://atcoder.jp/contests/abc261/tasks/abc261_b

ABCのB問題を解いていきます。

非対角部分の座標を列挙するIteratorを書けばきれいになりますが、なかなか大変ですね。Pythonなら簡単ですが。

// Tournament Result
#![allow(non_snake_case)]

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()
}

struct Table {
    A: Vec::<Vec::<char>>
}

struct NonDiagonals {
    i: usize,
    j: usize,
    N: usize,
}

impl NonDiagonals {
    fn create(N: usize) -> NonDiagonals {
        NonDiagonals { i: 1, j: 0, N }
    }
}

impl Iterator for NonDiagonals {
    type Item = (usize,usize);
    
    fn next(& mut self) -> Option<(usize,usize)> {
        let i = self.i;
        let j = self.j;
        if i == self.N {
            None
        }
        else if i == j + 1 {
            self.i = i + 1;
            self.j = 0;
            Some((i, j))
        }
        else {
            self.j = j + 1;
            Some((i, j))
        }
    }
}

impl Table {
    fn is_correct(&self) -> bool {
        self.is_correct_diagonal() && self.is_correct_non_diagonal()
    }
    
    fn is_correct_diagonal(&self) -> bool {
        let N = self.A.len();
        (0..N).all(|i| self.A[i][i] == '-')
    }
    
    fn is_valid(&self, i: usize, j: usize) -> bool {
        match self.A[i][j] {
            'W' => self.A[j][i] == 'L',
            'L' => self.A[j][i] == 'W',
            _   => self.A[j][i] == 'D',
        }
    }
    
    fn is_correct_non_diagonal(&self) -> bool {
        NonDiagonals::create(self.A.len()).all(|(i, j)| self.is_valid(i, j))
    }
    
    fn read() -> Table {
        let mut A = Vec::<Vec::<char>>::new();
        let N: i32 = read();
        for _ in 0..N {
            let s: String = read();
            A.push(s.chars().collect())
        }
        Table { A }
    }
}

fn main() {
    let table = Table::read();
    println!("{}", if table.is_correct() { "correct" } else { "incorrect" });
}