From 0b9af447ffa279f07bdcbc8201a6ad8d731ea95b Mon Sep 17 00:00:00 2001 From: Charles Date: Mon, 9 Mar 2020 20:52:05 +0100 Subject: Spaces in parsing, more intuitive equation display --- src/equation.hs | 18 +++++++++++------- src/main.hs | 1 + src/parser.hs | 42 ++++++++++++++++++++++++------------------ 3 files changed, 36 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/equation.hs b/src/equation.hs index 019701f..412428e 100644 --- a/src/equation.hs +++ b/src/equation.hs @@ -1,12 +1,11 @@ module Equation where -import Numeric.Natural import Data.List data Equation = Equation { left :: Polynomial, right :: Polynomial } type Polynomial = [Term] -data Term = Term { coefficient :: Float, exponent :: Natural } +data Term = Term { coefficient :: Float, exponent :: Int } instance Eq Term where (Term _ e1) == (Term _ e2) = e1 == e2 @@ -15,17 +14,22 @@ instance Ord Term where compare (Term _ e1) (Term _ e2) = compare e1 e2 instance Show Term where - show (Term c e) = show c ++ " * X^" ++ show e + show (Term 0 e) = "" + show (Term c 0) = show (round c) + show (Term c e) + | c < 0 = " - " ++ showInside (-c) + | c > 0 = " + " ++ showInside c + where showInside co = show (round co) ++ " * X^" ++ show e instance Show Equation where show (Equation l r) = showPolynomial l ++ " = " ++ showPolynomial r where showPolynomial [] = "0" - showPolynomial p = intercalate " + " (map show p) + showPolynomial p = concatMap show (filter (\(Term c _) -> c /= 0) p) equationMap :: (Polynomial -> Polynomial) -> Equation -> Equation equationMap f (Equation l r) = Equation (f l) (f r) -degree :: Polynomial -> Natural +degree :: Polynomial -> Int degree p = Equation.exponent (maximum p) reduce :: Equation -> Equation @@ -49,10 +53,10 @@ solveDegree2 :: Float -> Float -> Float -> [Float] solveDegree2 a b c | phi < 0 = [] | phi == 0 = [(-b) / (2.0 * a)] - | phi > 0 = [ (-b + sqrt phi) / (2.0 * a) + | phi > 0 = [ (-b + sqrt phi) / (2.0 * a) -- not alowed , (-b - sqrt phi) / (2.0 * a) ] - where phi = b ^ 2 - 4.0 * a * c + where phi = b * b - 4.0 * a * c solveDegree1 :: Float -> Float -> Float solveDegree1 b c = -c / b diff --git a/src/main.hs b/src/main.hs index 4b365a2..f466b68 100644 --- a/src/main.hs +++ b/src/main.hs @@ -11,6 +11,7 @@ main = do equ <- checkParsing (head args) let reduced = reduce equ putStrLn $ "Reduced From: " ++ show reduced + putStrLn $ "Polynomial degree: " ++ (show $ degree $ left reduced) putSolutions (left reduced) diff --git a/src/parser.hs b/src/parser.hs index df0ac10..49d23d7 100644 --- a/src/parser.hs +++ b/src/parser.hs @@ -3,7 +3,6 @@ module Parser where import Control.Applicative import Control.Monad import Data.Char -import Numeric.Natural import Equation @@ -44,35 +43,42 @@ charP x = Parser p p (c:cs) = if c == x then Just (c, cs) else Nothing +satisfy :: (Char -> Bool) -> Parser String +satisfy f = Parser (\s -> Just $ span f s) + digitsP :: Parser String -digitsP = Parser (\s -> Just $ span isDigit s) +digitsP = satisfy isDigit + +spacesP :: Parser String +spacesP = satisfy isSpace sepBy :: Parser a -> Parser b -> Parser [a] -sepBy x sep = ((:) <$> x <*> many (sep *> x)) <|> pure [] +sepBy x sep = (:) <$> x <*> many (sep *> x) +surround :: Parser a -> Parser b -> Parser b +surround surrounding x = surrounding *> x <* surrounding -- Equation parsers -- 1 * X^0 + 2 * X^1 + 1 * 3 * X^2 = 0 -coefficientP :: Parser Float -coefficientP = read <$> (floatP <|> digitsP) - where floatP = (\i _ f -> (i ++ "." ++ f)) - <$> digitsP <*> charP '.' <*> digitsP - -exponentP :: Parser Natural -exponentP = read <$> digitsP +intP :: Parser Int +intP = read <$> numStr + where numStr = ((:) <$> charP '-' <*> digitsP) <|> digitsP termP :: Parser Term -termP = (\coef _ exp -> Term coef exp) - <$> coefficientP - <*> (charP '*' *> charP 'X' *> charP '^') - <*> exponentP +termP = notConstantP <|> constantP + where constantP = (\c -> Term (fromIntegral c) 0) <$> intP + notConstantP = (\coef exp -> Term (fromIntegral coef) exp) + <$> intP <*> (between *> intP) + where between = spacesP *> charP '*' *> + spacesP *> charP 'X' *> + spacesP *> charP '^' *> + spacesP polynomialP :: Parser Polynomial -polynomialP = sepBy termP (charP '+') +polynomialP = sepBy termP (spacesP *> charP '+' *> spacesP) equationP :: Parser Equation -equationP = (\l _ r -> Equation l r) +equationP = (\l r -> Equation l r) <$> polynomialP - <*> charP '=' - <*> polynomialP + <*> (spacesP *> charP '=' *> spacesP *> polynomialP) -- cgit