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