Problem:
Problem D: Cheat Case

Problem

算数のテストを受けることになった俺達は、今から勉強しても赤点を取ってしまうことを確信し、カンニングで乗り切ることを決意した。

算数のテスト問題を作成するA先生はテスト用紙を手書きで作ることで知られている。彼がテスト問題を作成している時の筆跡情報を、近所の博士に作ってもらった筆跡盗聴鉛筆で盗み取る作戦だ。だが肝心の筆跡情報から問題を復元するプログラムは博士の技術では作ることができなかった。しかも、たとえ問題が復元できたとしても、俺達の頭脳では問題を解くことができない。どうすることもできなくなった俺達は、プログラマーであるあなたに、筆跡情報から問題を復元し、それを解くプログラムの作成を依頼することにした。

今回のテストでは、数式を解く問題が出題される。数式中の演算記号は＋（加算）,-（減算）,・（乗算）の3つのみで、乗算は加算、減算よりも優先して計算される。数式は必ず構文が正しいものが与えられる。また、0以外の数で、先頭が0であるものは与えられない。

問題が書かれる紙はグリッドで表される。筆跡情報は線分の集合で与えられ、各線分はX軸に水平または垂直、もしくは始点、終点が同じ（点）である。この線分は、始点から終点までにあるマスを黒く塗りつぶすことを表す。座標(0, 0)が紙の左上である。数式の各文字（0,1,2,3,4,5,6,7,8,9,＋,-,・）は以下で表される。

0

1

2

3

4

5

6

    

    

    

    

    

    

    

7

8

9

＋

-

・

    

    

    

    

    

    

 

A先生は印刷したかのような字を書くことで知られており、各文字は上記以外の書かれ方はしない。また、上記以外の文字が書かれることはない。2つ以上の文字がマスの辺を共有することはない。各文字の位置は、文字を構成するマス（黒いマス）の中で、最も左側にあるもののX座標で表される。数式の文字は、位置が小さい順に（左から右へ）解釈される。2つ以上の文字の位置が等しくなることはない。

Input

N
X11 Y11 X12 Y12
X21 Y21 X22 Y22
:
XN1 YN1 XN2 YN2

1行目に線分の数を表す1つの整数Nが与えられる。次に線分の情報がN行で与えられる。線分の情報のi行目には4つの整数Xi1, Yi1, Xi2, Yi2が空白区切りで与えられる。それぞれ、線分の1つ目の端点のX座標、Y座標、2つ目の端点のX座標、Y座標を表す。

Constraints

入力は以下の条件を満たす。

1 ≤ N ≤ 150

0 ≤ Xi1, Yi1, Xi2, Yi2 ≤ 200 (1 ≤ i ≤ N)

Xi1 = Xi2 または Yi1 = Yi2 (1 ≤ i ≤ N)

計算の途中と結果に現れる数は符号付き32ビット整数に収まる

Output

各ケースの計算結果を一行に出力せよ。

Sample Input 1

4
1 1 1 5
3 3 5 3
4 2 4 4
7 1 7 5

Sample Output 1

2

Sample Input 2

23
1 1 3 1
3 1 3 3
3 3 1 3
1 3 1 5
1 5 3 5
5 2 7 2
7 2 7 4
7 4 5 4
5 4 5 6
5 6 7 6
11 4 13 4
13 0 15 0
15 0 15 4
18 2 18 2
21 5 23 5
21 5 21 7
21 7 23 7
23 7 23 9
23 9 21 9
24 0 26 0
24 0 24 4
24 4 26 4
26 0 26 4

Sample Output 2

-328

Hint

1つのグリッドを2度以上塗りつぶすことがある

'1'など、1つの線分で表すことが可能でも、2つ以上の線分で表す場合がある

Sample Input 1の数式。

Sample Input 2の数式。"-7"の部分のように、ある文字を覆う最小の長方形の内部に別の文字が入り込む場合がある。

Solution in Rust (judge verdict: Accepted)

extern crate core;

use std::fmt;
use std::cmp::{Ordering, min, max};
use std::f32::MAX;
use std::ops::{Add, Sub, Mul, Div, Neg, Index, IndexMut, SubAssign};
use std::collections::{BTreeMap, VecDeque, BinaryHeap, BTreeSet};
use std::fmt::{Display, Formatter, Error};
use ::State::Either;

fn show<T: Display>(vec: &Vec<T>) {
    if vec.is_empty() {
        println!("[]");
    }else {
        print!("[{}", vec[0]);
        for i in 1 .. vec.len() {
            print!(", {}", vec[i]);
        }
        println!("]");
    }
}
fn show2<T: Display>(vec: &Vec<Vec<T>>) {
    if vec.is_empty() {
        println!("[]");
    }else {
        for l in vec {
            show(l);
        }
    }
}
macro_rules! read_line{
    () => {{
        let mut line = String::new();
        std::io::stdin().read_line(&mut line).ok();
        line
    }};
    (delimiter: ' ') => {
        read_line!().split_whitespace().map(|x|x.to_string()).collect::<Vec<_>>()
    };
    (delimiter: $p:expr) => {
        read_line!().split($p).map(|x|x.to_string()).collect::<Vec<_>>()
    };
    (' ') => {
        read_line!(delimiter: ' ')
    };
    ($delimiter:expr) => {
        read_line!(delimiter: $delimiter)
    };
    (' '; $ty:ty) => {
        read_line!().split_whitespace().map(|x|x.parse::<$ty>().ok().unwrap()).collect::<Vec<$ty>>()
    };
    ($delimiter:expr; $ty:ty) => {
        read_line!($delimiter).into_iter().map(|x|x.parse::<$ty>().ok().unwrap()).collect::<Vec<$ty>>()
    };
}
macro_rules! read_value{
    () => {
        read_line!().trim().parse().ok().unwrap()
    }
}
macro_rules! let_all {
    ($($n:ident:$t:ty),*) => {
        let line = read_line!(delimiter: ' ');
        let mut iter = line.iter();
        $(let $n:$t = iter.next().unwrap().parse().ok().unwrap();)*
    };
}
macro_rules! let_mut_all {
    ($($n:ident:$t:ty),*) => {
        let line = read_line!(delimiter: ' ');
        let mut iter = line.iter();
        $(let mut $n:$t = iter.next().unwrap().parse().ok().unwrap();)*
    };
}
#[derive(Copy, Clone, Eq, PartialEq)]
enum State {
    Black, White, Either
}
impl Display for State  {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        match self {
            &State::Black => write!(f, "B"),
            &State::White => write!(f, "W"),
            &State::Either => write!(f, "E"),
        }
    }
}
fn is_match(state: &[[bool; 201]; 201], x: usize, y: usize, character: &[[State; 5]; 7]) -> bool {
    for i in 0 .. 7 {
        for j in 0 .. 5 {
            match character[i][j] {
                State::Black if x + j < 1 || 201 < x + j || y + i < 1 || 201 < y + i || state[y + i - 1][x + j - 1] == false => return false,
                State::White if 1 <= x + j && x + j <= 201 && 1 <= y + i && y + i <= 201 && state[y + i - 1][x + j - 1] => return false,
                _ => {}
            }
        }
    }
    true
}
fn to_pattern(character: &[[bool; 3]; 5]) -> [[State; 5]; 7] {
    let mut result = [[State::Either; 5]; 7];
    for y in 1 .. 6 {
        for x in 1 .. 4 {
            if character[y - 1][x - 1] {
                result[y][x] = State::Black;
                if result[y + 1][x] != State::Black {
                    result[y + 1][x] = State::White;
                }
                if result[y - 1][x] != State::Black {
                    result[y - 1][x] = State::White;
                }
                if result[y][x + 1] != State::Black {
                    result[y][x + 1] = State::White;
                }
                if result[y][x - 1] != State::Black {
                    result[y][x - 1] = State::White;
                }
            }
        }
    }
    result
}
fn parse(state: &[[bool; 201];201]) -> Vec<char> {
    let zero = to_pattern( &[[true, true, true], [true, false, true], [true, false, true], [true, false, true], [true, true, true]]);
    let one = to_pattern(&[[true, false, false],[true, false, false],[true, false, false],[true, false, false],[true, false, false]]);
    let two = to_pattern(&[[true, true, true], [false, false, true], [true, true, true], [true, false, false], [true, true, true]]);
    let three = to_pattern(&[[true, true, true], [false, false, true], [true, true, true], [false, false, true], [true, true, true]]);
    let four = to_pattern(&[[true, false, true], [true, false, true], [true, true, true], [false, false, true], [false, false, true]]);
    let five = to_pattern(&[[true, true, true], [true, false, false], [true, true, true], [false, false, true], [true, true, true]]);
    let six = to_pattern(&[[true, true, true], [true, false, false], [true, true, true], [true, false, true], [true, true, true]]);
    let seven = to_pattern(&[[true, true, true], [false, false, true], [false, false, true], [false, false, true], [false, false, true]]);
    let eight = to_pattern(&[[true, true, true], [true, false, true], [true, true, true], [true, false, true], [true, true, true]]);
    let nine = to_pattern(&[[true, true, true], [true, false, true], [true, true, true], [false, false, true], [true, true, true]]);
    let plus = to_pattern(&[[false, true, false], [true, true, true], [false, true, false], [false, false, false], [false, false, false]]);
    let minus = to_pattern(&[[true, true, true], [false, false, false], [false, false, false], [false, false, false], [false, false, false]]);
    let times = to_pattern(&[[true, false, false], [false, false, false], [false, false, false], [false, false, false], [false, false, false]]);
    let mut result = Vec::new();
    for x in 0 .. 201 {
        for y in 0 .. 201 {
            if is_match(state, x, y,&zero) {
                result.push('0');
            }else if is_match(state, x, y, &one) {
                result.push('1');
            }else if is_match(state, x, y, &two) {
                result.push('2');
            }else if is_match(state, x, y, &three) {
                result.push('3');
            }else if is_match(state, x, y, &four) {
                result.push('4');
            }else if is_match(state, x, y, &five) {
                result.push('5');
            }else if is_match(state, x, y, &six) {
                result.push('6');
            }else if is_match(state, x, y, &seven){
                result.push('7');
            }else if is_match(state, x, y, &eight) {
                result.push('8');
            }else if is_match(state, x, y, &nine) {
                result.push('9');
            }else if is_match(state, x, y, &plus) {
                result.push('+');
            }else if is_match(state, x, y, &minus) {
                result.push('-');
            }else if is_match(state, x, y, &times) {
                result.push('*');
            }
        }
    }
    result
}
fn parse_i32(state: &Vec<char>, position: usize) -> Option<(i32, usize)> {
    if state.len() <= position || !state[position].is_digit(10) {
        return None
    }
    let mut result = 0;
    for i in position .. state.len() {
        if let Some(d) = state[i].to_digit(10) {
            result *= 10;
            result += d as i32;
        }else {
            return Some((result, i))
        }
    }
    Some((result, state.len()))
}
fn parse_term(state: &Vec<char>, position: usize) -> Option<(i32, usize)> {
    if let Some((value, next)) = parse_i32(state, position) {
        let mut pos = next;
        let mut result = value;
        while pos < state.len() && state[pos] == '*' {
            if let Some((v, n)) = parse_i32(state, pos + 1) {
                result *= v;
                pos = n;
            } else {unreachable!()}
        }
        Some((result, pos))
    }else {
        None
    }
}
fn parse_expression(state: &Vec<char>) -> i32 {
    if let Some((value, position)) = parse_term(state, 0) {
        let mut pos = position;
        let mut result = value;
        while pos < state.len() {
            match state[pos] {
                '+' => {
                    if let Some((v, p)) = parse_term(state, pos + 1) {
                        pos = p;
                        result += v;
                    }else {unreachable!()}
                }
                '-' => {
                    if let Some((v, p)) = parse_term(state, pos + 1){
                        pos = p;
                        result -= v;
                    }else {unreachable!()}
                }
                _ => unreachable!()
            }
        }
        result
    }else {
        unreachable!()
    }
}
fn main() {
    let mut state: [[bool; 201]; 201] = [[false; 201]; 201];
    let_all!(n: usize);
    for _ in 0 .. n {
        let_all!(fx: usize, fy: usize, tx: usize, ty: usize);
        for x in min(fx, tx) .. max(fx, tx) + 1 {
            for y in min(fy, ty) .. max(fy, ty) + 1 {
                state[y][x] = true;
            }
        }
    }
    println!("{}", parse_expression(&parse(&state)));
}