AtCoder Beginner Contest 250 A

https://atcoder.jp/contests/abc250/tasks/abc250_a

座標の問題なので、Pointという構造体を作ります。

struct Point {
    x: i32,
    y: i32,
}

要素をカンマ区切りで並べるだけです。
メソッドは次のように書きます。

impl Point {
    fn add(&self, other: &Point) -> Point {
        Point { x: self.x + other.x, y: self.y + other.y }
    }
}

引数に&selfが要るんですね。オブジェクトを作るのはこんな感じです。

    let pt = Point { x: w[0], y: w[1] };

Python

dirs = [Point(1, 0), Point(0, 1), ...]

と書く代わりに、Rustではこう書きます。

    let dirs = vec![Point {x: 1, y: 0}, Point {x: 0, y: 1}, ...]

隣を列挙して範囲内にフィルタリングしてカウントします。Python

sum(1 for _ in filter(lambda dir: b.is_inner(pt.add(dir)), dirs))

と書くとすると(ふつうはfilterではなくifを使うと思いますが)、Rustなら

    dirs.iter().filter(|&dir| b.is_inner(&pt.add(&dir))).count()

Vecはiteratorではないので、iterメソッドでiteratorにするんですね。

#![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()
}

fn read_vec<T: std::str::FromStr>() -> Vec<T> {
    read::<String>().split_whitespace()
            .map(|e| e.parse().ok().unwrap()).collect()
}

struct Point {
    x: i32,
    y: i32,
}

impl Point {
    fn add(&self, other: &Point) -> Point {
        Point { x: self.x + other.x, y: self.y + other.y }
    }
}

struct Box {
    H: i32,
    W: i32,
}

impl Box {
    fn is_inner(&self, pt: &Point) -> bool {
        1 <= pt.x && pt.x <= self.H && 1 <= pt.y && pt.y <= self.W
    }
}

fn num_neighbors(pt: &Point, b: &Box) -> usize {
    let dirs = vec![Point {x: 1, y: 0}, Point {x: 0, y: 1},
                    Point {x: -1, y: 0}, Point {x: 0, y: -1}];
    dirs.iter().filter(|&dir| b.is_inner(&pt.add(&dir))).count()
}

fn main() {
    let v = read_vec::<i32>();
    let b = Box { H: v[0], W: v[1] };
    let w = read_vec::<i32>();
    let pt = Point { x: w[0], y: w[1] };
    println!("{}", num_neighbors(&pt, &b));
}