blob: 412428efb3c55ab42e9fbc99c96ddc45c0baa75d (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
module Equation where
import Data.List
data Equation = Equation { left :: Polynomial, right :: Polynomial }
type Polynomial = [Term]
data Term = Term { coefficient :: Float, exponent :: Int }
instance Eq Term where
(Term _ e1) == (Term _ e2) = e1 == e2
instance Ord Term where
compare (Term _ e1) (Term _ e2) = compare e1 e2
instance Show Term where
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 = 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 -> Int
degree p = Equation.exponent (maximum p)
reduce :: Equation -> Equation
reduce equ = Equation (merge (left stdForm) (right stdForm)) []
where stdForm = equationMap (\a -> (reducePolynomial $ sort a)) equ
merge [] rs = rs
merge ls [] = ls
merge (l:ls) (r:rs)
| l == r = (subTerm l r) : merge ls rs
| l < r = l : merge ls (r:rs)
| r < l = r : merge (l:ls) rs
where subTerm (Term c1 e) (Term c2 _) = Term (c1 - c2) e
reducePolynomial [] = []
reducePolynomial [t] = [t]
reducePolynomial (t1:t2:ts)
| t1 == t2 = (addTerm t1 t2) : reducePolynomial ts
| otherwise = t1 : reducePolynomial (t2:ts)
where addTerm (Term c1 e) (Term c2 _) = Term (c1 + c2) e
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) -- not alowed
, (-b - sqrt phi) / (2.0 * a)
]
where phi = b * b - 4.0 * a * c
solveDegree1 :: Float -> Float -> Float
solveDegree1 b c = -c / b
solve :: Polynomial -> [Float]
solve [t0] = []
solve [t0, t1] = [solveDegree1 (coefficient t1) (coefficient t0)]
solve [t0, t1, t2] = solveDegree2 (coefficient t2) (coefficient t1) (coefficient t0)
solve _ = undefined
|