forked from steger/pr3-sose2026
Merge remote-tracking branch 'upstream/main'
commit
6d96eb957d
|
|
@ -0,0 +1,10 @@
|
|||
FROM ubuntu:24.04
|
||||
|
||||
RUN apt-get update && apt-get install -y build-essential curl libffi-dev libffi8ubuntu1 libgmp-dev libgmp10 libncurses-dev
|
||||
RUN curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh
|
||||
ENV PATH="$PATH:/root/.ghcup/bin"
|
||||
RUN ghcup install hls
|
||||
RUN apt-get update && apt-get install -y git zlib1g-dev
|
||||
RUN cabal update && cabal install ghci-dap haskell-debug-adapter
|
||||
RUN cabal update && cabal install --lib HUnit
|
||||
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"name": "Haskell Dev Container",
|
||||
"build": {
|
||||
"dockerfile": "Dockerfile"
|
||||
},
|
||||
"customizations": {
|
||||
"vscode": { "extensions": [
|
||||
"haskell.haskell",
|
||||
"phoityne.phoityne-vscode"
|
||||
]}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"editor.formatOnSave": true
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
|
||||
{
|
||||
// Automatically created by phoityne-vscode extension.
|
||||
|
||||
"version": "2.0.0",
|
||||
"presentation": {
|
||||
"reveal": "always",
|
||||
"panel": "new"
|
||||
},
|
||||
"tasks": [
|
||||
{
|
||||
// F7
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": false
|
||||
},
|
||||
"label": "haskell build",
|
||||
"type": "shell",
|
||||
"command": "cabal configure && cabal build"
|
||||
},
|
||||
{
|
||||
// F6
|
||||
"group": "build",
|
||||
"type": "shell",
|
||||
"label": "haskell clean & build",
|
||||
"command": "cabal clean && cabal configure && cabal build"
|
||||
},
|
||||
{
|
||||
// F8
|
||||
"group": {
|
||||
"kind": "test",
|
||||
"isDefault": true
|
||||
},
|
||||
"type": "shell",
|
||||
"label": "haskell test",
|
||||
"command": "cabal test"
|
||||
},
|
||||
{
|
||||
// F6
|
||||
"isBackground": true,
|
||||
"type": "shell",
|
||||
"label": "haskell watch",
|
||||
"command": "stack build --test --no-run-tests --file-watch"
|
||||
}
|
||||
|
||||
,
|
||||
{
|
||||
// Build a single Haskell file
|
||||
"type": "shell",
|
||||
"label": "haskell build single file",
|
||||
"command": "ghc",
|
||||
"args": [ "${file}" ],
|
||||
"problemMatcher": [],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
}
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
# Build
|
||||
|
||||
`ghc hello-world.hs`
|
||||
|
||||
# Run
|
||||
|
||||
`runghc hello-world.hs`
|
||||
|
||||
# Run interactively
|
||||
```
|
||||
ghci
|
||||
ghci> :load hello-world.hs
|
||||
ghci> main
|
||||
```
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
main :: IO ()
|
||||
main = putStrLn "Hello, World!"
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
# Haskell - Expressions
|
||||
|
||||
The following illustrates some haskell basics. It can be reproduced using `ghci`.
|
||||
|
||||
## Types, Literals, and Constants along with Arithmetic and Boolean Operations
|
||||
|
||||
Expression | Type (:t) | Value | Comment
|
||||
--- | --- | --- | --------
|
||||
`2` | `Num a => a` | `2` |
|
||||
`2.03` | `Fractional a => a` | `2.03` |
|
||||
`'c'` | `Char` | `'c'`
|
||||
`"hallo"` | `String` | `"hallo"` |
|
||||
`True` | `Bool` | `True` |
|
||||
`x=5` | `Num a => a` | `5` | Constant named `x`
|
||||
`2 + 3` | `Num a => a` | `5` | Similar `-,*,^`
|
||||
`2 / 3` | `Fractional a => a` | `0.6666666666666666` |
|
||||
`1 > 2` | `Bool` | `False` | Similar `<, <=, >=, ==, /=`
|
||||
`True && False` | `Bool` | `False` | Similar `\|\|,not`
|
||||
`((2+3)*5 > 1) \|\| not (1 > 2)` | `Bool` | `True` | Right part is not evaluated due to lazy evaluation
|
||||
|
||||
## Unary Functions
|
||||
|
||||
Expression | Type (:t) | Value | Comment
|
||||
--- | --- | --- | --------
|
||||
`sqrt(4)` | `Floating a => a` | `2.0` |
|
||||
`sqrt 4` | `Floating a => a` | `2.0` | Similar `abs,negate,signum,recip`
|
||||
`sqrt` | `Floating a => a -> a` | |
|
||||
`sqrt 3^2 + 4^2` | `Floating a => a` | `19.0` |
|
||||
`sqrt (3^2 + 4^2)` | `Floating a => a` | `5.0` |
|
||||
`negate(sqrt (3^2 + 4^2))` | `Floating a => a` | `-5.0` |
|
||||
`negate $ sqrt (3^2 + 4^2)` | `Floating a => a`| `-5.0` | Function **application** operator `$`
|
||||
`(negate . sqrt) (3^2 + 4^2)`| `Floating a => a`| `-5.0` | Function **composition** operator `.` Reads `negate` **after** `negate . sqrt` |
|
||||
`(negate . length) "hallo"` | `Int` | `-5` |
|
||||
`negatedRoot = negate . sqrt` | `Floating c => c -> c` | | Constant named `negatedRoot`
|
||||
|
||||
## Binary Functions
|
||||
|
||||
Expression | Type (:t) | Value | Comment
|
||||
--- | --- | --- | --------
|
||||
`div 8 4` | `Integral a => a` | `2` | Similar `mod,gcd,lcm,not`
|
||||
``8 `div` 4`` | `Integral a => a` | `2` | **Infix** notation using backticks
|
||||
`8 + 4` | `Num a => a` | `12` | `-,*,^,<, <=, >=, ==, /=`
|
||||
`(+) 8 4` | `Num a => a` | `12` | **Prefix** notation using parenthesis
|
||||
`div` | `Integral a => a -> a -> a` | | **Currying** represents multi-argument functions as a chain of single-argument functions |
|
||||
`div 8` | `Integral a => a -> a` | | binds the **first** argument; Similar `(8/),(8*),(8+),(8-)` |
|
||||
`div8bySomething = div 8` | `Integral a => a -> a` | |
|
||||
`div8bySomething 4` | `Integral a => a` | `2` |
|
||||
`uncurry div` | `Integral c => (c, c) -> c` | | accepts a single tuple argument
|
||||
`uncurry div (8,4)` | `Integral c => c` | `2` |
|
||||
`uncurry` | `(a -> b -> c) -> (a, b) -> c`| |
|
||||
`` (`div` 4) `` | `Integral a => a -> a` | | **Sectioning** binds the **second** argument of infix functions; Similar `(/8),(*8),(+8),(-8)` |
|
||||
``divSomethingBy4 = (`div` 4)`` | `Integral a => a -> a` | |
|
||||
`divSomethingBy4 8` | `Integral a => a` | `2` |
|
||||
`const` | `a -> b -> a` | |
|
||||
`const 8` | `Num a => b -> a` | | function that ignores the input and always returns 8
|
||||
`const 8 4` | `Num a => a` | `8` |
|
||||
|
||||
## Tuples
|
||||
|
||||
Expression | Type (:t) | Value | Comment
|
||||
--- | --- | --- | --------
|
||||
`(1, 2)` | `(Num a, Num b) => (a, b)` | `(1, 2)` |
|
||||
`(1, "hello", True)` | `(Num a => (a, String, Bool)` | `(1, "hello", True)` |
|
||||
`fst (1, 2)` | `Num a => a` | `1` |
|
||||
`snd (1, 2)` | `Num b => b` | `2` |
|
||||
`(,) 1 2` | `Num a => a -> a -> (a, a)` | `(1, 2)` |
|
||||
|
||||
## Strings
|
||||
|
||||
Expression | Type (:t) | Value | Comment
|
||||
--- | --- | --- | --------
|
||||
`"hello" ++ " world"` | `String` | `"hello world"` | String concatenation
|
||||
`length "hello"` | `Int` | `5` | Length of the string
|
||||
`null ""` | `Bool` | `True` | Checks if the string is empty
|
||||
|
||||
## Control Structures
|
||||
|
||||
Expression | Type (:t) | Value | Comment
|
||||
--- | --- | --- | --------
|
||||
`if 10/2==5 then "five" else "something else"` | `String` | `"five"` |
|
||||
`case 1 of { 1 -> "small"; 2 -> "medium"; _ -> "large"}` | `String` | `"small"` | patterns are overlapping
|
||||
`(let x = 5*2 in (x * 2,x /2))` | `(Fractional b, Num a) => (a, b)` | `(20,5.0)` |
|
||||
|
||||
## Lists
|
||||
|
||||
Expression | Type (:t) | Value | Comment
|
||||
--- | --- | --- | --------
|
||||
`[]` | `[a]` | `[]` |
|
||||
`1:7:4:[]` | `Num a => [a]` | `[1,7,4]` | actual construction of a list
|
||||
`[1,7,4]` | `Num a => [a]` | `[1,7,4]` |
|
||||
`8 : [1,7,4]` | `Num a => [a]` | `[8,1,7,4]` | **cons** operator, short for construct
|
||||
`[1,7,4]` | `[Num a] => [a]` | `[1,7,4]` |
|
||||
`(++)` | `[a] -> [a] -> [a]` | |
|
||||
`[1,7,4] ++ [8]` | `Num a => [a]` | `[1,7,4,8]` |
|
||||
`[1,7,4] !! 2` | `Num a => [a]` | `4` |
|
||||
`(!!)` | `[a] -> Int -> a` | |
|
||||
`head [1,7,4]` | `Num a => a` | `1` | Similar `last`
|
||||
`tail [1,7,4]` | `[Num a] => [a]` | `[7,4]` | Similar `init`
|
||||
`length [1,7,4]` | `Int` | `3` |
|
||||
`null []` | `Bool` | `True` |
|
||||
`reverse [1,7,4]` | `[Num a] => [a]` | `[4,7,1]` | Similar `Data.List.sort`
|
||||
`take 2 [1,7,4]` | `[Num a]=>[a]` | `[1,7]` | Similar `drop`
|
||||
`take` | `Int -> [a] -> [a]` | |
|
||||
`sum [1,7,4]` | `Num a=>a` | `12` | Similar `product,maximum,minimum,length`
|
||||
`foldl (-) 0 [1,7,4]` | `Num a => a` | `-12` | `(((0-1)-7)-4)`
|
||||
`foldl` | `Foldable t => (b -> a -> b) -> b -> t a -> b` | |
|
||||
`foldr (-) 0 [1,7,4]` | `Num a => a` | `-2` | `(1-(7-(4-0)))`
|
||||
`elem 7 [1,7,4]` | `Bool` | `True` |
|
||||
`all even [1,7,4]` | `Bool` | `False` | Similar `any`
|
||||
`filter even [1,7,4]` | `[Integral a] => [a]` | `[1,7,4]` | Similar `odd,(>1),(/=3)`
|
||||
`(length . filter (>1) ) [1,7,4]` | `Int` | `2` |
|
||||
`Data.List.partition (>1) [1,7,4]` | `(Ord a, Num a) => ([a], [a])` | `([7,4],[1])`
|
||||
`zip [1,7,4] ["one","seven","four","eight"]` | `Num a => [(a, String)]` | `[(1,"one"),(7,"seven"),(4,"four")]` | truncating to the shorter list
|
||||
`Data.List.sortOn fst $ zip [1,7,4] ["one", "seven", "four"]` | `(Ord b, Num b) => [(b, String)]` | `[(1,"one"),(4,"four"),(7,"seven")]`
|
||||
`Data.List.sort ["one","seven","four","eight"]` | `[String]` | `["eight","four","one","seven"]`
|
||||
`reverse $ Data.List.sort ["one","seven","four","eight"]` | `[String]` | `["seven","one","four","eight"]`
|
||||
`Data.List.sortBy compare ["one","seven","four","eight"]` | `[String]` | `["eight","four","one","seven"]`
|
||||
`Data.List.sortBy (flip compare) ["one","seven","four","eight"]` | `[String]` | `["seven","one","four","eight"]`
|
||||
`Data.List.sortBy (curry( (uncurry compare) . (uncurry(Control.Arrow.***) (length,length)))) ["one","seven","four","eight","ten"]` | `[String]` | `["one","ten","four","seven","eight"]` |
|
||||
`Data.List.sortBy (Data.Ord.comparing length) ["one","seven","four","eight","ten"]` | `[String]` | `["one","ten","four","seven","eight"]`
|
||||
`map (+1) [1,7,4]` | `Num a => [a]` | `[2,8,5]` |
|
||||
`map length ["one", "seven", "four"]` | `[Int]` | `[3,5,4]` |
|
||||
`map (negate . abs) [1,-7,4]` | `Num a => [a]` | `[-1,-7,-4]` |
|
||||
`map even [1,7,4]` | `[Bool]` | `[False,False,True]` |
|
||||
`[1..5]` | `(Num a, Enum a) => [a]` | `[1,2,3,4,5]` |
|
||||
`[1,3..9]` | `(Num a, Enum a) => [a]` | `[1,3,5,7,9]` |
|
||||
`[1..]` | `(Num a, Enum a) => [a]` | `[1,2,3,4,5,...]` | infinite sequence
|
||||
`take 4 [10..]` | `(Num a, Enum a) => [a]` | `[1,2,3,4]` | laziness in action
|
||||
`[x*2 \| x <- [1..5]]` | `[Num a] => [a]` | `[2, 4, 6, 8, 10]` | List comprehension
|
||||
``[x*2 \| x <- [1..5], x `mod` 3 == 0]`` | `[Num a] => [a]` | `[6]` |
|
||||
`[ (a,b,c) \| c <- [1..10], b <- [1..c], a <- [1..b], a^2 + b^2 == c^2]` | `(Num c, Eq c, Enum c) => [(c, c, c)]` | `[(3,4,5),(6,8,10)]`
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
# Assignment
|
||||
|
||||
You are provided with:
|
||||
|
||||
1. A vector of names
|
||||
2. A vector of ages
|
||||
|
||||
Your task is to compute a list containing the UPPERCASE names of the two oldest persons whose names ends with an "a". The result shall be sorted by alphabet.
|
||||
|
||||
Complete the corresponding unit test in the file `02-list-operations/list-operations.hs`.
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-}
|
||||
|
||||
{-# HLINT ignore "Avoid reverse" #-}
|
||||
{-# HLINT ignore "Use void" #-}
|
||||
|
||||
import Data.Char (toUpper)
|
||||
import Data.List (sort, sortOn)
|
||||
import Test.HUnit
|
||||
|
||||
names = ["Oliver", "Emma", "Liam", "Ava", "Noah", "Sophia", "James", "Mia", "Elijah", "Isabella"]
|
||||
|
||||
ages = [25, 30, 22, 29, 35, 28, 40, 26, 33, 31]
|
||||
|
||||
-- we are looking for the UPPERCASE names of the two oldest persons whose names ends with an a sorted alphabetically"
|
||||
|
||||
extractedNames = []
|
||||
|
||||
test1 = Test.HUnit.TestCase (assertEqual "ExtractedNames" ["EMMA", "ISABELLA"] extractedNames)
|
||||
|
||||
tests = TestList [test1]
|
||||
|
||||
main :: IO ()
|
||||
main = runTestTT test1 >> return ()
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
|
||||
-- single parameter
|
||||
|
||||
-- two parameters
|
||||
|
||||
-- ============= pattern matching =================
|
||||
|
||||
-- ============= guards =================
|
||||
|
||||
-- ============= recursive algorithms =================
|
||||
|
||||
-- ============= recursive list algorithms =================
|
||||
|
||||
-- ============= merge sort =================
|
||||
|
||||
-- =========== Filter all numbers that can be divided by 10 ===========
|
||||
|
||||
-- ========================== standard deviation using lambdas =====================
|
||||
-- The standard deviation is a measure of the amount of variation or dispersion of a set of values.
|
||||
-- It is defined as the square root of the average of the squared differences from the mean.
|
||||
--
|
||||
-- Formula:
|
||||
-- σ = sqrt( (1/N) * Σ (xi - μ)^2 )
|
||||
-- where:
|
||||
-- - σ is the standard deviation,
|
||||
-- - N is the number of values,
|
||||
-- - xi represents each value,
|
||||
-- - μ is the mean of the values.
|
||||
|
||||
stddev seq = 0
|
||||
|
||||
-- ======================= order list of strings by length =================
|
||||
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
# Assignment - Tower of Hanoi {.alert}
|
||||
|
||||
The Tower of Hanoi is a classic mathematical puzzle that involves three rods and a number of disks of different sizes.
|
||||
The puzzle starts with all the disks stacked in ascending order of size on one rod (the source rod), with the smallest disk on top.
|
||||
The objective is to move the entire stack to another rod (the destination rod), following these rules:
|
||||
|
||||
1. Only one disk can be moved at a time.
|
||||
2. Each move consists of taking the top disk from one rod and placing it on another rod.
|
||||
3. No disk may be placed on top of a smaller disk.
|
||||
|
||||
**Your task:**
|
||||
|
||||
Implement a function that solves the Tower of Hanoi problem for `n` disks. The rods are represented as Chars (e.g. 'a','b','c'). The result shall be a list of moving instructions. Add your implementation to the file `04-hanoi/hanoi.hs` that already contains a test and a helper function that creates the move instruction for a single move.
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-}
|
||||
|
||||
{-# HLINT ignore "Use void" #-}
|
||||
import Test.HUnit
|
||||
|
||||
-- some helper function that describes a single move
|
||||
move :: Int -> Char -> Char -> String
|
||||
move n src dst = "move disk " ++ show n ++ " from " ++ [src] ++ " to " ++ [dst]
|
||||
|
||||
-- transfers a number of disks (the Int) from a source (the first Char) rod to a destination (the second Char) rod via a temp (the third char) rod
|
||||
-- returns a list of required operations
|
||||
hanoi :: (Int,Char,Char,Char) -> [String]
|
||||
|
||||
--TODO: implement here
|
||||
|
||||
-- Source, Destination, Temp
|
||||
hanoiTests :: [((Int, Char, Char, Char), [String])]
|
||||
hanoiTests =
|
||||
[ ( (1, 'a', 'c', 'b'),
|
||||
[ "move disk 1 from a to c"
|
||||
]
|
||||
),
|
||||
( (1, 'b', 'a', 'c'),
|
||||
[ "move disk 1 from b to a"
|
||||
]
|
||||
),
|
||||
( (2, 'a', 'c', 'b'),
|
||||
[ "move disk 1 from a to b",
|
||||
"move disk 2 from a to c",
|
||||
"move disk 1 from b to c"
|
||||
]
|
||||
),
|
||||
( (3, 'a', 'c', 'b'),
|
||||
[ "move disk 1 from a to c",
|
||||
"move disk 2 from a to b",
|
||||
"move disk 1 from c to b",
|
||||
"move disk 3 from a to c",
|
||||
"move disk 1 from b to a",
|
||||
"move disk 2 from b to c",
|
||||
"move disk 1 from a to c"
|
||||
]
|
||||
),
|
||||
( (4, 'a', 'c', 'b'),
|
||||
[ "move disk 1 from a to b",
|
||||
"move disk 2 from a to c",
|
||||
"move disk 1 from b to c",
|
||||
"move disk 3 from a to b",
|
||||
"move disk 1 from c to a",
|
||||
"move disk 2 from c to b",
|
||||
"move disk 1 from a to b",
|
||||
"move disk 4 from a to c",
|
||||
"move disk 1 from b to c",
|
||||
"move disk 2 from b to a",
|
||||
"move disk 1 from c to a",
|
||||
"move disk 3 from b to c",
|
||||
"move disk 1 from a to b",
|
||||
"move disk 2 from a to c",
|
||||
"move disk 1 from b to c"
|
||||
]
|
||||
)
|
||||
]
|
||||
|
||||
hanoiTestCases :: [Test]
|
||||
hanoiTestCases = map (\(input, expected) -> TestCase (assertEqual ("hanoi " ++ show input) expected (hanoi input))) hanoiTests
|
||||
|
||||
tests :: Test
|
||||
tests = TestList hanoiTestCases
|
||||
|
||||
main :: IO ()
|
||||
main = runTestTT tests >> return ()
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
-- data Entity =
|
||||
|
||||
-- data Shape =
|
||||
|
||||
-- area :: Shape a -> a
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
# Complex Numbers
|
||||
|
||||
## Assignment
|
||||
Define a new type `Complex` that allows arithmetic calculations in an intuitive fashion. See below for the rules that shall be implemented. Incrementally make sure that all unit tests in `06-complex/complex.hs` are passed.
|
||||
|
||||
## Complex Numbers
|
||||
|
||||
Complex numbers are numbers of the form: $z = a + bi$
|
||||
|
||||
- **`a`**: The real part of the complex number.
|
||||
- **`b`**: The imaginary part of the complex number.
|
||||
- **`i`**: The imaginary unit, where $i^2 = -1$.
|
||||
|
||||
Complex numbers are used in mathematics, physics, and engineering to extend the real number system and solve equations that have no real solutions, such as $x^2 + 1 = 0$.
|
||||
|
||||
Complex numbers are often represented in both rectangular form $a + bi$ and polar/exponential form $r e^{i\theta}$.
|
||||
|
||||
|
||||
## Rules for Computing with Complex Numbers
|
||||
|
||||
### 1. **Addition and Subtraction**
|
||||
- Add or subtract the real and imaginary parts separately.
|
||||
- Rule:
|
||||
$(a + bi) + (c + di) = (a + c) + (b + d)i$
|
||||
$(a + bi) - (c + di) = (a - c) + (b - d)i$
|
||||
|
||||
**Examples**:
|
||||
1. $(2 + 3i) + (4 + 5i) = 6 + 8i$
|
||||
2. $(0 + 3i) + (2 + 0i) = 2 + 3i$
|
||||
3. $(7 + 2i) - (3 + 6i) = 4 - 4i$
|
||||
4. $(5 + 4i) - (1 + 2i) = 4 + 2i$
|
||||
|
||||
### 2. **Multiplication**
|
||||
- Use the distributive property and the rule $i^2 = -1$.
|
||||
- Rule:
|
||||
$(a + bi)(c + di) = (ac - bd) + (ad + bc)i$
|
||||
|
||||
**Examples**:
|
||||
1. $(1 + 2i)(3 + 4i) = -5 + 10i$
|
||||
2. $(2 + 3i)(1 - i) = 5 + i$
|
||||
3. $(4 + i)(2 - 3i) = 11 - 10i$
|
||||
4. $(3 + 2i)(3 + 2i) = 5 + 12i$
|
||||
|
||||
### 3. **Division**
|
||||
- Multiply numerator and denominator by the conjugate of the denominator.
|
||||
- Rule:
|
||||
$\frac{a + bi}{c + di} = \frac{(a + bi)(c - di)}{(c + di)(c - di)}$
|
||||
Simplifies to:
|
||||
$\frac{(ac + bd) + (bc - ad)i}{c^2 + d^2}$
|
||||
|
||||
**Examples**:
|
||||
1. $\frac{1 + i}{1 - i} = 0 + 1i$
|
||||
2. $\frac{3 + 2i}{4 + 3i} = \frac{18 + i}{25} = 0.72 - 0.04i$
|
||||
3. $\frac{2 + i}{1 + i} = \frac{3 - i}{2} = 1.5 - 0.5i$
|
||||
|
||||
### 4. **Complex Conjugate**
|
||||
- The conjugate of $a + bi$ is $a - bi$, used for simplifications and magnitude calculation.
|
||||
|
||||
**Examples**:
|
||||
1. Conjugate of $3 + 4i$ is $3 - 4i$.
|
||||
2. Conjugate of $5 - i$ is $5 + i$.
|
||||
3. Conjugate of $-2 + 3i$ is $-2 - 3i$.
|
||||
|
||||
### 5. **Magnitude (Modulus)**
|
||||
- The magnitude is the distance from the origin in the complex plane.
|
||||
- Rule: $|a + bi| = \sqrt{a^2 + b^2}$
|
||||
|
||||
**Examples**:
|
||||
1. $|3 + 4i| = \sqrt{3^2 + 4^2} = 5$
|
||||
2. $|1 - i| = \sqrt{1^2 + (-1)^2} = \sqrt{2}$
|
||||
3. $|0 + 5i| = \sqrt{0^2 + 5^2} = 5$
|
||||
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-}
|
||||
|
||||
{-# HLINT ignore "Use void" #-}
|
||||
import Test.HUnit
|
||||
|
||||
data Complex a = TODO
|
||||
|
||||
instance (Show a, Num a, Eq a) => Show (Complex a) where
|
||||
-- show :: (Show a, Num a, Eq a) => Complex a -> String
|
||||
-- TODO
|
||||
|
||||
instance (Num a, Floating a) => Num (Complex a) where
|
||||
-- (+) :: (Num a, Floating a) => Complex a -> Complex a -> Complex a
|
||||
-- (*) :: (Num a, Floating a) => Complex a -> Complex a -> Complex a
|
||||
-- TODO
|
||||
-- abs (Complex re im) = TODO
|
||||
-- signum (Complex re im) = TODO
|
||||
-- fromInteger n = TODO
|
||||
-- negate :: (Num a, Floating a) => Complex a -> Complex a
|
||||
-- negate (Complex re im) = Complex (negate re) (negate im)
|
||||
|
||||
instance (Fractional a, Floating a) => Fractional (Complex a) where
|
||||
-- fromRational r = TODO
|
||||
-- recip (Complex re im) = TODO
|
||||
|
||||
-- (Complex re1 im1) / (Complex re2 im2) = TODO
|
||||
|
||||
-- conj :: Num a => Complex a -> Complex a
|
||||
-- TODO
|
||||
|
||||
tests :: Test
|
||||
tests =
|
||||
TestList
|
||||
[ Test.HUnit.TestCase (assertEqual "Show 1+2i" "1+2i" (show $ Complex 1 2)),
|
||||
Test.HUnit.TestCase (assertEqual "Show 1" "1" (show $ Complex 1 0)),
|
||||
Test.HUnit.TestCase (assertEqual "Show i" "i" (show i)),
|
||||
Test.HUnit.TestCase (assertEqual "Show 5i" "5i" (show $ Complex 0 5)),
|
||||
Test.HUnit.TestCase (assertEqual "Show 0" "0" (show $ Complex 0 0)),
|
||||
Test.HUnit.TestCase (assertEqual "Compare Equal" True (Complex 2 3 == Complex 2 3)),
|
||||
Test.HUnit.TestCase (assertEqual "Compare Real Not Equal" False (Complex 1 3 == Complex 2 3)),
|
||||
Test.HUnit.TestCase
|
||||
(assertEqual "Compare Imag Not Equal" False (Complex 2 4 == Complex 2 3)),
|
||||
Test.HUnit.TestCase
|
||||
(assertEqual "Compare Not Equal" False (Complex 2 3 /= Complex 2 3)),
|
||||
Test.HUnit.TestCase
|
||||
( assertEqual
|
||||
"Addition 1"
|
||||
(Complex 6.0 8.0)
|
||||
(Complex 2.0 3.0 + Complex 4.0 5.0)
|
||||
),
|
||||
Test.HUnit.TestCase
|
||||
( assertEqual
|
||||
"Addition 2"
|
||||
(Complex 2.0 3.0)
|
||||
(Complex 0.0 3.0 + Complex 2.0 0.0)
|
||||
),
|
||||
Test.HUnit.TestCase
|
||||
( assertEqual
|
||||
"Subtraction 1"
|
||||
(Complex 4.0 (-4.0))
|
||||
(Complex 7.0 2.0 - Complex 3.0 6.0)
|
||||
),
|
||||
Test.HUnit.TestCase
|
||||
( assertEqual
|
||||
"Subtraction 2"
|
||||
(Complex 4.0 2.0)
|
||||
(Complex 5.0 4.0 - Complex 1.0 2.0)
|
||||
),
|
||||
Test.HUnit.TestCase
|
||||
( assertEqual
|
||||
"Negation"
|
||||
(Complex (-7.0) (-2.0))
|
||||
(negate (Complex 7.0 2.0))
|
||||
),
|
||||
Test.HUnit.TestCase
|
||||
( assertEqual
|
||||
"Multiplication 1"
|
||||
(Complex (-5.0) 10.0)
|
||||
(Complex 1.0 2.0 * Complex 3.0 4.0)
|
||||
),
|
||||
Test.HUnit.TestCase
|
||||
( assertEqual
|
||||
"Multiplication 2"
|
||||
(Complex 5.0 1.0)
|
||||
(Complex 2.0 3.0 * Complex 1.0 (-1.0))
|
||||
),
|
||||
Test.HUnit.TestCase
|
||||
( assertEqual
|
||||
"Multiplication 3"
|
||||
(Complex 11.0 (-10.0))
|
||||
(Complex 4.0 1.0 * Complex 2.0 (-3.0))
|
||||
),
|
||||
Test.HUnit.TestCase
|
||||
( assertEqual
|
||||
"Multiplication 4"
|
||||
(Complex 5.0 12.0)
|
||||
(Complex 3.0 2.0 * Complex 3.0 2.0)
|
||||
),
|
||||
Test.HUnit.TestCase
|
||||
( assertEqual
|
||||
"Magnitude 1"
|
||||
(Complex 5.0 0.0)
|
||||
(abs (Complex 3.0 4.0))
|
||||
),
|
||||
Test.HUnit.TestCase
|
||||
( assertEqual
|
||||
"Magnitude 2"
|
||||
(Complex (sqrt 2.0) 0.0)
|
||||
(abs (Complex 1.0 (-1.0)))
|
||||
),
|
||||
Test.HUnit.TestCase
|
||||
( assertEqual
|
||||
"Magnitude 3"
|
||||
(Complex 5.0 0.0)
|
||||
(abs (Complex 0.0 5.0))
|
||||
),
|
||||
TestCase (assertEqual "Conjugate of 3+4i" (Complex 3 (-4)) (conj (Complex 3 4))),
|
||||
TestCase (assertEqual "Conjugate of 5-i" (Complex 5 1) (conj (Complex 5 (-1)))),
|
||||
TestCase (assertEqual "Conjugate of -2+3i" (Complex (-2) (-3)) (conj (Complex (-2) 3)))
|
||||
]
|
||||
|
||||
main :: IO ()
|
||||
main = runTestTT tests >> return ()
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
import System.IO
|
||||
import Text.Read (readMaybe)
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
# Assignment - Statistics
|
||||
|
||||
The file `08-statistics/data.csv` contains random data of students. It consists of the following columns:
|
||||
|
||||
- first name
|
||||
- last name
|
||||
- study subject
|
||||
|
||||
The rest of the columns -- and that number may vary -- contain points for different tasks. The first row is a header.
|
||||
|
||||
Your task is to Write a program that reads a filename from standard input. The corresponding csv-file shall be parsed and then the following statistics shall be computed and printed to standard output:
|
||||
|
||||
- the best student, i.e. the student with the most accumulated points (name and points shall be printed)
|
||||
- the average points of all rows for each subject (subject and average points shall be printed in ascending order)
|
||||
|
||||
Implement your solution in the file `08-statistics/statistics.hs` and upload the file to moodle.
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
First Name,Last Name,Subject,Task1,Task2,Task3,Task4,Task5
|
||||
Alice,Johnson,IB,87,45,68,92,33
|
||||
Bob,Smith,CSB,56,79,42,88,12
|
||||
Charlie,Williams,IMB,73,94,35,64,89
|
||||
David,Brown,UIB,41,59,77,29,83
|
||||
Emma,Jones,IB,99,21,48,75,56
|
||||
Frank,Garcia,CSB,32,81,94,55,23
|
||||
Grace,Miller,IMB,74,53,61,95,39
|
||||
Henry,Davis,UIB,90,40,28,76,65
|
||||
Isabella,Rodriguez,IB,57,86,72,49,100
|
||||
Jack,Martinez,CSB,64,31,59,97,14
|
||||
Liam,Hernandez,IMB,85,67,50,78,41
|
||||
Mia,Lopez,UIB,44,92,33,56,81
|
||||
Noah,Gonzalez,IB,68,39,74,82,47
|
||||
Olivia,Wilson,CSB,95,20,62,53,34
|
||||
Paul,Anderson,IMB,29,88,49,31,77
|
||||
Sophia,Thomas,UIB,81,56,93,42,69
|
||||
Ethan,Moore,IB,47,77,65,59,92
|
||||
Zoe,Taylor,CSB,38,95,40,70,58
|
||||
Lucas,Harris,IMB,99,45,83,62,37
|
||||
Ava,Clark,UIB,53,66,91,85,29
|
||||
Benjamin,Walker,IB,71,58,80,34,61
|
||||
Chloe,Hall,CSB,76,23,67,47,94
|
||||
Daniel,Allen,IMB,39,82,55,90,73
|
||||
Ella,Young,UIB,86,32,99,60,25
|
||||
James,King,IB,42,75,48,93,57
|
||||
Madison,Wright,CSB,63,54,72,51,88
|
||||
Nathan,Scott,IMB,91,37,79,68,45
|
||||
Emma,Green,UIB,50,89,31,77,61
|
||||
Jacob,Baker,IB,74,69,58,46,97
|
||||
Emily,Adams,CSB,88,41,66,79,30
|
||||
Samuel,Nelson,IMB,33,85,92,40,50
|
||||
Sophia,Carter,UIB,69,47,71,58,94
|
||||
Alexander,Mitchell,IB,57,98,36,61,82
|
||||
Victoria,Perez,CSB,92,28,64,73,49
|
||||
William,Roberts,IMB,45,76,89,55,31
|
||||
Ella,Turner,UIB,78,59,41,96,68
|
||||
Daniel,Phillips,IB,60,32,85,71,43
|
||||
Natalie,Campbell,CSB,55,74,99,28,79
|
||||
Mason,Parker,IMB,93,50,39,82,66
|
||||
Hannah,Evans,UIB,48,69,57,95,22
|
||||
Christopher,Edwards,IB,90,88,34,53,72
|
||||
Lucy,Collins,CSB,31,46,81,77,56
|
||||
Gabriel,Stewart,IMB,65,79,62,90,44
|
||||
Avery,Morris,UIB,80,23,47,36,97
|
||||
Ryan,Ross,IB,58,71,83,45,74
|
||||
Sophie,Reed,CSB,99,33,60,81,51
|
||||
Isaac,Adams,IMB,42,92,30,57,85
|
||||
Leah,Bennett,UIB,76,64,55,89,39
|
||||
Tyler,Barnes,IB,67,40,78,95,20
|
||||
Scarlett,Morgan,CSB,34,84,91,47,53
|
||||
John,White,IMB,89,25,72,69,98
|
||||
Eleanor,James,UIB,54,58,49,87,62
|
||||
Caleb,Wood,IB,31,100,37,46,81
|
||||
Amelia,Hill,CSB,73,45,79,66,50
|
||||
Julian,Scott,IMB,97,34,89,22,76
|
||||
Charlotte,Bryant,UIB,63,92,41,88,32
|
||||
Isaiah,Mitchell,IB,81,68,52,39,74
|
||||
Lily,Foster,CSB,56,97,44,85,29
|
||||
Elijah,Howard,IMB,70,61,36,90,99
|
||||
Peyton,Washington,UIB,49,82,67,31,75
|
||||
Xavier,Cook,IB,88,55,93,42,64
|
||||
Nora,Bailey,CSB,37,72,57,96,47
|
||||
Owen,Rivera,IMB,59,30,80,77,91
|
||||
Harper,Cooper,UIB,50,99,33,28,65
|
||||
Eli,Fisher,IB,78,40,85,92,53
|
||||
Mila,Harrison,CSB,62,47,71,89,31
|
||||
Adam,Romero,IMB,34,66,98,42,75
|
||||
Stella,Patel,UIB,96,39,54,87,68
|
||||
Carson,Cox,IB,42,55,79,100,27
|
||||
Luna,Sanders,CSB,88,74,46,29,83
|
||||
Connor,Henderson,IMB,97,32,53,60,98
|
||||
Brooklyn,Bishop,UIB,45,90,61,72,31
|
||||
Andrew,Griffin,IB,58,42,87,65,49
|
||||
Natalia,Russell,CSB,70,23,74,56,92
|
||||
Jason,Myers,IMB,81,67,35,48,79
|
||||
Alexa,Hayes,UIB,37,98,55,93,42
|
||||
Christian,Long,IB,64,71,82,45,57
|
||||
Zoey,Gibson,CSB,90,54,38,100,73
|
||||
Brayden,Graham,IMB,39,89,66,53,31
|
||||
Maya,Sullivan,UIB,85,77,62,94,25
|
||||
Jaxon,Ford,IB,48,35,100,71,83
|
||||
Claire,Wallace,CSB,59,46,88,38,76
|
||||
Dominic,Cole,IMB,78,92,44,67,50
|
||||
Eva,Jenkins,UIB,100,29,53,79,61
|
||||
Riley,Perkins,IB,55,97,31,84,30
|
||||
Leo,Brooks,CSB,72,40,91,45,99
|
||||
Hailey,Reynolds,IMB,31,58,77,90,28
|
||||
Aaron,Fox,UIB,83,72,61,35,48
|
||||
Kennedy,Stevens,IB,41,66,85,92,53
|
||||
Sebastian,Webb,CSB,99,33,60,81,51
|
||||
Melanie,Ward,IMB,76,64,55,89,39
|
||||
Adrian,Bishop,UIB,67,40,78,95,20
|
||||
Jasmine,Cook,IB,34,84,91,47,53
|
||||
Miles,Barnes,CSB,89,25,72,69,98
|
||||
Savannah,Wood,IMB,54,58,49,87,62
|
||||
Hudson,Hill,UIB,31,100,37,46,81
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
import Data.List (nub, sortOn)
|
||||
import System.IO
|
||||
|
||||
-- separator -> Input -> Separated Input
|
||||
-- split :: Char -> String -> [String]
|
||||
|
||||
-- data Entry =
|
||||
|
||||
-- averages :: [Entry] -> [(String, Float)]
|
||||
|
||||
-- content -> Entries
|
||||
-- parse :: String -> [Entry]
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
putStrLn "Enter a filename: "
|
||||
putStrLn "..."
|
||||
Loading…
Reference in New Issue