hw1: init

This commit is contained in:
2026-02-14 19:57:27 -08:00
parent 52e7e119b6
commit 09f11f0e8b
9 changed files with 281 additions and 0 deletions

89
hw1/BigNum.hs Normal file
View 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
View 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
View File

@@ -0,0 +1,5 @@
public class Test {
public void main(String[] args) {
System.out.println(999999999999999999999 * 2);
}
}

63
hw1/hw1.txt Normal file
View 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
View File

@@ -0,0 +1,7 @@
3 + 4
9 * 7
2 ^ 8
400000000000000000001 * 2
999999999999999999999 - 999999999999999999998
483971285601 * 123448796045

0
hw1/output Normal file
View File

26
hw1/output_EXPECTED Normal file
View 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
View 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
View File

@@ -0,0 +1,5 @@
#!/bin/sh
runhaskell test.hs > output
runhaskell Calculator.hs < input >> output
diff output output_EXPECTED