Files
cs-252/hw1/BigNum.hs

106 lines
3.2 KiB
Haskell

{-
Name: <Your name here>
Class: CS 252
Assigment: HW1
Date: <Date assignment is due>
Description: <Describe the program and what it does>
-}
module BigNum (
BigNum,
bigAdd,
bigSubtract,
bigMultiply,
bigEq,
bigDec,
bigPowerOf,
prettyPrint,
stringToBigNum,
) where
type Block = Int -- An Int from 0-999
type BigNum = [Block]
maxblock = 1000
bigAdd :: BigNum -> BigNum -> BigNum
bigAdd x y = bigAdd' x y 0
bigAdd' :: BigNum -> BigNum -> Block -> BigNum
bigAdd' [] [] 0 = []
bigAdd' [] [] c = [c]
bigAdd' (x:xs) (y:ys) c = let s = x + y + c
in (s `mod` maxblock) : bigAdd' xs ys (s `div` maxblock)
bigAdd' (x:xs) [] c = let s = x + c
in (s `mod` maxblock) : bigAdd' xs [] (s `div` maxblock)
bigAdd' [] (y:ys) c = let s = y + c
in (s `mod` maxblock) : bigAdd' [] ys (s `div` maxblock)
bigSubtract :: BigNum -> BigNum -> BigNum
bigSubtract x y =
if length x < length y
then error "Negative numbers not supported"
else reverse $ stripLeadingZeroes $ reverse result
where result = bigSubtract' x y 0
stripLeadingZeroes :: BigNum -> BigNum
stripLeadingZeroes (0:[]) = [0]
stripLeadingZeroes (0:xs) = stripLeadingZeroes xs
stripLeadingZeroes xs = xs
-- Negative numbers are not supported, so you may throw an error in these cases
bigSubtract' :: BigNum -> BigNum -> Block -> BigNum
bigSubtract' [] [] 0 = []
bigSubtract' [] _ _ = error "Negative numbers not supported"
bigSubtract' (x:xs) (y:ys) b = let d = x - y - b
in if d < 0
then (d + maxblock) : bigSubtract' xs ys 1
else d : bigSubtract' xs ys 0
bigSubtract' (x:xs) [] b = let d = x - b
in if d < 0
then (d + maxblock) : bigSubtract' xs [] 1
else d : bigSubtract' xs [] 0
bigEq :: BigNum -> BigNum -> Bool
bigEq x y = stripLeadingZeroes x == stripLeadingZeroes y
bigDec :: BigNum -> BigNum
bigDec x = bigSubtract x [1]
-- Handle multiplication following the same approach you learned in grade
-- school, except dealing with blocks of 3 digits rather than single digits.
-- If you are having trouble finding a solution, write a helper method that
-- multiplies a BigNum by an Int.
bigMultiply :: BigNum -> BigNum -> BigNum
bigMultiply _ _ = error "Your code here"
bigPowerOf :: BigNum -> BigNum -> BigNum
bigPowerOf _ _ = error "Your code here"
prettyPrint :: BigNum -> String
prettyPrint [] = ""
prettyPrint xs = show first ++ prettyPrint' rest
where (first:rest) = reverse xs
prettyPrint' :: BigNum -> String
prettyPrint' [] = ""
prettyPrint' (x:xs) = prettyPrintBlock x ++ prettyPrint' xs
prettyPrintBlock :: Int -> String
prettyPrintBlock x | x < 10 = ",00" ++ show x
| x < 100 = ",0" ++ show x
| otherwise = "," ++ show x
stringToBigNum :: String -> BigNum
stringToBigNum "0" = [0]
stringToBigNum s = stringToBigNum' $ reverse s
stringToBigNum' :: String -> BigNum
stringToBigNum' [] = []
stringToBigNum' s | length s <= 3 = read (reverse s) : []
stringToBigNum' (a:b:c:rest) = block : stringToBigNum' rest
where block = read $ c:b:a:[]
sig = "9102llaf"