Initial commit
This commit is contained in:
91
board-shared/src/expr.rs
Normal file
91
board-shared/src/expr.rs
Normal file
@@ -0,0 +1,91 @@
|
||||
use crate::board::Board;
|
||||
use crate::lexer::lexer;
|
||||
use crate::parser;
|
||||
use crate::parser::{Expression, Expressions};
|
||||
use crate::tile::{Operator, Tile};
|
||||
|
||||
pub fn calculate(expr: &Expression) -> f64 {
|
||||
match expr {
|
||||
Expression::Digit(value) => *value as f64,
|
||||
Expression::Parentheses(expr) => calculate(expr),
|
||||
Expression::Binary(operator, left, right) => {
|
||||
let left = calculate(left);
|
||||
let right = calculate(right);
|
||||
match operator {
|
||||
Operator::Add => left + right,
|
||||
Operator::Subtract => left - right,
|
||||
Operator::Multiply => left * right,
|
||||
Operator::Divide => left / right,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn are_valid_expressions(expr: &Expressions) -> bool {
|
||||
let mut res: Option<f64> = None;
|
||||
for expr in expr {
|
||||
let value = calculate(expr);
|
||||
if let Some(res) = res {
|
||||
if res != value {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
res = Some(value);
|
||||
}
|
||||
}
|
||||
res.is_some()
|
||||
}
|
||||
|
||||
pub fn is_valid_guess(board: &Board, positions: &[(usize, usize)]) -> Result<bool, ()> {
|
||||
let tiles = positions
|
||||
.iter()
|
||||
.map(|&(x, y)| board.get(x, y))
|
||||
.collect::<Option<Vec<Tile>>>()
|
||||
.ok_or(())?;
|
||||
|
||||
let tokens = lexer(&tiles)?;
|
||||
let expressions = parser::parse(&tokens)?;
|
||||
Ok(are_valid_expressions(&expressions))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_calculate() {
|
||||
let expr = Expression::Binary(
|
||||
Operator::Add,
|
||||
Box::new(Expression::Digit(1)),
|
||||
Box::new(Expression::Digit(2)),
|
||||
);
|
||||
assert_eq!(calculate(&expr), 3.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_are_valid_expressions() {
|
||||
let expr = vec![
|
||||
Expression::Binary(
|
||||
Operator::Add,
|
||||
Box::new(Expression::Digit(3)),
|
||||
Box::new(Expression::Digit(4)),
|
||||
),
|
||||
Expression::Binary(
|
||||
Operator::Add,
|
||||
Box::new(Expression::Digit(6)),
|
||||
Box::new(Expression::Digit(1)),
|
||||
),
|
||||
];
|
||||
assert!(are_valid_expressions(&expr));
|
||||
|
||||
let expr = vec![
|
||||
Expression::Digit(9),
|
||||
Expression::Binary(
|
||||
Operator::Add,
|
||||
Box::new(Expression::Digit(7)),
|
||||
Box::new(Expression::Digit(1)),
|
||||
),
|
||||
];
|
||||
assert!(!are_valid_expressions(&expr));
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user