mathhhsss
This commit is contained in:
parent
61288747ae
commit
249fa1f2b2
51
src/main.rs
51
src/main.rs
|
@ -11,6 +11,8 @@ enum ErreurSophie {
|
|||
ManqueArgument(String),
|
||||
OrthographeNombre(String),
|
||||
MauvaisArgument(String),
|
||||
DesequilibreParenthese,
|
||||
VariableInconnue(String),
|
||||
}
|
||||
|
||||
impl fmt::Display for ErreurSophie {
|
||||
|
@ -20,7 +22,9 @@ impl fmt::Display for ErreurSophie {
|
|||
Self::PhraseVide => write!(f, "La phrase est vide."),
|
||||
Self::ManqueArgument(commande) => write!(f, "Il manque un argument pour \"{}\".", commande),
|
||||
Self::OrthographeNombre(nombre) => write!(f, "Le nombre \"{}\" est mal orthographié.", nombre),
|
||||
Self::MauvaisArgument(message) => write!(f, "La commande a reçu un mauvais argument, {}.", message)
|
||||
Self::MauvaisArgument(message) => write!(f, "La commande a reçu un mauvais argument, {}.", message),
|
||||
Self::DesequilibreParenthese => write!(f, "Les parenthèses sont déséquilibrés."),
|
||||
Self::VariableInconnue(nom) => write!(f, "La variable \"{}\" est inconnue", nom),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -123,31 +127,6 @@ impl Sophie {
|
|||
println!("- demande : {}", arguments);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn operation(&self, arguments: &str) -> Result<usize, ErreurSophie> {
|
||||
let somme_texte: Vec<&str> = arguments.split("plus").collect();
|
||||
let mut somme : usize = 0;
|
||||
for somme_element in somme_texte {
|
||||
let somme_element_propre: &str = somme_element.trim();
|
||||
let produit_texte: Vec<&str> = somme_element_propre.split("fois").collect();
|
||||
|
||||
let mut produit : usize = 1;
|
||||
for produit_element in produit_texte {
|
||||
let produit_element_propre: &str = produit_element.trim();
|
||||
let Some(first_char) = produit_element_propre.chars().next() else {
|
||||
return Err(ErreurSophie::MauvaisArgument("il y a un argument vide pour l'operation".to_string()))
|
||||
};
|
||||
let nombre = if first_char.is_uppercase() {
|
||||
self.variables[produit_element_propre]
|
||||
} else {
|
||||
nombres::texte_comme_nombre(produit_element_propre)?
|
||||
};
|
||||
produit *= nombre;
|
||||
}
|
||||
somme += produit;
|
||||
}
|
||||
Ok(somme)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
@ -172,6 +151,8 @@ fn main() {
|
|||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
|
||||
#[cfg(test)] // Compile and run only during testing
|
||||
mod tests {
|
||||
|
@ -179,7 +160,6 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn teste_conversion_nombres_texte() {
|
||||
// Test on a limited set of numbers to ensure feasibility
|
||||
for i in [0, 1, 42, 123, 999, 1031, 1_001_091, 72_036_854_775_807usize].iter() {
|
||||
let texte = nombres::nombre_comme_texte(*i); // Convert number to text
|
||||
match nombres::texte_comme_nombre(&texte) { // Convert text back to number
|
||||
|
@ -248,12 +228,23 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn teste_multiplication() {
|
||||
fn teste_maths() {
|
||||
let sophie = Sophie::new();
|
||||
let resultat = sophie.operation("trois fois deux plus quatre fois sept");
|
||||
let a = 2345678;
|
||||
let b = 987654;
|
||||
let c = 34523456;
|
||||
let d = 45678;
|
||||
let e = 2;
|
||||
let resultat = sophie.operation(&format!("{} fois {} plus ouvre la parenthèse {} moins {} ferme la parenthèse divisé par {}",
|
||||
nombres::nombre_comme_texte(a),
|
||||
nombres::nombre_comme_texte(b),
|
||||
nombres::nombre_comme_texte(c),
|
||||
nombres::nombre_comme_texte(d),
|
||||
nombres::nombre_comme_texte(e)
|
||||
));
|
||||
match resultat {
|
||||
Ok(nombre) => {
|
||||
assert_eq!(nombre, 34, "Echec de la multiplication de 3*2+4*7, got {}", nombre);
|
||||
assert_eq!(nombre, a*b+(c-d)/e, "Echec de l'opération mathématique, got {}", nombre);
|
||||
}
|
||||
Err(raison) => {
|
||||
panic!("Execution échouée pour multiplication, avec l'erreur : {}", raison);
|
||||
|
|
102
src/nombres.rs
102
src/nombres.rs
|
@ -1,4 +1,5 @@
|
|||
use super::ErreurSophie;
|
||||
use super::Sophie;
|
||||
|
||||
const NOMS_UNITES: [&str; 10] = ["", "un", "deux", "trois", "quatre", "cinq", "six", "sept", "huit", "neuf"];
|
||||
const NOMS_UNITES_DIX: [&str; 10] = ["dix", "onze", "douze", "treize", "quatorze", "quinze", "seize", "dix-sept", "dix-huit", "dix-neuf"];
|
||||
|
@ -6,6 +7,107 @@ const NOMS_DIZAINES: [&str; 9] = ["", "dix", "vingt", "trente", "quarante", "cin
|
|||
const NOMS_SEPARATEURS: [&str; 7] = ["", "mille", "million", "milliard", "billion", "billiard", "trillion"];
|
||||
const UNION: &str = "-";
|
||||
|
||||
impl Sophie {
|
||||
pub fn operation(&self, arguments: &str) -> Result<usize, ErreurSophie> {
|
||||
//return self.operation_elementaire(arguments);
|
||||
let texte = arguments
|
||||
.replace("ouvre la parenthèse", "ouvre-la-parenthese")
|
||||
.replace("ferme la parenthèse", "ferme-la-parenthese")
|
||||
.replace("divisé par", "divise-par");
|
||||
let mut expression: Vec<String> = texte.split(" ").map(String::from).collect();
|
||||
|
||||
while expression.contains(&"ouvre-la-parenthese".to_string()) {
|
||||
let mut ouverture: Option<usize> = None;
|
||||
let mut fermeture: Option<usize> = None;
|
||||
for index in 0..expression.len() {
|
||||
if expression[index] == "ouvre-la-parenthese" {
|
||||
ouverture = Some(index);
|
||||
}
|
||||
if expression[index] == "ferme-la-parenthese" && ouverture.is_some() {
|
||||
fermeture = Some(index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
let Some(index_ouverture) = ouverture else {
|
||||
return Err(ErreurSophie::DesequilibreParenthese);
|
||||
};
|
||||
let Some(index_fermeture) = fermeture else {
|
||||
return Err(ErreurSophie::DesequilibreParenthese);
|
||||
};
|
||||
let contenu: String = expression[(index_ouverture+1)..(index_fermeture)].join(" ");
|
||||
let nombre = self.operation_elementaire(&contenu)?;
|
||||
let nombre_texte = nombre_comme_texte(nombre);
|
||||
expression[index_ouverture] = nombre_texte;
|
||||
for _ in 0..(index_fermeture-index_ouverture) {
|
||||
expression.remove(index_ouverture+1);
|
||||
}
|
||||
}
|
||||
if expression.contains(&"ferme-la-parenthese".to_string()) {
|
||||
return Err(ErreurSophie::DesequilibreParenthese);
|
||||
}
|
||||
self.operation_elementaire(&expression.join(" "))
|
||||
}
|
||||
|
||||
pub fn operation_elementaire(&self, arguments: &str) -> Result<usize, ErreurSophie> {
|
||||
let texte = arguments.replace("divisé par", "divise-par");
|
||||
let mut expression: Vec<String> = texte.split(" ").map(String::from).collect();
|
||||
|
||||
let mut index = 0;
|
||||
while index < expression.len() {
|
||||
if expression[index] != "fois" && expression[index] != "divise-par" {
|
||||
index += 1;
|
||||
continue;
|
||||
}
|
||||
if index == 0 || index == expression.len() - 1 {
|
||||
return Err(ErreurSophie::ManqueArgument(expression[index].to_string()));
|
||||
}
|
||||
let a = self.texte_comme_nombre(&expression[index - 1])?;
|
||||
let b = self.texte_comme_nombre(&expression[index + 1])?;
|
||||
let produit = if expression[index] == "fois" {a*b} else {a/b};
|
||||
let produit_texte: String = nombre_comme_texte(produit);
|
||||
index -= 1;
|
||||
expression[index] = produit_texte;
|
||||
expression.remove(index + 1);
|
||||
expression.remove(index + 1);
|
||||
}
|
||||
|
||||
let mut index = 0;
|
||||
while index < expression.len() {
|
||||
if expression[index] != "plus" && expression[index] != "moins" {
|
||||
index += 1;
|
||||
continue;
|
||||
}
|
||||
if index == 0 || index == expression.len() - 1 {
|
||||
return Err(ErreurSophie::ManqueArgument(expression[index].to_string()));
|
||||
}
|
||||
let a = self.texte_comme_nombre(&expression[index - 1])?;
|
||||
let b = self.texte_comme_nombre(&expression[index + 1])?;
|
||||
let somme = if expression[index] == "plus" {a+b} else {a-b};
|
||||
let somme_texte: String = nombre_comme_texte(somme);
|
||||
index -= 1;
|
||||
expression[index] = somme_texte;
|
||||
expression.remove(index + 1);
|
||||
expression.remove(index + 1);
|
||||
}
|
||||
|
||||
if expression.len() > 1 {
|
||||
return Err(ErreurSophie::MauvaisArgument("expression mathématique".to_string()))
|
||||
}
|
||||
self.texte_comme_nombre(&expression[0])
|
||||
}
|
||||
|
||||
fn texte_comme_nombre(&self, texte: &str) -> Result<usize, ErreurSophie> {
|
||||
if texte.chars().next().map_or(false, |c| c.is_uppercase()) {
|
||||
if self.variables.contains_key(texte) {
|
||||
return Ok(self.variables[texte]);
|
||||
} else {
|
||||
return Err(ErreurSophie::VariableInconnue(texte.to_string()))
|
||||
}
|
||||
}
|
||||
texte_comme_nombre(texte)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn nombre_comme_texte(nombre: usize) -> String {
|
||||
if nombre == 0 {
|
||||
return "zéro".to_string()
|
||||
|
|
1
test.sp
1
test.sp
|
@ -1 +1,2 @@
|
|||
Affiche dix plus sept fois sept.
|
||||
Affiche deux fois ouvre la parenthèse quatre plus seize ferme la parenthèse.
|
||||
|
|
Loading…
Reference in a new issue