mathhhsss
This commit is contained in:
parent
61288747ae
commit
249fa1f2b2
53
src/main.rs
53
src/main.rs
|
@ -11,6 +11,8 @@ enum ErreurSophie {
|
||||||
ManqueArgument(String),
|
ManqueArgument(String),
|
||||||
OrthographeNombre(String),
|
OrthographeNombre(String),
|
||||||
MauvaisArgument(String),
|
MauvaisArgument(String),
|
||||||
|
DesequilibreParenthese,
|
||||||
|
VariableInconnue(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for ErreurSophie {
|
impl fmt::Display for ErreurSophie {
|
||||||
|
@ -20,7 +22,9 @@ impl fmt::Display for ErreurSophie {
|
||||||
Self::PhraseVide => write!(f, "La phrase est vide."),
|
Self::PhraseVide => write!(f, "La phrase est vide."),
|
||||||
Self::ManqueArgument(commande) => write!(f, "Il manque un argument pour \"{}\".", commande),
|
Self::ManqueArgument(commande) => write!(f, "Il manque un argument pour \"{}\".", commande),
|
||||||
Self::OrthographeNombre(nombre) => write!(f, "Le nombre \"{}\" est mal orthographié.", nombre),
|
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);
|
println!("- demande : {}", arguments);
|
||||||
Ok(())
|
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() {
|
fn main() {
|
||||||
|
@ -172,6 +151,8 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
#[cfg(test)] // Compile and run only during testing
|
#[cfg(test)] // Compile and run only during testing
|
||||||
mod tests {
|
mod tests {
|
||||||
|
@ -179,7 +160,6 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn teste_conversion_nombres_texte() {
|
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() {
|
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
|
let texte = nombres::nombre_comme_texte(*i); // Convert number to text
|
||||||
match nombres::texte_comme_nombre(&texte) { // Convert text back to number
|
match nombres::texte_comme_nombre(&texte) { // Convert text back to number
|
||||||
|
@ -231,7 +211,7 @@ mod tests {
|
||||||
let mut sophie = Sophie::new();
|
let mut sophie = Sophie::new();
|
||||||
let a = 2345678;
|
let a = 2345678;
|
||||||
let b = 987654;
|
let b = 987654;
|
||||||
let phrase = format!("Modifie Variable avec {}", nombres::nombre_comme_texte(a));
|
let phrase = format!("Modifie Variable avec {} ", nombres::nombre_comme_texte(a));
|
||||||
if let Err(raison) = sophie.execute_phrase(&phrase) {
|
if let Err(raison) = sophie.execute_phrase(&phrase) {
|
||||||
panic!("Execution échouée pour \"{}\", avec l'erreur : {}", phrase, raison);
|
panic!("Execution échouée pour \"{}\", avec l'erreur : {}", phrase, raison);
|
||||||
}
|
}
|
||||||
|
@ -248,12 +228,23 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn teste_multiplication() {
|
fn teste_maths() {
|
||||||
let sophie = Sophie::new();
|
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 {
|
match resultat {
|
||||||
Ok(nombre) => {
|
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) => {
|
Err(raison) => {
|
||||||
panic!("Execution échouée pour multiplication, avec l'erreur : {}", 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::ErreurSophie;
|
||||||
|
use super::Sophie;
|
||||||
|
|
||||||
const NOMS_UNITES: [&str; 10] = ["", "un", "deux", "trois", "quatre", "cinq", "six", "sept", "huit", "neuf"];
|
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"];
|
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 NOMS_SEPARATEURS: [&str; 7] = ["", "mille", "million", "milliard", "billion", "billiard", "trillion"];
|
||||||
const UNION: &str = "-";
|
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 {
|
pub fn nombre_comme_texte(nombre: usize) -> String {
|
||||||
if nombre == 0 {
|
if nombre == 0 {
|
||||||
return "zéro".to_string()
|
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.
|
Affiche deux fois ouvre la parenthèse quatre plus seize ferme la parenthèse.
|
||||||
|
|
Loading…
Reference in a new issue