hw1: init
This commit is contained in:
89
hw1/BigNum.hs
Normal file
89
hw1/BigNum.hs
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
{-
|
||||||
|
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' _ _ _ = error "Your code here"
|
||||||
|
|
||||||
|
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' _ _ _ = error "Your code here"
|
||||||
|
|
||||||
|
bigEq :: BigNum -> BigNum -> Bool
|
||||||
|
bigEq _ _ = error "Your code here"
|
||||||
|
|
||||||
|
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"
|
||||||
36
hw1/Calculator.hs
Normal file
36
hw1/Calculator.hs
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
-- This is a simple parser for testing out BigNum.
|
||||||
|
-- Note that there are much better parsers, which
|
||||||
|
-- we will explore in another class.
|
||||||
|
|
||||||
|
import BigNum
|
||||||
|
|
||||||
|
-- Crude way of handling whitespace: make sure
|
||||||
|
-- that all ops are surrounded by whitespace.
|
||||||
|
addSpace :: String -> String
|
||||||
|
addSpace [] = ""
|
||||||
|
addSpace ('+':xs) = " + " ++ addSpace xs
|
||||||
|
addSpace ('-':xs) = " - " ++ addSpace xs
|
||||||
|
addSpace ('*':xs) = " * " ++ addSpace xs
|
||||||
|
addSpace ('^':xs) = " ^ " ++ addSpace xs
|
||||||
|
addSpace (x:xs) = x : addSpace xs
|
||||||
|
|
||||||
|
calculate :: String -> BigNum -> BigNum -> BigNum
|
||||||
|
calculate "+" b1 b2 = bigAdd b1 b2
|
||||||
|
calculate "-" b1 b2 = bigSubtract b1 b2
|
||||||
|
calculate "*" b1 b2 = bigMultiply b1 b2
|
||||||
|
calculate "^" b1 b2 = bigPowerOf b1 b2
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
|
main = do
|
||||||
|
line <- getLine
|
||||||
|
if null line
|
||||||
|
then return ()
|
||||||
|
else do
|
||||||
|
case words $ addSpace line of
|
||||||
|
exp1:op:exp2:[] -> putStrLn $ prettyPrint $ calculate op big1 big2
|
||||||
|
where big1 = stringToBigNum exp1
|
||||||
|
big2 = stringToBigNum exp2
|
||||||
|
exp:[] -> putStrLn $ show $ stringToBigNum exp
|
||||||
|
_ -> putStrLn "Only simply binary expressions are supported"
|
||||||
|
main
|
||||||
|
|
||||||
5
hw1/Test.java
Normal file
5
hw1/Test.java
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
public class Test {
|
||||||
|
public void main(String[] args) {
|
||||||
|
System.out.println(999999999999999999999 * 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
63
hw1/hw1.txt
Normal file
63
hw1/hw1.txt
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
For the first assignment, we will look at how Haskell handles big numbers.
|
||||||
|
|
||||||
|
***NOTE: YOU MAY NOT CHANGE ANY TYPE SIGNATURES***
|
||||||
|
***IF YOU DO, YOU WILL GET A ZERO FOR THE ASSIGNMENT***
|
||||||
|
|
||||||
|
Consider the following Java program (available in Test.java).
|
||||||
|
|
||||||
|
public class Test {
|
||||||
|
public void main(String[] args) {
|
||||||
|
System.out.println(999999999999999999999 * 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
You could easily calculate 999999999999999999999 * 2 with pencil and paper;
|
||||||
|
Java cannot handle it.
|
||||||
|
|
||||||
|
$ javac Test.java
|
||||||
|
Test.java:3: error: integer number too large: 999999999999999999999
|
||||||
|
System.out.println(999999999999999999999 * 2);
|
||||||
|
^
|
||||||
|
1 error
|
||||||
|
|
||||||
|
With Haskell, there is no problem:
|
||||||
|
|
||||||
|
$ ghci
|
||||||
|
GHCi, version 7.6.3: http://www.haskell.org/ghc/ :? for help
|
||||||
|
Loading package ghc-prim ... linking ... done.
|
||||||
|
Loading package integer-gmp ... linking ... done.
|
||||||
|
Loading package base ... linking ... done.
|
||||||
|
Prelude> 999999999999999999999 * 2
|
||||||
|
1999999999999999999998
|
||||||
|
Prelude>
|
||||||
|
|
||||||
|
So how does Haskell handle these numbers?
|
||||||
|
We will implement a simplified BigNum module to understand it better.
|
||||||
|
|
||||||
|
In our implementation, a number will be a list of "blocks" of numbers from 0-999,
|
||||||
|
stored with the least significant "block" first. So 9,073,201 will be
|
||||||
|
stored as:
|
||||||
|
|
||||||
|
[201,73,9]
|
||||||
|
|
||||||
|
Your job is to complete BigNum.hs. The breakdown of points is as follows:
|
||||||
|
* 10 points -- Complete bigAdd'
|
||||||
|
* 5 points -- Complete bigSubtract'
|
||||||
|
* 3 points -- Complete bigMultiply
|
||||||
|
* 2 points -- Complete bigPowerOf
|
||||||
|
|
||||||
|
|
||||||
|
Starter code is available on the course website.
|
||||||
|
The files include:
|
||||||
|
* BigNum.hs -- You will modify this file (only).
|
||||||
|
* Calculator.hs -- A (very) simple calculator that relies on your BigNum module.
|
||||||
|
* test.hs -- A number of test cases that use BigNum.
|
||||||
|
* input -- A number of cases that Calculator.hs should handle correctly.
|
||||||
|
* output_EXPECTED -- the expected results of calling (from the command line):
|
||||||
|
$runhaskell test.hs
|
||||||
|
$runhaskell Calculator.hs < input
|
||||||
|
|
||||||
|
Note that negative numbers are not supported, and should raise an error.
|
||||||
|
|
||||||
|
Submit BigNum.hs through Canvas.
|
||||||
|
|
||||||
7
hw1/input
Normal file
7
hw1/input
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
3 + 4
|
||||||
|
9 * 7
|
||||||
|
2 ^ 8
|
||||||
|
400000000000000000001 * 2
|
||||||
|
999999999999999999999 - 999999999999999999998
|
||||||
|
483971285601 * 123448796045
|
||||||
|
|
||||||
0
hw1/output
Normal file
0
hw1/output
Normal file
26
hw1/output_EXPECTED
Normal file
26
hw1/output_EXPECTED
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
Addition
|
||||||
|
[455,1]
|
||||||
|
[455,3]
|
||||||
|
[455,235,681]
|
||||||
|
[455,235,681]
|
||||||
|
[455,1,681]
|
||||||
|
Subtraction
|
||||||
|
[999]
|
||||||
|
[962,634,9]
|
||||||
|
[1]
|
||||||
|
[0]
|
||||||
|
Multiplication
|
||||||
|
[12]
|
||||||
|
[0]
|
||||||
|
[392,296,4,12]
|
||||||
|
[518,250,645,161,37,915,479,1]
|
||||||
|
Power Of
|
||||||
|
[256]
|
||||||
|
[1]
|
||||||
|
Others
|
||||||
|
7
|
||||||
|
63
|
||||||
|
256
|
||||||
|
800,000,000,000,000,000,002
|
||||||
|
1
|
||||||
|
59,745,672,527,794,294,248,045
|
||||||
50
hw1/test.hs
Normal file
50
hw1/test.hs
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
import BigNum
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
|
main = do
|
||||||
|
putStrLn "Addition"
|
||||||
|
--999 + 456
|
||||||
|
putStrLn $ show $ bigAdd [999] [456]
|
||||||
|
--1999 + 1456
|
||||||
|
putStrLn $ show $ bigAdd [999,1] [456,1]
|
||||||
|
--681234999 + 456
|
||||||
|
putStrLn $ show $ bigAdd [999,234,681] [456]
|
||||||
|
--456 + 681234999
|
||||||
|
putStrLn $ show $ bigAdd [456] [999,234,681]
|
||||||
|
--681000999 + 456
|
||||||
|
putStrLn $ show $ bigAdd [999,0,681] [456]
|
||||||
|
|
||||||
|
putStrLn "Subtraction"
|
||||||
|
--1000 - 1
|
||||||
|
putStrLn $ show $ bigSubtract [0,1] [1]
|
||||||
|
--9643291 - 8329
|
||||||
|
putStrLn $ show $ bigSubtract [291,643,9] [329,8]
|
||||||
|
--999999 - 999998
|
||||||
|
putStrLn $ show $ bigSubtract [999,999] [998,999]
|
||||||
|
--10009 - 10009
|
||||||
|
putStrLn $ show $ bigSubtract [9,10] [9,10]
|
||||||
|
|
||||||
|
----Error cases
|
||||||
|
--putStrLn $ show $ bigSubtract [987] [0,1]
|
||||||
|
--putStrLn $ show $ bigSubtract [9] [456]
|
||||||
|
--putStrLn $ show $ bigSubtract [9] [10]
|
||||||
|
--putStrLn $ show $ bigSubtract [9,999,999,999] [10,999,999,999]
|
||||||
|
|
||||||
|
putStrLn "Multiplication"
|
||||||
|
--3 * 4
|
||||||
|
putStrLn $ show $ bigMultiply [3] [4]
|
||||||
|
--1987 * 0
|
||||||
|
putStrLn $ show $ bigMultiply [987,1] [0]
|
||||||
|
--3001074098 * 4
|
||||||
|
putStrLn $ show $ bigMultiply [98,74,1,3] [4]
|
||||||
|
--3001074098 * 493128456291
|
||||||
|
putStrLn $ show $ bigMultiply [98,74,1,3] [291,456,128,493]
|
||||||
|
|
||||||
|
putStrLn "Power Of"
|
||||||
|
--2^8
|
||||||
|
putStrLn $ show $ bigPowerOf [2] [8]
|
||||||
|
--1832^0
|
||||||
|
putStrLn $ show $ bigPowerOf [832,1] [0]
|
||||||
|
|
||||||
|
putStrLn "Others"
|
||||||
|
|
||||||
5
hw1/test.sh
Executable file
5
hw1/test.sh
Executable file
@@ -0,0 +1,5 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
runhaskell test.hs > output
|
||||||
|
runhaskell Calculator.hs < input >> output
|
||||||
|
diff output output_EXPECTED
|
||||||
|
|
||||||
Reference in New Issue
Block a user