問題文

弟は100以内の足し算と引き算をやりました。チャックしてあげてください。核問題の形式はa+b=c或いはa-b=c、どれも100を超えない非負整数です。cは弟が算出した回答で、200以内の比数整数であるか、一個の「?」かです。「?」は回答不能を意味します。

入力形式

入力は100行以内とし、EOF記号で終了します。一行ごとに、一問があります。形式は前述規定に則し、いかなるスペースを含みません。入力されたすべての整数に左に不要な0をつけていません。

出力形式

一行のみを出力します。一個の非負整数のみが出て、つまり、弟が正解した問題の数。

入力サンプル

1+2=3
3-1=5
6+7=?
99-0=99

回答案

use std::io;
use core::iter::Peekable;
use core::str::Chars;
pub struct Expression {
    a: i32,
    b: i32,
    op: char,
    answer: i32,
    unanswered: bool
}

fn main() {
    let mut line: String = String::new();
    let mut correct_count: i32 = 0;
    while io::stdin().read_line(&mut line).unwrap() > 0 {
        let mut char_seq: Peekable<Chars<'_>> = line.trim().chars().peekable();
        let a: i32   = read_number(&mut char_seq).unwrap().unwrap();
        let op: char = char_seq.next().unwrap();
        let b: i32   = read_number(&mut char_seq).unwrap().unwrap();
        assert!(char_seq.next().unwrap()=='=');
        let got_answer = read_number(&mut char_seq).unwrap();
        let expression = Expression {
            a: a,
            op: op,
            b: b,
            answer: got_answer.unwrap_or_default(),
            unanswered: got_answer.is_none()
        };
        match check_expression(&expression) {
            Ok(r) => correct_count += if r {1} else {0},
            Err(e) => println!("Error: {}", e)
        }
        line.clear();
    }
    println!("{}", correct_count);
}

fn read_number(text_iter: &mut Peekable<Chars<'_>>) -> Result<Option<i32>, &'static str> {
    let mut number_str: String = String::new();
    while let Some(&c) = text_iter.peek() {
        match c {
            c if c >= '0' && c <= '9' => {
                number_str.push(c);
                text_iter.next();
            },
            '?' => {
                number_str.push(c);
                text_iter.next();
                break;
            },
            _ => break
        }
    }
    if number_str == "?" {
        Ok(None)
    } else if number_str.len() > 0 {
        Ok(Some(number_str.parse().unwrap()))
    }
    else {
        Err("Reading a number while not at a number.")
    }
}

fn check_expression(expr: &Expression) -> Result<bool, &'static str> {
    let expected: i32;
    match expr.op {
        '+' => expected = expr.a + expr.b,
        '-' => expected = expr.a - expr.b,
        '*' => expected = expr.a * expr.b,
        '/' => expected = expr.a / expr.b,
        _ => return Err("Invalid operator.")
    }
    Ok(!expr.unanswered && expr.answer == expected)
}