From 5e9ba0f5bd2be00a323b3116b5744f7cbb386e19 Mon Sep 17 00:00:00 2001 From: Florian Fouratier Date: Mon, 1 Jun 2015 23:33:05 +0200 Subject: [PATCH] Fixes and tests --- SPECS.txt | 10 ++++----- src/Data/MyPolynomial.hs | 2 +- src/Data/MyPolynomial/Parser.hs | 25 ++++++++++++++--------- src/Main.hs | 21 +++++++++++++++---- tests/tests.rb | 36 ++++++++++++++++++++++++++------- 5 files changed, 67 insertions(+), 27 deletions(-) diff --git a/SPECS.txt b/SPECS.txt index 855659a..c33e904 100644 --- a/SPECS.txt +++ b/SPECS.txt @@ -28,22 +28,22 @@ V - Forme reduite : V - Degré du polynome V - La/les solutions ( signe du delta si sensé ) +| -> Speech correspondant à la solvabilité ( cf. ci-dessous ) | -> Degré 1: S = {x} inclue dans |R | -> Degré 2: S = {x} inclue dans |R² | -> Degré 2: S = {x1, x2} inclues dans |R² | -> Degré 2: S = {c1, c2} inclues dans |C² -| -> 2 reelles | double reelle degré 2 | 2 complexes | reelle degré 1 | -> pas de résolution (degré > 2) -| -> large: a = b pour tout a == b de degré 0 : S = |R -V - absurdité : a = b pour tout a != b +| -> large: 'a = b' pour tous a == b de degré 0 : S = |R +V - absurdité : 'a = b' pour tous a != b ------------------- II- Bonus -------------------------------- -BV - Forme naturelle : - c + bx + ax^2 = 0 (monomes à coeffs nuls non-affichés) +BV - Sortie: forme réduite naturelle : + c + bx + ax^2 = 0 (monomes à coeffs nuls non-exprimés) BV - Parsing: forme naturelle | -> '*' implicite diff --git a/src/Data/MyPolynomial.hs b/src/Data/MyPolynomial.hs index 13c3ab4..f8dc4b7 100644 --- a/src/Data/MyPolynomial.hs +++ b/src/Data/MyPolynomial.hs @@ -220,7 +220,7 @@ handleNegativePowers p = case (findNeg p) of Nothing -> get >>= (\s -> state (\_ badRoots (_ :*^: 0) = [] -- Should not happen. badRoots (c :*^: p) | (-p) == 1 = ((:[]) . (:+ 0) . solveDeg1) $ toMap [zero, (c :*^: 1), zeroP 2] | (-p) == 2 = bundle $ roots $ toMap [(c :*^: 2), zeroP 1, zeroP 0] - | otherwise = error $ "Will not solve: monomial of a higher absolute degree that 2:\n" ++ prettyMonomial (c :*^: p) + | otherwise = error $ "Will not solve: monomial of a higher absolute degree than 2:\n" ++ prettyMonomial (c :*^: p) findNeg = find (\(c :*^: p) -> p < 0 && c /= 0) diff --git a/src/Data/MyPolynomial/Parser.hs b/src/Data/MyPolynomial/Parser.hs index cdf0eae..653522d 100644 --- a/src/Data/MyPolynomial/Parser.hs +++ b/src/Data/MyPolynomial/Parser.hs @@ -120,23 +120,28 @@ implicitCoeffPath = do -- - -- Parse monomial parseMonomial :: ReadP Monomial parseMonomial = skipSpaces >> (explicitCoeffPath <++ implicitCoeffPath) - + -- Wrapper using a boolean hint about the sign being reversed. +htParseMonomial :: Bool -> ReadP Monomial +htParseMonomial False = parseMonomial +htParseMonomial _ = parseMonomial >>= \(c :*^: p) -> return ((-c) :*^: p) -- Parse polynomial; i.e. : [Monomial] parsePolynomial :: ReadP (D.DList Monomial) -parsePolynomial = do - let next = do - hp <- parseMonomial - skipSpaces - optional $ char '+' - skipSpaces - parsePolynomial >>= ( \dl -> return ( hp `D.cons` dl ) ) - in next +++ ( parseMonomial >>= ( \hp -> return hp >>= sToDL ) ) +parsePolynomial = goPoly False + where goPoly revHint = do + let next = do + hp <- htParseMonomial revHint + skipSpaces + bMinus <- look >>= \s -> case s of ('+':_) -> get >> return False + ('-':_) -> get >> return True + _ -> pfail + skipSpaces + ( goPoly bMinus ) >>= ( \dl -> return ( hp `D.cons` dl ) ) + in next +++ ( htParseMonomial revHint >>= \mn -> return mn >>= sToDL ) parseEq :: ReadP Equation diff --git a/src/Main.hs b/src/Main.hs index 8caafe9..cb37a75 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -1,6 +1,7 @@ import System.Environment (getArgs) import System.IO (hPutStrLn, stderr) +import System.Exit (exitFailure, exitSuccess) import Data.DList (toList) import Control.Monad (join) @@ -11,6 +12,12 @@ import Data.MyPolynomial.Parser import Solve + +usage :: () -> IO Bool +usage _ = hPutStrLn stderr "Usage: ./mySolver " + >> return False + + processArgs :: IO (Either () String) processArgs = do args <- getArgs @@ -18,10 +25,16 @@ processArgs = do then return $ Left () else return $ Right (head args) + +doExit :: Bool -> IO () +doExit True = exitSuccess +doExit _ = exitFailure + main :: IO () main = do - let error _ = hPutStrLn stderr "Usage: ./mySolver " - proceed a = do + let proceed a = do let wrout = execWriter ( verboseSolve $ ( read a :: Equation ) ) - in putStrLn ( (toList . join) wrout ) - in processArgs >>= either error proceed + in putStrLn ( (toList . join) wrout ) >> return True + in processArgs + >>= either usage proceed + >>= doExit diff --git a/tests/tests.rb b/tests/tests.rb index ba6a33d..cca28e0 100755 --- a/tests/tests.rb +++ b/tests/tests.rb @@ -1,21 +1,24 @@ -#!/usr/bin/ruby +#!/usr/bin/env ruby + argv = ['../mySolver'] tests = [ \ # Basic / mandatory cases '5 * X^0 + 4 * X^1 = 4 * X^0', - '5 * X^0 + 4 * X^1 = 4 * X^0', + # Out of bounds degree '8 * X^0 - 6 * X^1 + 0 * X^2 - 5.6 * X^3 = 3 * X^0', + # |R '42 = 42', + # None '42 - 43 * X^0 = 0', - # Deg2 single. + # Deg2 single. ' X^2 - 1 + 4X = 2 X', # Deg1 neg power - ' 5 = X^1', - # Deg1 neg power + ' 5 = X^-1', + # Deg3, neg power ' X^2 = 2 X^-1', # Deg2 neg power ' X = 5 X^-1', @@ -33,7 +36,24 @@ 'X + 1 = -X^-1'\ ] -sep = Proc.new do + +expectations = [ \ + '-1/4 ; degree 1 speech.', + ' Degree too high (3)', + '|R', + 'None: absurd', + '-1-sqrt(2) ; sqrt(2)-1 ~> -2.41 ; 0.41', + '1/5 ; excluding 0; deg 1', + "Shouldn't solve (deg 3)", + " sqrt(5), -sqrt(5), excluding 0 ~> +-2.24", + "~-> +-2.58 ; excluding 0", + ' Degree : will not solve.', + '-1/2 +- (Math.sqrt(3) / 2)i', + '-1/2 +- (Math.sqrt(3)/ 2)i ; excluding 0' +] + + +sep = Proc.new do spaces = Array.new( 80, ' '.bytes.first ).pack('C*') nl = [0xA].pack('C') @@ -43,8 +63,10 @@ end.call -tests.each do |c| +tests.zip( expectations ).each do |p| + c = p.first + puts 'Expecting: ' + p.last cmd = argv.+([' \'', c, '\'']).join puts cmd system cmd