From 09f11f0e8b95ef318c9f05cdac2a9858547458b0 Mon Sep 17 00:00:00 2001 From: Yuri Tatishchev Date: Sat, 14 Feb 2026 19:57:27 -0800 Subject: [PATCH] hw1: init --- hw1/BigNum.hs | 89 +++++++++++++++++++++++++++++++++++++++++++++ hw1/Calculator.hs | 36 ++++++++++++++++++ hw1/Test.java | 5 +++ hw1/hw1.txt | 63 ++++++++++++++++++++++++++++++++ hw1/input | 7 ++++ hw1/output | 0 hw1/output_EXPECTED | 26 +++++++++++++ hw1/test.hs | 50 +++++++++++++++++++++++++ hw1/test.sh | 5 +++ 9 files changed, 281 insertions(+) create mode 100644 hw1/BigNum.hs create mode 100644 hw1/Calculator.hs create mode 100644 hw1/Test.java create mode 100644 hw1/hw1.txt create mode 100644 hw1/input create mode 100644 hw1/output create mode 100644 hw1/output_EXPECTED create mode 100644 hw1/test.hs create mode 100755 hw1/test.sh diff --git a/hw1/BigNum.hs b/hw1/BigNum.hs new file mode 100644 index 0000000..3de9087 --- /dev/null +++ b/hw1/BigNum.hs @@ -0,0 +1,89 @@ +{- + Name: + Class: CS 252 + Assigment: HW1 + Date: + Description: +-} + +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" diff --git a/hw1/Calculator.hs b/hw1/Calculator.hs new file mode 100644 index 0000000..aea26bf --- /dev/null +++ b/hw1/Calculator.hs @@ -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 + diff --git a/hw1/Test.java b/hw1/Test.java new file mode 100644 index 0000000..78b8458 --- /dev/null +++ b/hw1/Test.java @@ -0,0 +1,5 @@ +public class Test { + public void main(String[] args) { + System.out.println(999999999999999999999 * 2); + } +} diff --git a/hw1/hw1.txt b/hw1/hw1.txt new file mode 100644 index 0000000..ea0a436 --- /dev/null +++ b/hw1/hw1.txt @@ -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. + diff --git a/hw1/input b/hw1/input new file mode 100644 index 0000000..d9aa21b --- /dev/null +++ b/hw1/input @@ -0,0 +1,7 @@ +3 + 4 +9 * 7 +2 ^ 8 +400000000000000000001 * 2 +999999999999999999999 - 999999999999999999998 +483971285601 * 123448796045 + diff --git a/hw1/output b/hw1/output new file mode 100644 index 0000000..e69de29 diff --git a/hw1/output_EXPECTED b/hw1/output_EXPECTED new file mode 100644 index 0000000..d65fb42 --- /dev/null +++ b/hw1/output_EXPECTED @@ -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 diff --git a/hw1/test.hs b/hw1/test.hs new file mode 100644 index 0000000..acde9b9 --- /dev/null +++ b/hw1/test.hs @@ -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" + diff --git a/hw1/test.sh b/hw1/test.sh new file mode 100755 index 0000000..404f98d --- /dev/null +++ b/hw1/test.sh @@ -0,0 +1,5 @@ +#!/bin/sh +runhaskell test.hs > output +runhaskell Calculator.hs < input >> output +diff output output_EXPECTED +