zhaw-fup/Exercises/exercise-2/Solution.hs

220 lines
4.1 KiB
Haskell

import Data.List (sort)
--------------------
-- Exercise 1
--------------------
data Car = Car
{ model :: Model
, make :: Make
, year :: Integer
, color :: Color
, power :: Horsepower
} deriving (Show, Eq, Ord)
----------
-- a)
----------
newtype Model = Model String
deriving (Show, Eq, Ord)
newtype Make = Make String
deriving (Show, Eq, Ord)
data Color = RGB
{ r :: Integer
, g :: Integer
, b :: Integer
} deriving (Show, Eq, Ord)
type Horsepower = Integer
----------
-- b)
----------
ford = Car {
make = Make "Ford",
model = Model "Fiesta",
color = RGB {
r = 0xFF,
g = 0x00,
b = 0x00
},
power = 70,
year = 2017
}
ferrari = Car {
make = Make "Ferrari",
model = Model "Testarossa",
color = RGB 0x00 0xFF 0x00,
power = 27,
year = 1991
}
zoe = Car {
make = Make "Renault",
model = Model "Zoe",
color = RGB 0xFF 0xFF 0xFF,
power = 70,
year = 2023
}
sorted = sort [zoe, ferrari, ford]
-- >>> sorted
-- [Car {model = Model "Fiesta", make = Make "Ford", year = 2017, color = RGB {r = 255, g = 0, b = 0}, power = 70},Car {model = Model "Testarossa", make = Make "Ferrari", year = 1991, color = RGB {r = 0, g = 255, b = 0}, power = 27},Car {model = Model "Zoe", make = Make "Renault", year = 2023, color = RGB {r = 255, g = 255, b = 255}, power = 70}]
--
--------------------
-- Exercise 2
--------------------
data Tree a
= Node (Tree a) a (Tree a)
| Leaf a
----------
-- a)
----------
collect :: Tree a -> [a]
collect x =
case x of
Node a b c -> [b] ++ concat (map collect [a, c])
Leaf a -> [a]
----------
-- b)
----------
data PolyTree a =
PolyTree a [PolyTree a]
deriving (Show)
----------
-- c)
----------
tree =
PolyTree 1 [
PolyTree 2 [
PolyTree 5 [],
PolyTree 6 [],
PolyTree 7 []
],
PolyTree 3 [
PolyTree 8 []
]
]
-- >>> show tree
-- "PolyTree 1 [PolyTree 2 [PolyTree 5 [],PolyTree 6 [],PolyTree 7 []],PolyTree 3 [PolyTree 8 []]]"
--
--------------------
-- Exercise 3
--------------------
data NatNumber =
Z
| S NatNumber
deriving (Show)
eval :: NatNumber -> Integer
eval x =
case x of
Z -> 0
S a -> 1 + eval a
-- >>> Z
-- Z
--
-- >>> eval $ S $ S $ S Z
-- 3
--
uneval :: Integer -> NatNumber
uneval x
| x < 0 = error "negative numbers are not natural numbers"
| x == 0 = Z
| otherwise = S (uneval (x - 1))
-- >>> uneval (-1)
-- *** Exception: negative numbers are not natural numbers
-- CallStack (from HasCallStack):
-- error, called at /home/manuel/Documents/Repositories/zhaw-fup/Exercises/exercise-2/Solution.hs:133:15 in main:Main
--
-- >>> uneval 0
-- Z
--
-- >>> uneval 1
-- S Z
--
-- >>> uneval 3
-- S (S (S Z))
--
addNat :: NatNumber -> NatNumber -> NatNumber
addNat a b =
case (a, b) of
(Z, b) -> b
(S a, b) -> S (addNat a b)
-- >>> eval (addNat (uneval 7) (uneval 2))
-- 9
--
mulNat :: NatNumber -> NatNumber -> NatNumber
mulNat a b =
case (a, b) of
(Z, b) -> Z
(S a, b) -> addNat (mulNat a b) b
-- >>> eval (mulNat (uneval 3) (uneval 2))
-- 6
--
fact :: NatNumber -> NatNumber
fact x =
case x of
Z -> S Z
S a -> mulNat (S a) (fact a)
-- >>> eval (fact Z)
-- 1
--
-- >>> eval (fact (S (S Z)))
-- 2
--
--------------------
-- Exercise 4
--------------------
type Program = [(Integer, Integer)]
type Input = Integer
type Output = [Integer]
execute :: Program -> Input -> Output
execute program input =
reverse (internal program input [])
where
internal :: Program -> Input -> Output -> Output
internal [] input output = input:output
internal ((a,b):coefficients) input output
| mod (input * a) b == 0 =
internal program (div (input * a) b) (input:output)
| otherwise = internal coefficients input output
fibProgram :: Program
fibProgram =
[ (91,33)
, (11,13)
, (1,11)
, (399,34)
, (17,19)
, (1,17)
, (2,7)
, (187,5)
, (1,3)
]
-- Should evaluate to True
-- >>> sum (execute fibProgram 31250) == 26183978971946924
-- True
--