diff --git a/complexnums/package.yaml b/complexnums/package.yaml index 9cef8cb..9a4a226 100644 --- a/complexnums/package.yaml +++ b/complexnums/package.yaml @@ -23,6 +23,7 @@ dependencies: - base >= 4.7 && < 5 - regex-pcre - lens +- split library: source-dirs: src diff --git a/complexnums/src/Lib.hs b/complexnums/src/Lib.hs index 21a0a57..f01cf78 100644 --- a/complexnums/src/Lib.hs +++ b/complexnums/src/Lib.hs @@ -8,6 +8,9 @@ import Control.Arrow ((>>>)) import Text.Regex.PCRE ((=~)) import qualified Text.Regex.PCRE as PCRE import Control.Lens.Operators +import qualified Data.List as List +import qualified Data.List.Split as Split +import qualified Debug.Trace as Trace if' :: Bool -> a -> a -> a if' True x _ = x @@ -21,7 +24,8 @@ prompt loopCondition text = line >>= breakorcontinue (SIO.stdout & SIO.hFlush) >> getLine -complexNumber = "^\\s*\\+?(-?\\s*[0-9\\.]+)?\\s*(\\+?((-\\s*)?[0-9\\.]*)i)?\\s*$" +complexNumber = "^\\s*(()()([\\-\\+])?\\s*(([0-9\\.]*)i)|([\\-\\+])?\\s*([0-9\\.]+)()(())|([\\-\\+])?\\s*([0-9\\.]+)\\s*([\\-\\+])\\s*(([0-9\\.]*)i))\\s*$" + data ComplexNumber = ComplexNumber { complexNumberReal :: Float, @@ -34,32 +38,54 @@ instance Show ComplexNumber where stringToComplex :: String -> ComplexNumber stringToComplex input = ComplexNumber realValue imaginaryValue where - realValue = if' (null realDigits) 0 (realDigits & read) - imaginaryValue = - if' (null imaginaryDigits) - (if' (null imaginaryPart) - 0 - 1 - ) - (imaginaryDigits & read) - _:realDigits:imaginaryPart:imaginaryDigits:_ = match + realValue = if' (null realDigits) 0 (read realDigits * handleSign realSign) + imaginaryValue = handleImaginary (handleSign imaginarySign) imaginaryPart imaginaryDigits + handleSign "+" = 1 :: Float + handleSign "-" = -1 + handleSign "" = 1 + handleImaginary sign part digits + | null part = 0 + | null digits = 1 * sign + | otherwise = read digits * sign + realSign:realDigits:imaginarySign:imaginaryPart:imaginaryDigits:_ = match & drop 2 & Split.chunksOf 5 & dropWhile(\a -> (a & filter(=="") & length) == 5) & head match:_ = input =~ complexNumber :: [[String]] addComplex :: ComplexNumber -> ComplexNumber -> ComplexNumber addComplex a b = ComplexNumber (complexNumberReal a + complexNumberReal b) (complexNumberImaginary a + complexNumberImaginary b) multiplyComplex :: ComplexNumber -> ComplexNumber -> ComplexNumber -multiplyComplex a b = ComplexNumber (complexNumberReal a * complexNumberReal b - complexNumberImaginary a * complexNumberImaginary b) (complexNumberReal a * complexNumberImaginary b + complexNumberReal b * complexNumberImaginary a) +multiplyComplex a b = ComplexNumber + (complexNumberReal a * complexNumberReal b - complexNumberImaginary a * complexNumberImaginary b) + (complexNumberReal a * complexNumberImaginary b + complexNumberReal b * complexNumberImaginary a) + +divideComplex :: ComplexNumber -> ComplexNumber -> ComplexNumber +divideComplex num dem = getdem & getfinal + where + getfinal newdem = ComplexNumber + ( + (complexNumberReal num * complexNumberReal dem + complexNumberImaginary num * complexNumberImaginary dem) + / newdem + ) + ( + (complexNumberReal dem * complexNumberImaginary num - complexNumberReal num * complexNumberImaginary dem) + / newdem + ) + getdem = complexNumberReal dem ** 2 + complexNumberImaginary dem ** 2 someFunc :: IO () someFunc = showResults <$> firstNumber <*> secondNumber >>= putStrLn where showResults f s = [ + "Input: ", + f & show, + s & show, "Added: ", addComplex f s & show, - "\nMultiplied: ", - multiplyComplex f s & show - ] & concat + "Multiplied: ", + multiplyComplex f s & show, + "Divided: ", + divideComplex f s & show + ] & List.intercalate "\n" firstNumber = ("Enter a complex number in the form of a + bi: " & prompt(=~ complexNumber)) <&> stringToComplex secondNumber = ("Enter a second complex number in the form of a + bi: " & prompt(=~ complexNumber)) <&> stringToComplex