diff --git a/50001 - Algorithm Analysis and Design/Lecture 1 - (Introduction)/Lecture 1.pdf b/50001 - Algorithm Analysis and Design/Lecture 1 - (Introduction)/Lecture 1.pdf
new file mode 100644
index 0000000..a0cfa65
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 1 - (Introduction)/Lecture 1.pdf differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 1 - (Introduction)/Lecture 1.tex b/50001 - Algorithm Analysis and Design/Lecture 1 - (Introduction)/Lecture 1.tex
new file mode 100644
index 0000000..9fedee3
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 1 - (Introduction)/Lecture 1.tex
@@ -0,0 +1,71 @@
+\documentclass{report}
+ \title{50001 - Algorithm Analysis and Design - Lecture 1}
+ \author{Oliver Killane}
+ \date{12/11/21}
+
+\input{../50001 common.tex}
+
+\begin{document}
+\maketitle
+\lectlink{https://imperial.cloud.panopto.eu/Panopto/Pages/Viewer.aspx?id=d281ea45-d9df-4f23-8578-adbf00d38370}
+
+\section*{Introduction}
+An algorithm is a method of computing a result for a given problem, at its core in a systematic/mathematical means.
+\\
+\\ This course extensively uses haskell instead of pesudocode to express problems, though its lessons still apply to other languages.
+
+\section*{Fundamentals}
+\sidenote{Insertion Problem}{
+ Given an integer $x$ and a sorted list $ys$, produce a list containing $x:ys$ that is ordered.
+ \\
+ \\ Note that this can be solved by simply using $sort(x:ys)$ however this is considered wasteful as it does not exploit the fact that $ys$ is already sorted.
+}
+An example algorithm would be to traverse $ys$ until we find a suitable place for $x$
+\codelist{Haskell}{insert.hs}
+\subsubsection*{Call Steps}
+In order to determine the complexity of the function, we use a \keyword{cost model} and determine what steps must be taken.
+\\
+\\ For example for $insert \ 4 \ [1,3,6,7]$
+\\ \begin{steps}
+ \start{insert \ 4 \ [1,3,6,7]}
+ \step{1 : insert \ 4 \ [3,6,7]}{definition of $insert$}
+ \step{1 : 3 : insert \ 4 \ [6,7]}{definition of $insert$}
+ \step{1 : 3 : : 4 : [6,7]}{definition of $insert$}
+\end{steps}
+Hence this requires $3$ call steps.
+\\
+\\ We can use recurrence relations to get a generalised formula for the worst case (maximum number of calls):
+\[\begin{matrix}
+ T_{insert} 0 & = 1 \\
+ T_{insert} 1 & = 1 + T_{insert}(n-1) \\
+ \end{matrix}\]
+We can solve the recurrence:
+\[\begin{matrix}
+ T_{insert} (n) & = 1 + T_{insert}(n-1) \\
+ T_{insert} (n) & = 1 + 1 + T_{insert}(n-2) \\
+ T_{insert} (n) & = 1 + 1 + \dots + 1 + T_{insert}(n-n) \\
+ T_{insert} (n) & = n + T_{insert}(0) \\
+ T_{insert} (n) & = n + 1 \\
+ \end{matrix}\]
+
+\subsubsection*{More complex algorithms}
+\codelist{Haskell}{isort.hs}
+\[\begin{matrix}
+ T_{isort} 0 & = 1 \\
+ T_{isort} n & = 1 + T_{insert}(n-1) + T_{isort}(n-1) \\
+ \end{matrix}\]
+Hence by using our previous formula for $insert$
+\[\begin{matrix}
+ T_{isort} n & = 1 + n + T_{isort}(n-1) \\
+ \end{matrix}\]
+And by recurrence:
+\[\begin{matrix}
+ T_{isort} (n) & = 1 + n + (1 + n - 1) + T_{isort}(n-2) \\
+ T_{isort} (n) & = 1 + n + (1 + n - 1) + (1 + n - 2) + \dots + T_{isort}(n-n) \\
+ T_{isort} (n) & = 1 + n + (1 + n - 1) + (1 + n - 2) + \dots + T_{isort}(0) \\
+ T_{isort} (n) & = n + n + (n - 1) + (n - 2) + \dots + (n-n) + 1 \\
+ T_{isort} (n) & = 1 + n + \sum_{i = 0}^n{i} \\
+ T_{isort} (n) & = \sum_{i = 0}^{n+1}{i} \\
+ T_{isort} (n) & = \cfrac{(n+1)\times(n+1)}{2} \\
+ \end{matrix}\]
+\end{document}
diff --git a/50001 - Algorithm Analysis and Design/Lecture 1 - (Introduction)/code/insert.hs b/50001 - Algorithm Analysis and Design/Lecture 1 - (Introduction)/code/insert.hs
new file mode 100644
index 0000000..a656541
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 1 - (Introduction)/code/insert.hs
@@ -0,0 +1,5 @@
+insert :: Int -> [Int] -> [Int]
+insert x [] = [x]
+insert x yss@(y:ys)
+ | x <= y = x:yss
+ | otherwise = y : insert x ys
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 1 - (Introduction)/code/isort.hs b/50001 - Algorithm Analysis and Design/Lecture 1 - (Introduction)/code/isort.hs
new file mode 100644
index 0000000..71e21bc
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 1 - (Introduction)/code/isort.hs
@@ -0,0 +1,3 @@
+isort :: [Int] -> [Int]
+isort [] = []
+isort (x:xs) = insert x (isort xs)
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 10 - (Random Access Lists)/Lecture 10.pdf b/50001 - Algorithm Analysis and Design/Lecture 10 - (Random Access Lists)/Lecture 10.pdf
new file mode 100644
index 0000000..86eaafd
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 10 - (Random Access Lists)/Lecture 10.pdf differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 10 - (Random Access Lists)/Lecture 10.tex b/50001 - Algorithm Analysis and Design/Lecture 10 - (Random Access Lists)/Lecture 10.tex
new file mode 100644
index 0000000..64b7096
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 10 - (Random Access Lists)/Lecture 10.tex
@@ -0,0 +1,37 @@
+\documentclass{report}
+ \title{50001 - Algorithm Analysis and Design - Lecture 10}
+ \author{Oliver Killane}
+ \date{18/11/21}
+
+\input{../50001 common.tex}
+
+\begin{document}
+\maketitle
+\lectlink{https://imperial.cloud.panopto.eu/Panopto/Pages/Viewer.aspx?id=62e2dbd5-4fba-4758-b2a6-addb016ec088}
+
+\section*{List lookup}
+\codelist{Haskell}{list lookup.hs}
+As you ca see \fun{!!} costs $O(n)$ as it may traverse the entire list.
+\\
+\\ If we want this access to be faster, we can use trees:
+\codelist{Haskell}{list tree.hs}
+This costs $O(\log n)$ as each recursive call acts on half of the remaining list.
+\\
+\\ However we have difficulty with insertion:
+\begin{center}
+ \begin{tabular}{l l l}
+ Insert Quickly & $n : t = node (Leaf n) t$ & Effectively becomes a linked list, $\log n$ search time ruined. \\
+ Insert Slowly & Rebalance tree (e.g \keyword{AVL} tree) & Complex and no longer $O(1)$ insert. \\
+ \end{tabular}
+\end{center}
+
+\section*{Random Access Lists}
+A list containing elements that are either nothing, or a perfect tree with size the same as $2^{index}$.
+\centerimage{width=\textwidth}{RAList.png}
+The empty tree can be represented by a $Tip$ value (from the notes), or using type $Maybe(Tree)$ (from the lecture) where $Tree \ a = Leaf \ x \ | \ Node \ n \ l \ r$.
+\\
+\\ When we add to a tree, we add to the first element of the \struct{RAList}, if the invariant is breached (no longer perfect tree of size $2^0$) it can be combined with the next list over (if empty, place, else combine and repeat).
+\\
+\\ This way while the worst case insert is $O(n)$, our amortized complexity is $O(1)$ much as with increment.
+\codelist{Haskell}{RAList.hs}
+\end{document}
diff --git a/50001 - Algorithm Analysis and Design/Lecture 10 - (Random Access Lists)/code/RAList.hs b/50001 - Algorithm Analysis and Design/Lecture 10 - (Random Access Lists)/code/RAList.hs
new file mode 100644
index 0000000..9d910eb
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 10 - (Random Access Lists)/code/RAList.hs
@@ -0,0 +1,33 @@
+data Tree a = Tip | Leaf a | Node Int (Tree a) (Tree a)
+
+type RAList a = [Tree a]
+
+instance List RAList where
+ toList :: RAList a -> [a]
+ toList (RaList ls) = concatMap toList ls
+
+ fromList :: [a] -> RAList a
+ fromList = foldr (:) empty
+
+ empty :: RAList a
+ empty = []
+
+ (:) :: a -> RAList a -> RAList a
+ n : [] = [Leaf n]
+ n : (RAList ls) = RAList (insertTree (Leaf n) ls)
+ where
+ insertTree :: Tree a -> [Tree a] -> [Tree a]
+ insertTree t ([]) = [t]
+ insertTree t (Tip:ls) = t:ls
+ insertTree t (t':ts) = Tip: insertTree (node t t') ts
+
+ length :: RAList a -> Int
+ length (RAList ls) = foldr ((+) . length) 0 ls
+
+ (!!) :: RAList a -> Int -> a
+ (RAList []) !! _ = error "(!!): empty list"
+ (RAList (x:xs)) !! n
+ | isEmpty x = (RAList ts) !! k
+ | n < m = x !! n
+ | otherwise = (RAList xs) !! (n-m)
+ where m = length x
diff --git a/50001 - Algorithm Analysis and Design/Lecture 10 - (Random Access Lists)/code/list lookup.hs b/50001 - Algorithm Analysis and Design/Lecture 10 - (Random Access Lists)/code/list lookup.hs
new file mode 100644
index 0000000..65d03c2
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 10 - (Random Access Lists)/code/list lookup.hs
@@ -0,0 +1,3 @@
+(!!) :: [a] -> Int -> a
+(x:xs) !! 0 = x
+(_:xs) !! k = xs !! (k-1)
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 10 - (Random Access Lists)/code/list tree.hs b/50001 - Algorithm Analysis and Design/Lecture 10 - (Random Access Lists)/code/list tree.hs
new file mode 100644
index 0000000..473f1e4
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 10 - (Random Access Lists)/code/list tree.hs
@@ -0,0 +1,26 @@
+data Tree a = Tip | Leaf a | Node Int (Tree a) (Tree a)
+
+node :: Tree a -> Tree a -> Tree a
+node l r = Node (size l + size r) l r
+
+instance List Tree where
+ toList :: Tree a -> [a]
+ toList Tip = []
+ toList (Leaf n) = [n]
+ toList (Fork n l r) = toList l ++ toList r
+
+ -- Invariant: size Node n a b = n = size a + size b
+ length :: Tree a -> Int
+ length Tip = 0
+ length (Leaf _) = 1;
+ length (Node n _ _) = n;
+
+ (!!) :: Tree a -> Int -> a
+ (Leaf x) !! 0 = x
+ (Node n l r) !! k
+ | k < m = l!!k
+ | otherwise = r!! (k-m)
+ where m = length l
+
+ -- case for Tip !! n or Leaf !! >0
+ _ !! _ = error "(!!): Cannot get list index"
diff --git a/50001 - Algorithm Analysis and Design/Lecture 10 - (Random Access Lists)/diagram/RAList.drawio b/50001 - Algorithm Analysis and Design/Lecture 10 - (Random Access Lists)/diagram/RAList.drawio
new file mode 100644
index 0000000..ed11669
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 10 - (Random Access Lists)/diagram/RAList.drawio
@@ -0,0 +1,209 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 10 - (Random Access Lists)/image/RAList.png b/50001 - Algorithm Analysis and Design/Lecture 10 - (Random Access Lists)/image/RAList.png
new file mode 100644
index 0000000..9428fb1
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 10 - (Random Access Lists)/image/RAList.png differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/Lecture 11.pdf b/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/Lecture 11.pdf
new file mode 100644
index 0000000..2e277b2
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/Lecture 11.pdf differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/Lecture 11.tex b/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/Lecture 11.tex
new file mode 100644
index 0000000..2a12ea4
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/Lecture 11.tex
@@ -0,0 +1,68 @@
+\documentclass{report}
+ \title{50001 - Algorithm Analysis and Design - Lecture 11}
+ \author{Oliver Killane}
+ \date{18/11/21}
+
+\input{../50001 common.tex}
+
+\begin{document}
+\maketitle
+\lectlink{https://imperial.cloud.panopto.eu/Panopto/Pages/Viewer.aspx?id=678e8f17-9eb3-4469-96d0-adde00d597c2}
+
+\section*{Equality}
+\codelist{Haskell}{equality.hs}
+Eq is the typeclass for equality, any instance of this class should ensure the equality satisfied the laws:
+\begin{center}
+ \begin{tabular}{r l}
+ reflexivity & $x == x$ \\
+ transitivity & $x == y \land y == z \Rightarrow x == z$ \\
+ symmetry & $x == y \Rightarrow y == x$ \\
+ \end{tabular}
+\end{center}
+We also expect the idescernability of identicals (Leibniz Law):
+\[x == y \Rightarrow f \ x == f \ y\]
+For a set-like interface we have a member function:
+\codelist{Haskell}{member.hs}
+If we assume only that Eq holds, the complexity is $O(n)$ as we must potentially check all members of the set. To get around this, we use ordering.
+
+\section*{Orderings}
+The Ord typeclass allows us to check for inequalities:
+\codelist{Haskell}{order.hs}
+We must try to ensure certain properties hold, for example for to have a partial order we require:
+\begin{center}
+ \begin{tabular}{r l}
+ reflexivity & $x \leq x$ \\
+ transitivity & $x \leq y \land y \leq z \Rightarrow x \leq z$ \\
+ antisymmetry & $x \leq y \land y \leq x \Rightarrow x == y$ \\
+ \end{tabular}
+\end{center}
+There are also total orders (all elements in the set are ordered compared to all others), for which we add the constraint:
+\begin{center}
+ \begin{tabular}{r l}
+ connexity & $x \leq y \lor y \leq x$ \\
+ \end{tabular}
+\end{center}
+
+\section*{Ordered Sets}
+\codelist{Haskell}{ordset.hs}
+We can implement this class for Trees:
+\codelist{Haskell}{search tree.hs}
+However the worst case here is still $O(n)$ as we do not balance the tree as more members are inserted. If the members are added in order, the tree devolves to a linked list.
+\\
+\\ We need a way to create a tree that self balances.
+
+\section*{Binary Search Trees (AVL Trees)}
+\codelist{Haskell}{avl tree.hs}
+When inserting into the tree we must keep the tree balanced such that no subtree's left is more than one higher than its' right.
+\codelist{Haskell}{avl tree insert.hs}
+We must rebalance the tree after insertion, this must consider the following cases:
+\centerimage{width=\textwidth}{htree balanced.png}
+When the tree's balanced invariant has been broken, we must follow these cases:
+\centerimage{width=\textwidth}{htree rotate right.png}
+\codelist{Haskell}{avl rotate right.hs}
+When the right subtree's right subtree is higher:
+\centerimage{width=\textwidth}{htree rotate left.png}
+\codelist{Haskell}{avl rotate left.hs}
+We can use rotate left and rotate right to for the two cases where the right subtree is 2 or more higher than the left.
+\codelist{Haskell}{avl balance.hs}
+\end{document}
diff --git a/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/code/avl balance.hs b/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/code/avl balance.hs
new file mode 100644
index 0000000..1906726
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/code/avl balance.hs
@@ -0,0 +1,10 @@
+balance :: Ord a => HTree a -> a -> HTree a -> HTree
+balance l x r
+ | lh == lr || abs (lr - lr) == 1 = t
+ | lh > lr = rotr(hnode (if height ll < height lr then rotl l else l) x r)
+ | otherwise = rotl(hnode l x (if height rl > height rr then rotr r else r))
+ where
+ lh = height l
+ rl = height r
+ (HNode _ ll _ lr) = l
+ (HNode _ rl _ rr) = r
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/code/avl rotate left.hs b/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/code/avl rotate left.hs
new file mode 100644
index 0000000..bbc4105
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/code/avl rotate left.hs
@@ -0,0 +1,5 @@
+rotl :: HTree a -> HTree a
+rotl (HNode _ ll w (HNode _ lrl x lrr))
+ = hnode (hnode ll w lrl) x lrr
+
+-- so for the example: HNode _ wt y r -> rotr ( hnode (rotl wt) y r)
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/code/avl rotate right.hs b/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/code/avl rotate right.hs
new file mode 100644
index 0000000..a2acb2a
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/code/avl rotate right.hs
@@ -0,0 +1,2 @@
+rotr :: HTree a -> HTree a
+rotr (HNode _ (HNode _ ll x lr) y r) = hnode ll x (hnode lr y r)
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/code/avl tree insert.hs b/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/code/avl tree insert.hs
new file mode 100644
index 0000000..216e509
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/code/avl tree insert.hs
@@ -0,0 +1,6 @@
+insert :: Ord a => a -> HTree a -> HTree a
+insert x HTip = hnode Tip x Tip
+insert x t@(HNode _ l y r)
+ | x == y = t
+ | x < y = balance (insert x l) y r
+ | otherwise = balance l y (insert x r)
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/code/avl tree.hs b/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/code/avl tree.hs
new file mode 100644
index 0000000..d2a1c8e
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/code/avl tree.hs
@@ -0,0 +1,10 @@
+-- H for height! The int stored at a node is the height of that tree.
+data HTree a = HTip | HNode Int (HTree a) a (HTree a)
+
+height :: HTree a -> Int
+height HTip = 0
+height (HNode h _ _ _) = h
+
+hnode :: HTree a -> a -> HTree a -> HTree a
+hnode l x r = HNode h l x r
+ where h = max (height l) (height r) + 1
diff --git a/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/code/equality.hs b/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/code/equality.hs
new file mode 100644
index 0000000..638d826
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/code/equality.hs
@@ -0,0 +1,2 @@
+class Eq a where
+ (==) :: a -> a -> Bool
diff --git a/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/code/member.hs b/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/code/member.hs
new file mode 100644
index 0000000..799fa2e
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/code/member.hs
@@ -0,0 +1 @@
+(in) :: Eq a => a -> Set a -> Bool
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/code/order.hs b/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/code/order.hs
new file mode 100644
index 0000000..c52b022
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/code/order.hs
@@ -0,0 +1,5 @@
+class Eq a => Ord a where
+ (<=) :: a -> a -> Bool
+ (<) :: a -> a -> Bool
+ (>=) :: a -> a -> Bool
+ (>) :: a -> a -> Bool
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/code/ordset.hs b/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/code/ordset.hs
new file mode 100644
index 0000000..55c514f
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/code/ordset.hs
@@ -0,0 +1,6 @@
+class OrdSet ordset where
+ empty :: ordset n
+ insert :: Ord a => a -> ordset a -> ordset a
+ member :: Ord a => a -> ordset a -> Bool
+ fromList :: Ord a => [a] -> ordset a
+ toList :: Ord a => ordset a -> [a]
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/code/search tree.hs b/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/code/search tree.hs
new file mode 100644
index 0000000..6b6255e
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/code/search tree.hs
@@ -0,0 +1,26 @@
+data Tree a = Tip | Node (Tree a) a (Tree a)
+
+instance OrdSet Tree where
+ empty :: Tree n
+ empty = Tip
+
+ insert :: Ord a => a -> Tree a -> Tree a
+ insert x Tip = Node Tip x Tip
+ insert x (Node l y r)
+ | x == y = t
+ | x < y = Node (insert x l) y r
+ | otherwise = Node l y (insert x r)
+
+ member :: Ord a => a -> Tree a -> Bool
+ member x Tip = False
+ member x (Node l y r)
+ | x == y = True
+ | x < y = member x l
+ | otherwise = member x r
+
+ fromList :: Ord a => [a] -> Tree a
+ fromList = foldr insert empty
+
+ toList :: Ord a => Tree a -> [a]
+ toList Tip = []
+ toList (Node l y r) = toList l ++ y:toList r
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/diagram/htree balanced.drawio b/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/diagram/htree balanced.drawio
new file mode 100644
index 0000000..5a5a029
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/diagram/htree balanced.drawio
@@ -0,0 +1,160 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/diagram/htree rotate left.drawio b/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/diagram/htree rotate left.drawio
new file mode 100644
index 0000000..f16b25d
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/diagram/htree rotate left.drawio
@@ -0,0 +1,265 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/diagram/htree rotate right.drawio b/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/diagram/htree rotate right.drawio
new file mode 100644
index 0000000..0ff101e
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/diagram/htree rotate right.drawio
@@ -0,0 +1,143 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/image/htree balanced.png b/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/image/htree balanced.png
new file mode 100644
index 0000000..833bdca
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/image/htree balanced.png differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/image/htree rotate left.png b/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/image/htree rotate left.png
new file mode 100644
index 0000000..63c04f0
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/image/htree rotate left.png differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/image/htree rotate right.png b/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/image/htree rotate right.png
new file mode 100644
index 0000000..6bd4261
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 11 - (Search Trees)/image/htree rotate right.png differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 12 - (Red Black Trees 1)/Lecture 12.pdf b/50001 - Algorithm Analysis and Design/Lecture 12 - (Red Black Trees 1)/Lecture 12.pdf
new file mode 100644
index 0000000..fa95f6e
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 12 - (Red Black Trees 1)/Lecture 12.pdf differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 12 - (Red Black Trees 1)/Lecture 12.tex b/50001 - Algorithm Analysis and Design/Lecture 12 - (Red Black Trees 1)/Lecture 12.tex
new file mode 100644
index 0000000..291115b
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 12 - (Red Black Trees 1)/Lecture 12.tex
@@ -0,0 +1,41 @@
+\documentclass{report}
+ \title{50001 - Algorithm Analysis and Design - Lecture 12}
+ \author{Oliver Killane}
+ \date{18/11/21}
+
+\input{../50001 common.tex}
+
+\begin{document}
+\maketitle
+\lectlink{https://imperial.cloud.panopto.eu/Panopto/Pages/Viewer.aspx?id=abdb5a60-fd1c-44bb-afbe-ade100fb80eb}
+
+\section*{Red-Black Trees}
+\keyword{AVL trees} worked by storing an extra integer (height) to use in rebalancing, \keyword{red-black trees} use an extra bit to determine if a node is red or black.
+\\
+\\ In practice they are less balanced than \keyword{AVL trees} however the insertion is faster and the data structure is a little bit smaller.
+\codelist{Haskell}{red-black tree.hs}
+The structure relies on two invariances:
+\begin{enumerate}
+ \item Every Red node must have a Black parent node.
+ \item Every path from the root to leaf must have the same number of black nodes.
+\end{enumerate}
+\subsubsection*{Valid Red Black Trees}
+\centerimage{width=\textwidth}{red-black trees.png}
+\subsubsection*{Invalid Red Black Trees}
+\centerimage{width=\textwidth}{not red-black trees.png}
+We have an insert function that needs to rebalance the tree:
+\codelist{Haskell}{red-black insert.hs}
+\centerimage{width=\textwidth}{balance cases.png}
+
+\section*{Counting}
+We can exploit the analogy we used with counting and trees for \keyword{RALists} here, with a difference.
+\\
+\\ Imagine a counting system that lacks zeros. We can count to 10 as:
+\begin{center}
+ \begin{tabular}{l l l l l l l l l l l l l l l l l l}
+ Normal: & 1 & 2 & \dots & 9 & 10 & \dots & 11 & 12 & \dots & 19 & 20 & \dots & 101 & 102 & \dots & 110 & 111 \\
+ Special: & 1 & 2 & \dots & 9 & X & \dots & 11 & 12 & \dots & 19 & 1X & \dots & X1 & X2 & \dots & XX & 111 \\
+ \end{tabular}
+\end{center}
+We can use this with the pattern of inserting elements into a red black tree (in order) to map red black trees to an incrementing number.
+\end{document}
diff --git a/50001 - Algorithm Analysis and Design/Lecture 12 - (Red Black Trees 1)/code/rbtree functions.hs b/50001 - Algorithm Analysis and Design/Lecture 12 - (Red Black Trees 1)/code/rbtree functions.hs
new file mode 100644
index 0000000..e2749bf
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 12 - (Red Black Trees 1)/code/rbtree functions.hs
@@ -0,0 +1,2 @@
+fromOrdList :: Ord a => [a] -> RBTree a
+fromOrdList = foldr insert Empty
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 12 - (Red Black Trees 1)/code/red-black insert.hs b/50001 - Algorithm Analysis and Design/Lecture 12 - (Red Black Trees 1)/code/red-black insert.hs
new file mode 100644
index 0000000..0696e5e
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 12 - (Red Black Trees 1)/code/red-black insert.hs
@@ -0,0 +1,23 @@
+blacken :: Ord a => RBTree a -> RBTree a
+blacken (Node Red l x r) = Node Black l x r
+blacken t = t
+
+balance :: Ord a => Colour -> RBTree a -> a -> RBTree a -> RBTree a
+balance c l v r = case Node c l v r of
+ Node Black (Node Red (Node Red a x b) y c) z d -> bal x y z a b c d
+ Node Black (Node Red a x (Node Red b y c)) z d -> bal x y z a b c d
+ Node Black a x (Node Red (Node Red b y c) z d) -> bal x y z a b c d
+ Node Black a x (Node Red b y (Node Red c z d)) -> bal x y z a b c d
+ t -> t
+ where
+ bal x y z a b c d = Node Red (Node Black a x b) y (Node Black c z d)
+
+insert :: Ord a => a -> RBTree a -> RBTree a
+insert = (blacken .) . ins
+ where
+ ins :: Ord a => a -> RBTree a -> RBTree a
+ ins x Empty = Node Red Empty x Empty
+ ins x t@(Node c l y r)
+ | x < y = balance c (ins x l) y r
+ | x == y = t
+ | otherwise = balance c l y (ins x r)
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 12 - (Red Black Trees 1)/code/red-black tree.hs b/50001 - Algorithm Analysis and Design/Lecture 12 - (Red Black Trees 1)/code/red-black tree.hs
new file mode 100644
index 0000000..2a365dc
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 12 - (Red Black Trees 1)/code/red-black tree.hs
@@ -0,0 +1,3 @@
+data Colour = Red | Black
+
+data RBTree a = Empty | Node Colour (RBTree a) a (RBTree a)
diff --git a/50001 - Algorithm Analysis and Design/Lecture 12 - (Red Black Trees 1)/diagram/balance cases.drawio b/50001 - Algorithm Analysis and Design/Lecture 12 - (Red Black Trees 1)/diagram/balance cases.drawio
new file mode 100644
index 0000000..9169354
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 12 - (Red Black Trees 1)/diagram/balance cases.drawio
@@ -0,0 +1,449 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 12 - (Red Black Trees 1)/diagram/not red-black trees.drawio b/50001 - Algorithm Analysis and Design/Lecture 12 - (Red Black Trees 1)/diagram/not red-black trees.drawio
new file mode 100644
index 0000000..5bf4aef
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 12 - (Red Black Trees 1)/diagram/not red-black trees.drawio
@@ -0,0 +1,115 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 12 - (Red Black Trees 1)/diagram/red-black trees.drawio b/50001 - Algorithm Analysis and Design/Lecture 12 - (Red Black Trees 1)/diagram/red-black trees.drawio
new file mode 100644
index 0000000..ddea936
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 12 - (Red Black Trees 1)/diagram/red-black trees.drawio
@@ -0,0 +1,139 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 12 - (Red Black Trees 1)/image/balance cases.png b/50001 - Algorithm Analysis and Design/Lecture 12 - (Red Black Trees 1)/image/balance cases.png
new file mode 100644
index 0000000..bca4c18
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 12 - (Red Black Trees 1)/image/balance cases.png differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 12 - (Red Black Trees 1)/image/not red-black trees.png b/50001 - Algorithm Analysis and Design/Lecture 12 - (Red Black Trees 1)/image/not red-black trees.png
new file mode 100644
index 0000000..f14c04a
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 12 - (Red Black Trees 1)/image/not red-black trees.png differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 12 - (Red Black Trees 1)/image/red-black trees.png b/50001 - Algorithm Analysis and Design/Lecture 12 - (Red Black Trees 1)/image/red-black trees.png
new file mode 100644
index 0000000..4c15ca4
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 12 - (Red Black Trees 1)/image/red-black trees.png differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 13 - (Red Black Trees 2)/Lecture 13.pdf b/50001 - Algorithm Analysis and Design/Lecture 13 - (Red Black Trees 2)/Lecture 13.pdf
new file mode 100644
index 0000000..3771366
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 13 - (Red Black Trees 2)/Lecture 13.pdf differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 13 - (Red Black Trees 2)/Lecture 13.tex b/50001 - Algorithm Analysis and Design/Lecture 13 - (Red Black Trees 2)/Lecture 13.tex
new file mode 100644
index 0000000..aa0f2d7
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 13 - (Red Black Trees 2)/Lecture 13.tex
@@ -0,0 +1,21 @@
+\documentclass{report}
+ \title{50001 - Algorithm Analysis and Design - Lecture 13}
+ \author{Oliver Killane}
+ \date{22/11/21}
+
+\input{../50001 common.tex}
+
+\begin{document}
+\maketitle
+\lectlink{https://imperial.cloud.panopto.eu/Panopto/Pages/Viewer.aspx?id=ce3f2216-40e2-4203-9898-ade70160bbb1}
+
+\section*{Red Black Trees Continued}
+We have a pattern with inserting elements from an ordered list into the tree.
+\centerimage{width=\textwidth}{red black insert pattern.png}
+We can encode this as a special binary number system, using $1$ and $2$ such that the least significant bit is a the number of trees of $2^0$ nodes, and the nth is $2^n$.
+\centerimage{width=\textwidth}{red black counting pattern.png}
+We can increment this by:
+\codelist{Haskell}{treenary.hs}
+We can convert a list of digits back to a red black tree by:
+\codelist{Haskell}{to RBTree.hs}
+\end{document}
diff --git a/50001 - Algorithm Analysis and Design/Lecture 13 - (Red Black Trees 2)/code/to RBTree.hs b/50001 - Algorithm Analysis and Design/Lecture 13 - (Red Black Trees 2)/code/to RBTree.hs
new file mode 100644
index 0000000..2a8d233
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 13 - (Red Black Trees 2)/code/to RBTree.hs
@@ -0,0 +1,7 @@
+-- fold left to combine the digits together into a tree
+fromList :: [a] -> RBTree a
+fromList xs = foldl link Empty (foldr add xs)
+
+link :: RBTree a -> Digit a -> RBTree a
+link l (One x t) = Node Black l x t
+link l (Two x t y u) = Node Black (Node Red l x t) y u
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 13 - (Red Black Trees 2)/code/treenary.hs b/50001 - Algorithm Analysis and Design/Lecture 13 - (Red Black Trees 2)/code/treenary.hs
new file mode 100644
index 0000000..15b9ace
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 13 - (Red Black Trees 2)/code/treenary.hs
@@ -0,0 +1,7 @@
+-- each element is a red black tree (+ an extra root element (a))
+data Digit a = One a (RBTree a) | Two a (RBTree a) a (RBTree a)
+
+incr :: a -> RBTree a -> [Digit a] -> [Digit a]
+incr x t [] = [One x t]
+incr x t ((One y u) : ds) = Two x t y u : ds
+incr x t ((Two y u z v) : ds) = One x t : incr y (Node Black u z v) ds
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 13 - (Red Black Trees 2)/diagram/red black counting pattern.drawio b/50001 - Algorithm Analysis and Design/Lecture 13 - (Red Black Trees 2)/diagram/red black counting pattern.drawio
new file mode 100644
index 0000000..38a17b6
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 13 - (Red Black Trees 2)/diagram/red black counting pattern.drawio
@@ -0,0 +1,717 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 13 - (Red Black Trees 2)/diagram/red black insert pattern.drawio b/50001 - Algorithm Analysis and Design/Lecture 13 - (Red Black Trees 2)/diagram/red black insert pattern.drawio
new file mode 100644
index 0000000..afe5973
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 13 - (Red Black Trees 2)/diagram/red black insert pattern.drawio
@@ -0,0 +1,214 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 13 - (Red Black Trees 2)/image/red black counting pattern.png b/50001 - Algorithm Analysis and Design/Lecture 13 - (Red Black Trees 2)/image/red black counting pattern.png
new file mode 100644
index 0000000..f86bfec
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 13 - (Red Black Trees 2)/image/red black counting pattern.png differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 13 - (Red Black Trees 2)/image/red black insert pattern.png b/50001 - Algorithm Analysis and Design/Lecture 13 - (Red Black Trees 2)/image/red black insert pattern.png
new file mode 100644
index 0000000..1b45806
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 13 - (Red Black Trees 2)/image/red black insert pattern.png differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/Lecture 14.pdf b/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/Lecture 14.pdf
new file mode 100644
index 0000000..1a0ad2d
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/Lecture 14.pdf differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/Lecture 14.tex b/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/Lecture 14.tex
new file mode 100644
index 0000000..f8c50e3
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/Lecture 14.tex
@@ -0,0 +1,62 @@
+\documentclass{report}
+ \title{50001 - Algorithm Analysis and Design - Lecture 14}
+ \author{Oliver Killane}
+ \date{28/11/21}
+\input{../50001 common.tex}
+\begin{document}
+\maketitle
+\lectlink{https://imperial.cloud.panopto.eu/Panopto/Pages/Viewer.aspx?id=a562661f-da77-4d28-85a6-ade80168e6e5}
+
+\section*{Randomized Algorithms}
+An algorithm that uses random values to produce a result.
+\begin{center}
+ \begin{tabular}{l l l}
+ \textbf{Algorithm Type} & \textbf{Running time} & \textbf{Correct Result} \\
+ Monte Carlo & Predicatable & Unpredictably \\
+ Las Vegas & Unpredictable & Predictably \\
+ \end{tabular}
+\end{center}
+
+\section*{Random Generation}
+
+Functions are deterministic (always map same inputs to same outputs), this is known as \keyword{Leibniz's law} or the \keyword{Law of indiscernibles}:
+\[x = y \Rightarrow f x = f y\]
+We can exhibit pesudo random behaviour using an input that varies \begin{tabular}{l l}
+ explicitly & (e.g Random numbers through seeds) \\
+ implicitly & (e.g Microphone or camera noise) \\
+\end{tabular}
+
+\subsection*{Inside IO Monad}
+We can use basic random through the IO monad like this:
+\codelist{Haskell}{simple random.hs}
+However using the \struct{IO monad} is too specific, we may want to use random numbers in other contexts.
+
+\subsection*{StdGen}
+In haskell we can use \struct{Stdgen}.
+\codelist{Haskell}{stdgen.hs}
+By passing the newly generated \struct{StdGen} we can generate new values based on the original seed.
+\centerimage{width=\textwidth}{random seeds.png}
+
+\subsection*{With Random Monad}
+Rather than passing \struct{StdGen} seeds through the program, we can use the \struct{MonadRandom} monad which internally uses this value.
+
+
+\section*{Randomized $\pi$}
+\centerimage{width=0.6\textwidth}{randomized pi.png}
+(Monte Carlo Algorithm - known number of samples, known running time per sample) To estimate $\pi$, find the proportion of randomly selected spots that are within the circle.
+\begin{center}
+ \begin{tabular}{l l}
+ Area of square & $2 \times 2 = 4$ \\
+ Area of circle & $\pi \times 1^2 = \pi$ \\
+ Probability in circle & $\cfrac{\pi}{4}$ \\
+ \end{tabular}
+\end{center}
+Once we have the proportion, we can multiply by 4 to get an estimate of $\pi$.
+\codelist{Haskell}{montePi.hs}
+
+\section*{Treaps}
+Simultaneously a \keyword{Tree} and a \keyword{Heap}. Stores values in order, while promoting higher priority nodes to the top of the tree.
+\centerimage{width=0.8\textwidth}{treap.png}
+\codelist{Haskell}{treap.hs}
+\centerimage{width=0.8\textwidth}{lnode and rnode.png}
+\end{document}
diff --git a/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/code/MonadRandom.hs b/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/code/MonadRandom.hs
new file mode 100644
index 0000000..b9bab25
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/code/MonadRandom.hs
@@ -0,0 +1,5 @@
+class Monad m => MonadRandom m where
+ getRandom :: Random a => m a
+ getRandoms :: Random a => m [a]
+ getRandomR :: Random a => (a, a) -> m a
+ getRandomRs :: Random a => (a, a) -> m [a]
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/code/montePi.hs b/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/code/montePi.hs
new file mode 100644
index 0000000..4a07e8f
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/code/montePi.hs
@@ -0,0 +1,40 @@
+import Control.Monad.Random (getRandomR, randomRs, MonadRandom)
+import System.Random (mkStdGen, StdGen)
+
+-- Here we can use one quarter of the circle, hence if the distance from the
+-- bottom left (0,0) to the point is within 1 then it is in the circle.
+inside :: Double -> Double -> Bool
+inside x y = 1 >= x * x + y * y
+
+-- Take 1000 samples and return 4 * the proportion.
+montePi :: MonadRandom m => m Double
+montePi = loop samples 0
+ where
+ samples = 10000
+ loop 0 m = return (4 * fromIntegral m / fromIntegral samples)
+ loop n m = do
+ x <- getRandomR (0,1)
+ y <- getRandomR (0,1)
+ loop (n-1) (if inside x y then m + 1 else m)
+
+
+
+
+-- Using a stream of random numbers (RandomRs)
+
+-- Get pairs of random numbers from the stream
+pairs :: [a] -> [(a,a)]
+pairs (x:y:ls) = (x,y):pairs ls
+
+-- From the pairs of random numbers, get the proportion of points inside the
+-- circle and use to get pi.
+montePi' :: Double
+montePi' = 4 * hits src / fromIntegral samples
+ where
+ samples = 10000
+ hits = fromIntegral .
+ length .
+ filter (uncurry inside) .
+ take samples .
+ pairs
+ src = randomRs (0, 1) (mkStdGen 42) :: [Double]
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/code/simple random.hs b/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/code/simple random.hs
new file mode 100644
index 0000000..f2311b3
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/code/simple random.hs
@@ -0,0 +1,6 @@
+import Control.Monad.Random (getRandom)
+
+main :: IO ()
+main = do
+ x <- getRandom :: IO Int
+ print (42 + x)
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/code/stdgen.hs b/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/code/stdgen.hs
new file mode 100644
index 0000000..11ed27f
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/code/stdgen.hs
@@ -0,0 +1,21 @@
+import System.Random (StdGen)
+
+-- Create a source of randomness from an integer seed
+mkStdGen :: Int -> StdGen
+
+-- Generate a random interger, and a new source of randomness
+random :: StdGen -> (Int, StdGen)
+
+-- Generate an infinite list of random numbers using an initial seed
+-- (source of random).
+randoms :: StdGen -> [Int]
+randoms seed = x:randoms seed' where (x, seed') = random seed
+
+-- In order to generate random value for any type, a typeclass is used
+class Random a where
+ random :: StdGen -> (a, StdGen)
+ randoms :: StdGen -> [a]
+
+ -- Random over a (R)ange
+ randomR :: (a,a) -> StdGen -> (a, StdGen)
+ randomRs:: (a,a) -> StdGen -> [a]
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/code/treap.hs b/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/code/treap.hs
new file mode 100644
index 0000000..3bc2578
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/code/treap.hs
@@ -0,0 +1,47 @@
+-- Node contains child treaps, as well as value (a) and the priority (Int)
+data Treap a = Empty | Node (Treap a) a Int (Treap a)
+
+-- Normal tree search using values
+member :: Ord a => a -> Treap a -> Bool
+member x (Node l y _ r)
+ | x == y = True
+ | x < y = member x l
+ | otherwise = member x r
+member _ Empty = False
+
+-- Priority based insert
+pinsert :: Ord a => a -> Int -> Treap a -> Treap a
+pinsert x p Empty = Node Empty x p Empty
+pinsert x p t@(Node l y q r)
+ | x == y = t
+ | x < y = lnode (pinsert x p l) y q r
+ | otherwise = rnode l y q (pinsert x p r)
+
+-- rotate right (check left node)
+lnode :: Treap a -> a -> Int -> Treap a -> Treap a
+lnode Empty y q r = Node Empty y q r
+lnode l@(Node a x p b) y q c
+ | q > p = Node a x p (Node b y q c)
+ | otherwise = Node l y q c
+
+-- rotate left (check right node)
+rnode :: Treap a -> a -> Int -> Treap a -> Treap a
+rnode l y q Empty = Node l y q Empty
+rnode a x p r@(Node b y q c)
+ | q < p = Node (Node a x p b) y q c
+ | otherwise = Node a x p r
+
+-- delete node by recursively searching, then delete and merge subtrees
+delete :: Ord a => a -> Treap a -> Treap a
+delete x Empty = Empty
+delete x (Node a y q b)
+ | x == y = merge a b
+ | x < y = Node (delete x a) y q b
+ | otherwise = Node a y q (delete x b)
+
+merge :: Treap a -> Treap a -> Treap a
+merge Empty r = r
+merge l Empty = l
+merge l@(Node a x p b) r@(Node c y q d)
+ | p < q = Node a x p (merge b r)
+ | otherwise = Node (merge l c) y q d
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/diagram/lnode and rnode.drawio b/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/diagram/lnode and rnode.drawio
new file mode 100644
index 0000000..0383451
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/diagram/lnode and rnode.drawio
@@ -0,0 +1,163 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/diagram/random seeds.drawio b/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/diagram/random seeds.drawio
new file mode 100644
index 0000000..eab1e1d
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/diagram/random seeds.drawio
@@ -0,0 +1,95 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/diagram/randomized pi.drawio b/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/diagram/randomized pi.drawio
new file mode 100644
index 0000000..c873702
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/diagram/randomized pi.drawio
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/diagram/treap.drawio b/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/diagram/treap.drawio
new file mode 100644
index 0000000..ea16802
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/diagram/treap.drawio
@@ -0,0 +1,199 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/image/lnode and rnode.png b/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/image/lnode and rnode.png
new file mode 100644
index 0000000..d2bf31f
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/image/lnode and rnode.png differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/image/random seeds.png b/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/image/random seeds.png
new file mode 100644
index 0000000..a504856
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/image/random seeds.png differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/image/randomized pi.png b/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/image/randomized pi.png
new file mode 100644
index 0000000..aa9e33b
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/image/randomized pi.png differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/image/treap.png b/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/image/treap.png
new file mode 100644
index 0000000..d21c575
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 14 - (Randomized Algorithms)/image/treap.png differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 15 - (Treaps)/Lecture 15.pdf b/50001 - Algorithm Analysis and Design/Lecture 15 - (Treaps)/Lecture 15.pdf
new file mode 100644
index 0000000..da17d9d
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 15 - (Treaps)/Lecture 15.pdf differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 15 - (Treaps)/Lecture 15.tex b/50001 - Algorithm Analysis and Design/Lecture 15 - (Treaps)/Lecture 15.tex
new file mode 100644
index 0000000..357098f
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 15 - (Treaps)/Lecture 15.tex
@@ -0,0 +1,23 @@
+\documentclass{report}
+ \title{50001 - Algorithm Analysis and Design - Lecture 15}
+ \author{Oliver Killane}
+ \date{29/11/21}
+\input{../50001 common.tex}
+\begin{document}
+\maketitle
+\lectlink{https://imperial.cloud.panopto.eu/Panopto/Pages/Viewer.aspx?id=e7c5b433-e2eb-4762-9a09-adee01382a82}
+
+\section*{Randomized Treaps}
+By using a random value for priority when inserting values into the treap, we can ensure a high likelihood of balancing, without complex balancing being required.
+\\
+\\ We can use this to create a randomized quicksort.
+\codelist{Haskell}{randomized treap.hs}
+
+\section*{Randomized Binary Trees}
+We can balance a binary tree without using a treap, by inserting at the root (and rotating the tree to ensure it is ordered) with a certain probability.
+\codelist{Haskell}{Randomized Binary Tree.hs}
+For every insert we have chance $\cfrac{1}{n+1}$ of inserting at the root of the tree. Then this occurs, the contents are rotated to ensure the tree's ordering is maintained.
+\\
+\\ This means that there is a very high probability of balance being maintained, however correct results are only returned when distinct elements are inserted at most once.
+
+\end{document}
diff --git a/50001 - Algorithm Analysis and Design/Lecture 15 - (Treaps)/code/Randomized Binary Tree.hs b/50001 - Algorithm Analysis and Design/Lecture 15 - (Treaps)/code/Randomized Binary Tree.hs
new file mode 100644
index 0000000..9ebbf78
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 15 - (Treaps)/code/Randomized Binary Tree.hs
@@ -0,0 +1,43 @@
+import System.Random (StdGen, mkStdGen, randomR)
+
+data BTree a = Empty | Node (BTree a) a (BTree a)
+
+insert :: Ord a => a -> BTree a -> BTree a
+insert x Empty = Node Empty x Empty
+insert x t@(Node l y r)
+ | x == y = t
+ | x < y = Node (insert x l) y r
+ | otherwise = Node l y (insert x r)
+
+-- basic lefty/right rotations
+rotr :: BTree a -> a -> BTree a -> BTree a
+rotr (Node a x b) y c = Node a x (Node b y c)
+rotr _ _ _= error "(rotr): left was empty"
+
+rotl :: BTree a -> a -> BTree a -> BTree a
+rotl a x (Node b y c) = Node (Node a x b) y c
+rotl _ _ _= error "(rtol): right was empty"
+
+
+-- Insert to the root of the tree (maintaining order)
+insertRoot :: Ord a => a -> BTree a -> BTree a
+insertRoot x Empty = Node Empty x Empty
+insertRoot x t@(Node l y r)
+ | x == y = t
+ | x < y = rotr (insertRoot x l) y r
+ | otherwise = rotl l y (insertRoot x r)
+
+-- Randomized binary tree
+data RBTree a = RBTree StdGen Int (BTree a)
+
+empty :: RBTree a
+empty = RBTree (mkStdGen 42) 0 Empty
+
+-- chance of 1 / n+1 of inserting at root.
+insert' :: Ord a => a -> RBTree a -> RBTree a
+insert' x (RBTree seed n t) = RBTree seed' (n+1) (f x t)
+ where
+ f = case p of
+ 0 -> insertRoot
+ _ -> insert
+ (p, seed') = randomR (0,n) seed
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 15 - (Treaps)/code/randomized treap.hs b/50001 - Algorithm Analysis and Design/Lecture 15 - (Treaps)/code/randomized treap.hs
new file mode 100644
index 0000000..2a785d6
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 15 - (Treaps)/code/randomized treap.hs
@@ -0,0 +1,26 @@
+import System.Random (StdGen, mkStdGen, random)
+-- node random :: StdGen -> (Int, StdGen)
+
+data RTreap a = RTreap StdGen (Treap a)
+
+insert :: Ord a => a -> RTreap a -> RTreap a
+insert x (RTreap seed t) = RTreap seed' (pinsert x p t)
+ where (p, seed') = random seed
+
+-- note 42 is used for
+empty :: RTreap a
+empty = RTreap (mkStdGen 42) Empty
+
+-- Build up tree, requires O(n log n)
+fromList :: Ord a => [a] -> RTreap a
+fromList xs = foldr insert empty xs
+
+-- Linear time conversion (use treap tolist)
+toList :: RTreap a -> [a]
+toList (RTreap _ t) = tolist t
+
+-- Randomiozed Quicksort O(n log n)
+-- Effectively the random priorities are the partitions, first pivot is the
+-- highest priority.
+rquicksort :: Ord a => [a] -> [a]
+rquicksort = toList . fromList
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 16 - (Mutable Algorithms)/Lecture 16.pdf b/50001 - Algorithm Analysis and Design/Lecture 16 - (Mutable Algorithms)/Lecture 16.pdf
new file mode 100644
index 0000000..68fcaa1
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 16 - (Mutable Algorithms)/Lecture 16.pdf differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 16 - (Mutable Algorithms)/Lecture 16.tex b/50001 - Algorithm Analysis and Design/Lecture 16 - (Mutable Algorithms)/Lecture 16.tex
new file mode 100644
index 0000000..0376ac1
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 16 - (Mutable Algorithms)/Lecture 16.tex
@@ -0,0 +1,34 @@
+\documentclass{report}
+ \title{50001 - Algorithm Analysis and Design - Lecture 16}
+ \author{Oliver Killane}
+ \date{18/12/21}
+\input{../50001 common.tex}
+\begin{document}
+\maketitle
+\lectlink{https://imperial.cloud.panopto.eu/Panopto/Pages/Viewer.aspx?id=940579d0-4ab4-41d0-a3a9-adf8008866f0}
+
+\section*{Mutable Algorithms}
+We can use \struct{STRef} \var{s} \var{a} to hold a mutable reference to
+\var{a} that can be created, read and modified.
+\codelist{Haskell}{st.hs}
+
+We can use this to create a mutable version of fibonacci.
+\codelist{Haskell}{fib.hs}
+
+\section*{Mutable Datastructures}
+\subsection*{Array}
+\codelist{Haskell}{array.hs}
+Each operation is assumed to take constant time.
+\\
+\\ For example, an algorithm to find the smallest natural number not in a list.
+\codelist{Haskell}{minfree.hs}
+
+\subsection*{Hash}
+\codelist{Haskell}{hash.hs}
+A hash generates an integer from some data. Typically range restricted
+(e.g hashmap can hold a finite number of entries), and the hash function
+should be designed to reduce collisions (two distinct data having the same hash).
+\\
+\\ Below is an example of a bucket based hash map, using linked list buckets.
+\centerimage{width=0.6\textwidth}{hash diagram.png}
+\end{document}
diff --git a/50001 - Algorithm Analysis and Design/Lecture 16 - (Mutable Algorithms)/code/array.hs b/50001 - Algorithm Analysis and Design/Lecture 16 - (Mutable Algorithms)/code/array.hs
new file mode 100644
index 0000000..02541bb
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 16 - (Mutable Algorithms)/code/array.hs
@@ -0,0 +1,13 @@
+import Control.Monad.ST
+import Data.Array.ST
+
+-- Use indexable i, range, default to get a mutable array in some state
+newArray :: Ix i => (i,i) -> a -> ST s (STArray s i a)
+
+-- Use indexable i, a mutable array and return the value a with state s
+readArray :: Ix i -> STArray s i a -> i -> ST s a
+
+-- Use indexable i, a mutable array, and the value to place, return a
+-- computation that updates the array (new state) but returns no value.
+-- note:
+writeArray :: Ix i => STArray s i a -> i -> a -> ST s ()
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 16 - (Mutable Algorithms)/code/fib.hs b/50001 - Algorithm Analysis and Design/Lecture 16 - (Mutable Algorithms)/code/fib.hs
new file mode 100644
index 0000000..7e41d49
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 16 - (Mutable Algorithms)/code/fib.hs
@@ -0,0 +1,24 @@
+import Data.STRef (newSTRef, readSTRef, writeSTRef)
+import Control.Monad.ST (runST)
+
+-- immutable looping fibonacci
+fib :: Int -> Integer
+fib n = loop n 0 1
+ where
+ loop :: Int -> Integer -> Integer -> Integer
+ loop 0 x y = x
+ loop n x y = loop (n-1) y (x+y)
+
+-- mutable looping fibonacci
+fib0 :: Int -> Integer
+fib0 n = runST $ do
+ rx <- newSTRef 0
+ ry <- newSTRef 1
+ let loop 0 = do readSTRef rx
+ loop n = do {
+ x <- readSTRef rx;
+ y <- readSTRef ry;
+ writeSTRef rx y;
+ writeSTRef ry (x + y);
+ loop (n - 1);}
+ loop n
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 16 - (Mutable Algorithms)/code/hash.hs b/50001 - Algorithm Analysis and Design/Lecture 16 - (Mutable Algorithms)/code/hash.hs
new file mode 100644
index 0000000..c73ba37
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 16 - (Mutable Algorithms)/code/hash.hs
@@ -0,0 +1,2 @@
+class Hashable a where
+ hash :: a -> Int
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 16 - (Mutable Algorithms)/code/minfree.hs b/50001 - Algorithm Analysis and Design/Lecture 16 - (Mutable Algorithms)/code/minfree.hs
new file mode 100644
index 0000000..570e46e
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 16 - (Mutable Algorithms)/code/minfree.hs
@@ -0,0 +1,36 @@
+import Data.Array.MArray (MArray(newArray))
+import Data.Array.ST
+import Control.Monad.ST
+import Data.List ((\\))
+
+-- immutable
+minfree :: [Int] -> Int
+minfree xs = head ( [0..] \\ xs )
+
+-- effectively the same as minfree
+minfree' :: [Int] -> Int
+minfree' xs = head . filter(not . (`elem` xs)) $ [0..]
+
+
+-- Builds up an array of which are present,
+minfreeMut :: [Int] -> Int
+minfreeMut = length . takeWhile id . checklist
+
+{-
+Build an array, at each index True/False for if the index is in xs
+We only need to use an array of size (length xs) as we do not care about
+natural numbers larger than this (if they are in the list, then a smaller
+natural number was missed).
+
+xs [0,1,2,3,6,7,8]
+ys [T,T,T,T,F,F,T] ... (don't care about 7 or 8)
+
+-}
+checklist :: [Int] -> [Bool]
+checklist xs = runST $ do {
+ ys <- newArray (0,l - 1) False :: ST s (STArray s Int Bool);
+ sequence [writeArray ys x True | x <- xs, x < l];
+ getElems ys;
+ }
+ where
+ l = length xs
diff --git a/50001 - Algorithm Analysis and Design/Lecture 16 - (Mutable Algorithms)/code/st.hs b/50001 - Algorithm Analysis and Design/Lecture 16 - (Mutable Algorithms)/code/st.hs
new file mode 100644
index 0000000..db1ff55
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 16 - (Mutable Algorithms)/code/st.hs
@@ -0,0 +1,19 @@
+
+-- State Transformer (ST) takes a state s and return value a.
+-- "Give me any program with any state s, and if it returns an a, so will I".
+runST :: (forall s . ST s a) -> a
+
+-- Take a value a, produces a program with some state s, that returns a
+-- reference with that state and the value stored.
+newSTRef :: a -> ST s (STRef s a)
+
+-- Takes in a reference in some state s, performs a computation to get a
+readSTRef :: STRef s a -> ST s a
+
+-- Take in a reference, and a new value a, performing a computation to update
+-- the referenced value (update does not return anything itself, hence ()).
+writeSTRef :: STRef s a -> a -> ST s ()
+
+-- Takes a value, returns a computation that executes in any state s to return
+-- an a.
+return :: a -> ST s a
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 16 - (Mutable Algorithms)/diagram/hash diagram.drawio b/50001 - Algorithm Analysis and Design/Lecture 16 - (Mutable Algorithms)/diagram/hash diagram.drawio
new file mode 100644
index 0000000..0532bf5
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 16 - (Mutable Algorithms)/diagram/hash diagram.drawio
@@ -0,0 +1,100 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 16 - (Mutable Algorithms)/image/hash diagram.png b/50001 - Algorithm Analysis and Design/Lecture 16 - (Mutable Algorithms)/image/hash diagram.png
new file mode 100644
index 0000000..e5b59f5
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 16 - (Mutable Algorithms)/image/hash diagram.png differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 17 - (Mutable Algorithms II)/Lecture 17.pdf b/50001 - Algorithm Analysis and Design/Lecture 17 - (Mutable Algorithms II)/Lecture 17.pdf
new file mode 100644
index 0000000..15b8c94
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 17 - (Mutable Algorithms II)/Lecture 17.pdf differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 17 - (Mutable Algorithms II)/Lecture 17.tex b/50001 - Algorithm Analysis and Design/Lecture 17 - (Mutable Algorithms II)/Lecture 17.tex
new file mode 100644
index 0000000..3002f97
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 17 - (Mutable Algorithms II)/Lecture 17.tex
@@ -0,0 +1,21 @@
+\documentclass{report}
+ \title{50001 - Algorithm Analysis and Design - Lecture 17}
+ \author{Oliver Killane}
+ \date{18/12/21}
+\input{../50001 common.tex}
+\begin{document}
+\maketitle
+\lectlink{https://imperial.cloud.panopto.eu/Panopto/Pages/Viewer.aspx?id=78ea6bc7-9ac6-47ae-8bc9-adf8008866b4}
+
+\section*{Mutable Nub}
+This can be useful for the \fun{nub} function (removes duplicates from a list) by using a bucket based hashmap of items from the list to determine duplication.
+\codelist{Haskell}{nub.hs}
+
+\section*{Quicksort}
+We can also implement quicksort, which can be done in place in an array
+(saved memory and time as accesses are constant time).
+\\
+\\ By using mutable data structures we can swap elements when reordering by reading and writing from the array.
+\codelist{Haskell}{quicksort.hs}
+
+\end{document}
diff --git a/50001 - Algorithm Analysis and Design/Lecture 17 - (Mutable Algorithms II)/code/nub.hs b/50001 - Algorithm Analysis and Design/Lecture 17 - (Mutable Algorithms II)/code/nub.hs
new file mode 100644
index 0000000..ff38566
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 17 - (Mutable Algorithms II)/code/nub.hs
@@ -0,0 +1,29 @@
+import Control.Monad (when)
+import Data.Array.ST
+ ( getElems, newListArray, readArray, writeArray, STArray )
+import Control.Monad.ST ( ST, runST )
+
+
+-- immutable version:
+nub :: Eq a => [a] -> [a]
+nub = reverse . foldl nubHelper []
+ where
+ nubHelper :: Eq a => [a] -> a -> [a]
+ nubHelper ns c
+ | c `elem` ns = ns
+ | otherwise = c:ns
+
+-- mutable version, create a hash table of characters to track which have
+-- already been seen.
+nubMut :: (Hashable a, Eq a) => [a] -> [a]
+nubMut xs = concat $ runST $ do
+ axss <- newListArray (0, n - 1) (replicate 256 [ ]) :: ST s (STArray s Int [a])
+ sequence [do {
+ let hx = hash x `mod` (n - 1)
+ ys <- readArray axss hx
+ unless (x `elem` ys) $ do writeArray axss hx (x : ys)}
+ | x <- xs]
+ getElems axss
+ where
+ -- number of buckets in the hash table
+ n = 256
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 17 - (Mutable Algorithms II)/code/quicksort.hs b/50001 - Algorithm Analysis and Design/Lecture 17 - (Mutable Algorithms II)/code/quicksort.hs
new file mode 100644
index 0000000..4c3e218
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 17 - (Mutable Algorithms II)/code/quicksort.hs
@@ -0,0 +1,47 @@
+import Data.Array.ST ( readArray, writeArray, STArray, getElems )
+import Control.Monad.ST ( ST )
+
+-- swap elements over (classic store in temp & swap over other before writeback)
+swap :: STArray s Int a -> Int -> Int -> ST s ()
+swap axs i j = do
+ temp <- readArray axs i
+ readArray axs j >>= writeArray axs i
+ writeArray axs j temp
+
+qsort :: Ord a => [a] -> [a]
+qsort xs = runST $ do
+ axs <- newListArray (0,n) xs
+ aqsort axs 0 n
+ getElems axs
+ where
+ n = length xs - 1
+
+{-
+Partition around a pivot (k) (all smaller to left, larger to right
+(unsorted)), then recur on these partitions
+Index: 0 (k-1) k (k+1) n
+Contents: [ ..<= x .. ][x][ .. >x ..]
+-}
+aqsort :: Ord a => STArray s Int a -> Int -> Int -> ST s ()
+aqsort axs i j
+ | i >= j = return ()
+ | otherwise = do
+ k <- apartition axs i j
+ aqsort axs i (k - 1)
+ aqsort axs (k + 1) j
+
+apartition :: Ord a => STArray s Int a -> Int -> Int -> ST s Int
+apartition asx p q = do
+ x <- readArray axs p
+ let loop i j
+ | i > j = do
+ swap axs p j
+ return j
+ | otherwise = do
+ u <- readArray axs i
+ if u < x
+ then do loop (i + 1) j
+ else do
+ swap axs i j
+ loop i (j - 1)
+ loop (p+1) q
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 2 - (Evaluation)/Lecture 2.pdf b/50001 - Algorithm Analysis and Design/Lecture 2 - (Evaluation)/Lecture 2.pdf
new file mode 100644
index 0000000..bece841
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 2 - (Evaluation)/Lecture 2.pdf differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 2 - (Evaluation)/Lecture 2.tex b/50001 - Algorithm Analysis and Design/Lecture 2 - (Evaluation)/Lecture 2.tex
new file mode 100644
index 0000000..bda38bb
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 2 - (Evaluation)/Lecture 2.tex
@@ -0,0 +1,139 @@
+\documentclass{report}
+ \title{50001 - Algorithm Analysis and Design - Lecture 2}
+ \author{Oliver Killane}
+ \date{12/11/21}
+
+\input{../50001 common.tex}
+
+\newcommand{\cond}[3]{\text{if } #1 \text{ then } #2 \text{ else } #3}
+
+\begin{document}
+\maketitle
+\lectlink{https://imperial.cloud.panopto.eu/Panopto/Pages/Viewer.aspx?id=c8abc020-d7c8-44ad-b1df-adc100991181}
+
+\section*{Evaluation \& Cost Models}
+\codelist{Haskell}{minimum.hs}
+When analysing the cost of \fun{minimum} we must consider how the function is evaluated.
+\\
+\\ For example we could shortcut the once \fun{isort} has determined the first element (the minimum) of the list.
+\\
+\sidenote{Cost Model}{
+ A model to determine the time taken to execute a program.
+ \\
+ \\ The model assigns cost to different operations (e.g comparisons, calls, memory reads/writes)
+ \\
+ \\ A very generalised cost model assigns cost based on the number of \keyword{reductions} required to evaluate a program.
+}
+
+\section*{Small While Language}
+We can define a small language of expressions as follows:
+\[e ::= x \ | \ k \ | \ f \ e_1 \dots e_n \ | \ \cond{e}{e_1}{e_2}\]
+where $k$ means constant and $x$ is the variable form.
+\\ Infix functions such as $+, -, \times$ are written normally, and are also expressions as they can be used in the form $(+) \ e_1 \ e_2$.
+\\
+\\ There are also several primitive constants: $True, False, 0, 1, 2, \dots$
+\\ List constants and operations are also primitive: $[], (:), null, head, tail$
+
+\section*{Evaluation Order}
+\begin{itemize}
+ \bullpara{Applicative Order}{ Strict evaluation
+ \\The leftmost, innermost reducible expression is evaluated first.
+ \\ e.g for $fst (3 \times 2, 1 + 2)$
+ \\ \begin{steps}
+ \start{fst (3 \times 2, 1 + 2)}
+ \step{ fst (6, 1 + 2)}{Definition of $\times$}
+ \step{fst (6, 3)}{ Definition of $+$}
+ \step{6}{Definition of $fst$}
+ \end{steps}
+ }
+ \bullpara{Normal Order}{ Lazy evaluation
+ \\ The leftmost outer reducible is evaluated first. Efectively evaluating the function before its arguments.
+ \\ e.g for $fst (0, 1 + 2)$
+ \\ \begin{steps}
+ \start{fst (3 \times 2, 1 + 2)}
+ \step{3 \times 2}{ Definition of $fst$}
+ \step{6}{ Definition of $\times$}
+ \end{steps}
+ }
+\end{itemize}
+For a given program, if \keyword{applicative} and \keyword{normal} terminate, then they produce the same value in normal form.
+\\
+\\ However there are some programs where \keyword{normal} evaluation terminates, but \keyword{applicative} will not.
+\begin{minipage}[t]{0.4\textwidth}
+ \centerline{\textbf{Applicative}}
+ \begin{steps}
+ \start{fst (0, \text{crazy nonesense})}
+ \step{CRASH!}{ By lack of definition for crazy nonesense}
+ \end{steps}
+\end{minipage}
+\hfill
+\begin{minipage}[t]{0.4\textwidth}
+ \centerline{\textbf{Normal}}
+ \begin{steps}
+ \start{fst (0, \text{crazy nonesense})}
+ \step{0}{ Definition of $fst$}
+ \end{steps}
+\end{minipage}
+The program may by syntactically correct, but have an error such as zero-division which will not be evaluated and hence not result in improper termination under \keyword{normal} order.
+\begin{large} \[\text{Applicative Terminates} \Rightarrow \text{Normal Terminates}\] \end{large}
+
+\section*{Cost Model for Small While}
+We can evaluate a cost model for the small while language by creating a function $T$ to assign cost to expressions.
+\\\begin{tabular}{p{0.25\textwidth} p{0.35\textwidth} p{0.4\textwidth}}
+ \textbf{Type} & \textbf{Function} & \textbf{Explanation} \\
+ \hline
+ non-primitive function & $\begin{matrix}
+ f \ a_1 \ \dots \ a_n = e \\
+ T(f) \ a_1 \ \dots \ a_n = T(e) + 1 \\
+ \end{matrix}$ & Given we have already computed all argument, the cost of the function is the cost of the expression it produces, and a single call. \\
+ \hline
+ primitive function & $T(f) \ x \dots \ x_n = 0$ & Primitive functions are assumed to be free. \\
+ \hline
+ Variable & $T(x) = 0$ & accessing variables is free. \\
+ \hline
+ Application & $T(f \ e_1 \ \dots \ e_n) = T(f) \ e_1 \ \dots \ e_n + T(e_1) + \dots + T(e_n)$ & When applying a function we must consider both its cost, and the cost of all argument expressions. \\
+ \hline
+ Conditional & $T(\cond{p}{e_1}{e_2}) = T(p) + \cond{p}{T(e_1)}{T(e_2)}$ & Cost of condition and of the resulting expression. \\
+\end{tabular}
+
+\section*{Cost Model Example}
+Given the function:
+\[mul \ m \ n = \cond{m=0}{0}{n + mul \ (m-1) \ n}\]
+Evaluate $T(mul \ 3 \ 100)$
+\\
+\begin{proof}
+ \proofstep{1}{$mul \ 3 \ 100$}{}
+ \proofstep{2}{$T(\cond{3=0}{0}{100 + mul \ (3-1) \ 100}) + 1$}{By Rule for non-primitive functions}
+ \proofstep{3}{$T(3=0) + T(100 + mul \ (3-1) \ 100) + 1$}{By rule for conditionals}
+ \proofstep{4}{$0 + T(100 + mul \ (3-1) \ 100) + 1$}{By primitive functions}
+ \proofstep{5}{$T(+) (100 \ mul \ (3-1) \ 100) + T(100) + T(mul \ (3-1) \ 100) + 1$}{By application rule}
+ \proofstep{6}{$0 + T(100) + T(mul \ (3-1) \ 100) + 1$}{By rule for primitive functions}
+ \proofstep{7}{$0 + T(mul \ (3-1) \ 100) + 1$}{By rule for constants}
+ \proofstep{8}{$T(mul) \ (3-1) \ 100 + T(3 - 1) + T(100) + 1$}{By application rule}
+ \proofstep{9}{$T(mul) \ (3-1) \ 100 + T(-) 3 \ 1 + T(100) + 1$}{By application rule}
+ \proofstep{10}{$T(mul) \ 2 \ 100 + 1$}{By application rule}
+ \proofstep{11}{$T(\cond{2=0}{0}{100 + mul \ (2-1) \ 100}) + 1 + 1$}{By Rule for non-primitive functions}
+ \proofstep{12}{$T(2=0) + T(100 + mul \ (2-1) \ 100) + 2$}{By rule for conditionals}
+ \proofstep{13}{$0 + T(100 + mul \ (2-1) \ 100) + 2$}{By primitive functions}
+ \proofstep{14}{$T(+) (100 \ mul \ (2-1) \ 100) + T(100) + T(mul \ (2-1) \ 100) + 2$}{By application rule}
+ \proofstep{15}{$0 + T(100) + T(mul \ (2-1) \ 100) + 2$}{By rule for primitive functions}
+ \proofstep{16}{$0 + T(mul \ (2-1) \ 100) + 2$}{By rule for constants}
+ \proofstep{17}{$T(mul) \ (2-1) \ 100 + T(2 - 1) + T(100) + 2$}{By application rule}
+ \proofstep{18}{$T(mul) \ (2-1) \ 100 + T(-) 2 \ 1 + T(100) + 2$}{By application rule}
+ \proofstep{19}{$T(mul) \ 1 \ 100 + 2$}{By application rule}
+ \proofstep{20}{$T(\cond{1=0}{0}{100 + mul \ (1-1) \ 100}) + 2 + 1$}{By Rule for non-primitive functions}
+ \proofstep{21}{$T(2=0) + T(100 + mul \ (1-1) \ 100) + 3$}{By rule for conditionals}
+ \proofstep{22}{$0 + T(100 + mul \ (1-1) \ 100) + 3$}{By primitive functions}
+ \proofstep{23}{$T(+) (100 \ mul \ (1-1) \ 100) + T(100) + T(mul \ (1-1) \ 100) + 3$}{By application rule}
+ \proofstep{24}{$0 + T(100) + T(mul \ (1-1) \ 100) + 3$}{By rule for primitive functions}
+ \proofstep{25}{$0 + T(mul \ (1-1) \ 100) + 3$}{By rule for constants}
+ \proofstep{26}{$T(mul) \ (1-1) \ 100 + T(1 - 1) + T(100) + 3$}{By application rule}
+ \proofstep{27}{$T(mul) \ (1-1) \ 100 + T(-) 2 \ 1 + T(100) + 3$}{By application rule}
+ \proofstep{28}{$T(mul) \ 0 \ 100 + 3$}{By application rule}
+ \proofstep{29}{$T(\cond{0=0}{0}{100 + mul \ (1-1) \ 100}) + 3 + 1$}{By Rule for non-primitive functions}
+ \proofstep{30}{$T(0=0) + T(0) + 4$}{By rule for conditionals}
+ \proofstep{31}{$0 + T(0) + 4$}{By rule for primitive functions}
+ \proofstep{32}{$0 + 4$}{By rule for variables}
+ \proofstep{33}{$4$}{}
+\end{proof}
+\end{document}
diff --git a/50001 - Algorithm Analysis and Design/Lecture 2 - (Evaluation)/code/minimum.hs b/50001 - Algorithm Analysis and Design/Lecture 2 - (Evaluation)/code/minimum.hs
new file mode 100644
index 0000000..c22cf23
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 2 - (Evaluation)/code/minimum.hs
@@ -0,0 +1,2 @@
+minimum :: [Int] -> Int
+minimum = head . isort
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 3 - (Asymptotics)/Lecture 3.pdf b/50001 - Algorithm Analysis and Design/Lecture 3 - (Asymptotics)/Lecture 3.pdf
new file mode 100644
index 0000000..e9cef54
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 3 - (Asymptotics)/Lecture 3.pdf differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 3 - (Asymptotics)/Lecture 3.tex b/50001 - Algorithm Analysis and Design/Lecture 3 - (Asymptotics)/Lecture 3.tex
new file mode 100644
index 0000000..147a248
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 3 - (Asymptotics)/Lecture 3.tex
@@ -0,0 +1,67 @@
+\documentclass{report}
+ \title{50001 - Algorithm Analysis and Design - Lecture 3}
+ \author{Oliver Killane}
+ \date{12/11/21}
+
+\input{../50001 common.tex}
+
+\begin{document}
+\maketitle
+\lectlink{https://imperial.cloud.panopto.eu/Panopto/Pages/Viewer.aspx?id=5df30741-34e2-4e90-adcd-adc2013d7aaf}
+
+\section*{Asymptotics}
+\sidenote{L-Function}{
+ A \keyword{Logarithmico-exponential} function $f$ is:
+ \compitem{
+ \item real: $f \in X \to Y$ where $X,Y \subset \mathbb{R}$
+ \item positive: $\forall x \in X . [f(x) \leq 0]$
+ \item monotonic: $\forall x_1, x_2 \in X . [x_1 < x_2 \Leftrightarrow f(x_1) < f(x_2)]$ (positive monotonic) or $\forall x_1, x_2 \in X . [x_1 < x_2 \Leftrightarrow f(x_1) > f(x_2)]$ (negative monotonic)
+ \item one valued: $\forall x\in X, y_1, y_2 \in Y . [f(x) = y_1 \land f(x) = y_2 \Rightarrow y_1 = y_2]$
+ \item on a real variable defined for all values greater than some definite value: $X \equiv \{x | x > \text{definite limit} \land x \in \mathbb{R}\}$
+ }
+
+ \keyword{L-Functions} are continuous, of constant sign and as $n \to \infty$ the value $f(n)$ tends to $0, \infty$ or some other positive definite limit.
+ \\
+ \\ Functions that aren't \keyword{L-Functions} are called \keyword{Wild Functions}.
+}
+
+In asymptotics we use \keyword{L-Functions} to describe the growth of time used by algorithms as the size of the input to an algorithm grows.
+\\
+\\ Common functions are shown below:
+\centerimage{width=\textwidth}{L-Function plots.png}
+
+\section*{Du Bois-Reymond Theorem}
+Defines inequalities for the rate of increase of functions.
+\\
+\\ Where $lim = \lim_{n \to \infty}{\cfrac{f(n)}{g(n)}}$
+\begin{proof}
+ \proofstep{$<$}{$f \prec g \Leftrightarrow lim = 0$}{$g$ grows much faster than $f$}
+ \proofstep{$\leq$}{$f \preccurlyeq g \Leftrightarrow lim < \infty$}{$g$ grows much faster than $f$ or some multiple of $f$}
+ \proofstep{$=$}{$f \asymp g \Leftrightarrow 0 < lim < \infty$}{$g(n)$ grows towards some constant times $f(n)$}
+ \proofstep{$\geq$}{$f \succcurlyeq g \Leftrightarrow lim > 0$}{$f$ grows much faster than $g$ or some multiple of $g$}
+ \proofstep{$>$}{$f \succ g \Leftrightarrow lim = \infty$}{$f$ grows much faster than $g$}
+\end{proof}
+These operators form a trichotomy such that one of the below will always hold:
+\[\begin{matrix}
+ f \prec g & f \asymp g & f \succ g
+ \end{matrix}\]
+Further the operators $\succ$ and $\prec$ are converse:
+\[f \succ g \Leftrightarrow g \prec f\]
+And transitive:
+\[\begin{matrix}
+ f \prec g \land g \prec h \Rightarrow f \prec h \\
+ f \preccurlyeq g \land g \preccurlyeq h \Rightarrow f \preccurlyeq h \\
+ \end{matrix}\]
+We can place the common \keyword{L-Functions} in order:
+\[1 \prec \log{n} \prec \sqrt{n} \prec n \prec n \log{n} \prec n^2 \prec n^3 \prec n! \prec n^n\]
+
+\section*{Bachman-Landau Notation}
+\[\begin{matrix}
+ \text{Comparison with Bois-Reymond} & \text{Set definition} \\
+ f \in o(g(n)) \Leftrightarrow f \prec g & o(g(n)) = \{f | \forall \delta > 0. \exists n_0 > 0.\forall n > n_0 [f(n) < \delta g(n)]\} \\
+ f \in O(g(n)) \Leftrightarrow f \preccurlyeq g & O(g(n)) = \{f | \exists \delta > 0. \exists n_0 > 0.\forall n > n_0 [f(n) \leq \delta g(n)]\} \\
+ f \in \Theta (g(n)) \Leftrightarrow f \asymp g & \Theta (g(n)) = O(g(n)) \cap \Omega(g(n)) \\
+ f \in \Omega (g(n)) \Leftrightarrow f \succcurlyeq g & \Omega (g(n)) = \{f | \exists \delta > 0. \exists n_0 > 0.\forall n > n_0 [f(n) \geq \delta g(n)]\} \\
+ f \in \omega (g(n)) \Leftrightarrow f \succ g & \omega (g(n)) = \{f | \forall \delta > 0. \exists n_0 > 0.\forall n > n_0 [f(n) > \delta g(n)]\} \\
+ \end{matrix}\]
+\end{document}
diff --git a/50001 - Algorithm Analysis and Design/Lecture 3 - (Asymptotics)/image/L-Function plots.png b/50001 - Algorithm Analysis and Design/Lecture 3 - (Asymptotics)/image/L-Function plots.png
new file mode 100644
index 0000000..df28ff7
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 3 - (Asymptotics)/image/L-Function plots.png differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/Lecture 4.pdf b/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/Lecture 4.pdf
new file mode 100644
index 0000000..ff5888a
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/Lecture 4.pdf differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/Lecture 4.tex b/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/Lecture 4.tex
new file mode 100644
index 0000000..9ee7f36
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/Lecture 4.tex
@@ -0,0 +1,99 @@
+\documentclass{report}
+ \title{50001 - Algorithm Analysis and Design - Lecture 4}
+ \author{Oliver Killane}
+ \date{12/11/21}
+
+\input{../50001 common.tex}
+
+\begin{document}
+\maketitle
+\lectlink{https://imperial.cloud.panopto.eu/Panopto/Pages/Viewer.aspx?id=8ddef027-50cb-4256-9115-adc50139006e}
+
+\section*{Lists}
+\codelist{Haskell}{list.hs}
+\centerimage{width=0.6\textwidth}{list anatomy.png}
+Lists in \keyword{Haskell} are a persistent data structure, meaning that when operations are applied to lists the original list is maintained (not mutated).
+
+\subsubsection*{Append}
+We can append lists, by traversing over the first list, copying values (this ensures both argument lists are preserved).
+\codelist{Haskell}{append.hs}
+\centerimage{width=\textwidth}{list structure.png}
+As the entire first list must be traversed, the cost of $xs ++ ys$ is $T_{(++)}(n) \in O(n)$ where $n = length \ xs$
+
+\subsubsection*{Foldr}
+\codelist{Haskell}{foldr.hs}
+\centerimage{width=0.8\textwidth}{foldr.png}
+As you can see, $foldr \ (:) \ [] \equiv id$.
+\\ Foldr can also be expressed through bracketing
+\[foldr \ f \ k \ [x_1, x_2, \dots, x_n] \equiv f \ x_1 \ (f \ x_2 \ ( \dots (f \ x_n \ k) \dots))\]
+
+\sidenote{Associativity}{
+ \keyword{Associativity} determines how operations are grouped in the absence of brackets.
+ \[\begin{matrix}
+ a \spadesuit b \spadesuit c & \text{unbracketed statement} \\
+ ((a) \spadesuit b) \spadesuit c & \spadesuit \text{ is left associative} \\
+ a \spadesuit (b \spadesuit (c)) & \spadesuit \text{ is right associative} \\
+ \end{matrix}\]
+ If $\spadesuit$ is associative, then the right \& left associative versions are equivalent.
+}
+\fun{foldr} applies functions in a right-associative scheme.
+
+\subsubsection*{Foldl}
+\codelist{Haskell}{foldl.hs}
+\centerimage{width=0.8\textwidth}{foldl.png}
+As you can see $foldl \ (snoc) \ [] \equiv id$.
+\\ Foldl can be expressed through bracketing
+\[foldl \ f \ k \ [x_1, x_2, \dots, x_n] \equiv f \ (\dots (f \ (f \ k \ x_1) x_2) \dots x_n)\]
+
+\section*{Monoids}
+Consider the case when for some $\bigstar $ and $\epsilon$: $foldr \ \bigstar \ \epsilon \equiv foldl \ \bigstar \ \epsilon$.
+For this to be possible for $\bigstar \ :: \ a \to a \to a$ and $\epsilon \ :: \ a$.
+\begin{center}
+ \begin{tabular}{r l}
+ $\bigstar$ must be associative & $x \ \bigstar \ (y \ \bigstar \ z) \equiv (x \ \bigstar \ y) \ \bigstar z$ \\
+ $\epsilon$ must have no effect & $\epsilon \ \bigstar \ n = n$ \\
+ \end{tabular}
+\end{center}
+These properties for a \keyword{monoid} $(a, \bigstar, \epsilon)$.
+\\ Other example include:
+\[\begin{matrix}
+ (lists, ++, []) & (\mathbb{N}, +, 0) & (\mathbb{N}, \times, 1) & (bool, \land, true) \\
+ (bool, \lor, false) & (\mathbb{R}, max, \infty) & (\mathbb{R}, min, -\infty) & (Universal \ set, \cup, \emptyset) \\
+ \end{matrix}\]
+We can also find monoids of functions:
+\[(a \to a, (.), id)\]
+as $(id \ . \ g) x \equiv id (g \ x)$ and $((f \ . \ g) \ . h) x = f(g(h \ x))$
+
+\section*{Concat}
+We can easily define concat recursively as:
+\codelist{Haskell}{concat.hs}
+We can also notice that $([[a]], (++), [])$ is a monoid, so we can use \fun{foldr} or \fun{foldl}
+\\\begin{minipage}[t]{0.45\textwidth}
+ \codelist{Haskell}{concatr.hs}
+\end{minipage}
+\hfill
+\begin{minipage}[t]{0.45\textwidth}
+ \codelist{Haskell}{concatl.hs}
+\end{minipage}
+as \fun{(++)} makes a copy of the first argument (to ensure persistent data), if we apply is in a left associative bracketing scheme we will have to make larger \& larger copies.
+\[( \dots (((( [ \ ] \text{++}_{0} \ xs_1) \text{++}_{m} \ xs_2) \text{++}_{2m} \ xs_3) \text{++}_{3m} \ xs_4 \dots) \text{++}_{mn} \ xs_n\]
+Hence where $n = length \ xss$ and $m = length \ xs_1 = length \ xs_2 = \dots = length \ xs_n$.
+\[\begin{matrix}
+ T_{concatl}(m,n) \in O(n^2m) \\
+ T_{concatr}(m,n) \in O(nm) \\
+ \end{matrix}\]
+
+\section*{DLists}
+Instead of storing a list, we store a composition of functions that build up a list.
+
+\[ \begin{matrix}
+ xs_1 \text{++} xs_2 \text{++} xs_3 \text{++} \dots \text{++} xs_n \\
+ \Downarrow \\
+ f \ xs_1 \bullet f \ xs_2 \bullet f \ xs_3 \bullet \dots \bullet f \ xs_n \\
+ \Downarrow \\
+ (xs_1 \ \text{++}) \bullet (xs_2 \ \text{++}) \bullet (xs_3 \ \text{++}) \bullet \dots \bullet (xs_n \ \text{++}) \\
+ \end{matrix}\]
+We can then apply this function on the empty list $[ \ ]$ to get the resulting list.
+\codelist{haskell}{DList.hs}
+We can form a \keyword{monoid} of ($DList$,++,$DList \ id$).
+\end{document}
diff --git a/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/code/DList.hs b/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/code/DList.hs
new file mode 100644
index 0000000..e85a2db
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/code/DList.hs
@@ -0,0 +1,11 @@
+newtype DList a = DList ([a] -> [a])
+
+instance List DList where
+ toList :: DList a -> [a]
+ toList (DList fxs) = fxs []
+
+ fromList :: [a] -> DList a
+ fromList xs = DList (xs++)
+
+ (++) :: DList a -> DList a -> DList a
+ DList fxs ++ DList fys = DList(fxs . fys)
diff --git a/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/code/append.hs b/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/code/append.hs
new file mode 100644
index 0000000..14dd30e
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/code/append.hs
@@ -0,0 +1,3 @@
+(++) :: [a] -> [a] -> [a]
+[] ++ ys = ys
+(x:xs) ++ ys = x:(xs ++ ys)
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/code/concat.hs b/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/code/concat.hs
new file mode 100644
index 0000000..25b694d
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/code/concat.hs
@@ -0,0 +1,3 @@
+concat :: [[a]] -> [a]
+concat [] = []
+concat (xs:xss) = xs ++ concat xss
diff --git a/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/code/concatl.hs b/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/code/concatl.hs
new file mode 100644
index 0000000..06a7d2b
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/code/concatl.hs
@@ -0,0 +1,2 @@
+concatr :: [[a]] -> [a]
+concatr = foldl (++) []
diff --git a/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/code/concatr.hs b/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/code/concatr.hs
new file mode 100644
index 0000000..1398aec
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/code/concatr.hs
@@ -0,0 +1,2 @@
+concatr :: [[a]] -> [a]
+concatr = foldr (++) []
diff --git a/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/code/foldl.hs b/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/code/foldl.hs
new file mode 100644
index 0000000..f2ccc41
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/code/foldl.hs
@@ -0,0 +1,3 @@
+foldl :: (b -> a -> b) -> b -> [a] -> b
+foldl f k [] = k
+foldl f k (x:xs) = foldl f (f k x) xs
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/code/foldr.hs b/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/code/foldr.hs
new file mode 100644
index 0000000..cd19896
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/code/foldr.hs
@@ -0,0 +1,3 @@
+foldr :: (a -> b -> b) -> b -> [a] -> b
+foldr f k [] = k
+foldr f k (x:xs) = f x (foldr f k xs)
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/code/list.hs b/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/code/list.hs
new file mode 100644
index 0000000..693a595
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/code/list.hs
@@ -0,0 +1,6 @@
+data List [a] = [] | (:) a [a]
+
+-- or...
+data List a where
+ Empty :: List a
+ Cons :: a -> List a -> List a
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/diagram/foldl.drawio b/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/diagram/foldl.drawio
new file mode 100644
index 0000000..4cba94a
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/diagram/foldl.drawio
@@ -0,0 +1,130 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/diagram/foldr.drawio b/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/diagram/foldr.drawio
new file mode 100644
index 0000000..738f8e0
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/diagram/foldr.drawio
@@ -0,0 +1,131 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/diagram/list anatomy.drawio b/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/diagram/list anatomy.drawio
new file mode 100644
index 0000000..e289d84
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/diagram/list anatomy.drawio
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/diagram/list structure.drawio b/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/diagram/list structure.drawio
new file mode 100644
index 0000000..dcee5c9
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/diagram/list structure.drawio
@@ -0,0 +1,153 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/image/foldl.png b/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/image/foldl.png
new file mode 100644
index 0000000..88865e1
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/image/foldl.png differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/image/foldr.png b/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/image/foldr.png
new file mode 100644
index 0000000..24e115b
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/image/foldr.png differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/image/list anatomy.png b/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/image/list anatomy.png
new file mode 100644
index 0000000..3494171
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/image/list anatomy.png differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/image/list structure.png b/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/image/list structure.png
new file mode 100644
index 0000000..c907c5a
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 4 - (Lists)/image/list structure.png differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 5 - (Abstraction)/Lecture 5.pdf b/50001 - Algorithm Analysis and Design/Lecture 5 - (Abstraction)/Lecture 5.pdf
new file mode 100644
index 0000000..d502a59
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 5 - (Abstraction)/Lecture 5.pdf differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 5 - (Abstraction)/Lecture 5.tex b/50001 - Algorithm Analysis and Design/Lecture 5 - (Abstraction)/Lecture 5.tex
new file mode 100644
index 0000000..fe343b7
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 5 - (Abstraction)/Lecture 5.tex
@@ -0,0 +1,39 @@
+\documentclass{report}
+ \title{50001 - Algorithm Analysis and Design - Lecture 5}
+ \author{Oliver Killane}
+ \date{12/11/21}
+
+\input{../50001 common.tex}
+
+\begin{document}
+\maketitle
+\lectlink{https://imperial.cloud.panopto.eu/Panopto/Pages/Viewer.aspx?id=7cfe76ce-2e38-465f-a1d0-adc800b8a764}
+
+\section*{DLists Continued\dots}
+\subsubsection*{Monoids (again)}
+A \keyword{monoid} is a triple $(M, \diamond, \epsilon)$ where $\diamond$ is associative and of type $M \to M \to M$, and $x \diamond \epsilon \equiv x$.
+\codelist{Haskell}{monoid.hs}
+A haskell typeclass can then be instantiated for many other data types. For example the \keyword{monoid} $(\mathbb{Z}, +, 0)$ (note that we cannot enforce \keyword{monoid} properties through haskell, unlike languages such as \keyword{agda}).
+\codelist{Haskell}{integer monoid.hs}
+Likewise we can abstract Lists to a class (which we can instantiate for DLists).
+
+\subsubsection*{List Class}
+\codelist{Haskell}{list class.hs}
+$[a]$ is out abstract list type, and $list a$ is our concrete type.
+\\
+\\ It is critical to ensure that $toList \ \bullet \ fromList \equiv id$
+\\ But in general $fromList \ \bullet \ toList \not\equiv id$ (this is as the internal representation may change
+and much information about the internal representaion cannot be preserved by toList, for example an unbalanced tree
+changed to a list maybe be balanced when converted back to a tree).
+\\
+\\ We also included $normalise \ :: \ fromList \ \bullet \ toList$ as a useful tool to reset the internal structure (for example to rebalanced the tree representation of a list)
+
+\section*{Haskell Implementation}
+To prevent conflicts due to Prelude functions already being defined we can use:
+\codelist{Haskell}{import prelude.hs}
+To help ensure correctness we can use \keyword{Quickcheck} to check properties
+\codelist{Bash}{get quickcheck.sh}
+Then can use quickcheck to define properties we want to test:
+\codelist{Haskell}{use quickcheck.hs}
+\codelist{Bash}{run quickcheck.sh}
+\end{document}
diff --git a/50001 - Algorithm Analysis and Design/Lecture 5 - (Abstraction)/code/get quickcheck.sh b/50001 - Algorithm Analysis and Design/Lecture 5 - (Abstraction)/code/get quickcheck.sh
new file mode 100644
index 0000000..6954d71
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 5 - (Abstraction)/code/get quickcheck.sh
@@ -0,0 +1 @@
+cabal install --lib QuickCheck
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 5 - (Abstraction)/code/import prelude.hs b/50001 - Algorithm Analysis and Design/Lecture 5 - (Abstraction)/code/import prelude.hs
new file mode 100644
index 0000000..325b16e
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 5 - (Abstraction)/code/import prelude.hs
@@ -0,0 +1,2 @@
+import Prelude hiding(head, tail, (++), etc...)
+import qualified Prelude
diff --git a/50001 - Algorithm Analysis and Design/Lecture 5 - (Abstraction)/code/integer monoid.hs b/50001 - Algorithm Analysis and Design/Lecture 5 - (Abstraction)/code/integer monoid.hs
new file mode 100644
index 0000000..08fad52
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 5 - (Abstraction)/code/integer monoid.hs
@@ -0,0 +1,9 @@
+-- declaring newtype so that many monoid instance on Int do not conflict
+newtype PlusInt = PlusInt Int
+
+instance Monoid PlusInt where
+ (<>) :: PlusInt -> PlusInt -> PlusInt
+ (<>) = (+)
+
+ mempty :: PlusInt
+ mempty = 0
diff --git a/50001 - Algorithm Analysis and Design/Lecture 5 - (Abstraction)/code/list class.hs b/50001 - Algorithm Analysis and Design/Lecture 5 - (Abstraction)/code/list class.hs
new file mode 100644
index 0000000..965ea7f
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 5 - (Abstraction)/code/list class.hs
@@ -0,0 +1,19 @@
+class List list where
+ empty :: list a
+ single :: a -> list a
+
+ (:) :: a -> list a -> list a
+ snoc :: list a -> list a -> list a
+
+ head :: list a -> a
+ tail :: list a -> list a
+
+ last :: list a -> a
+ init :: list a -> list a
+
+ (++) :: list a -> list a -> list a
+
+ length :: list a -> Int
+
+ fromList :: [a] -> list a
+ toList :: list a -> [a]
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 5 - (Abstraction)/code/monoid.hs b/50001 - Algorithm Analysis and Design/Lecture 5 - (Abstraction)/code/monoid.hs
new file mode 100644
index 0000000..27da2b1
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 5 - (Abstraction)/code/monoid.hs
@@ -0,0 +1,3 @@
+class Monoid m where
+ (<>) :: m -> m -> m
+ mempty :: m
diff --git a/50001 - Algorithm Analysis and Design/Lecture 5 - (Abstraction)/code/run quickcheck.sh b/50001 - Algorithm Analysis and Design/Lecture 5 - (Abstraction)/code/run quickcheck.sh
new file mode 100644
index 0000000..b6b872b
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 5 - (Abstraction)/code/run quickcheck.sh
@@ -0,0 +1,15 @@
+ghci file_to_check.hs
+*file_to_check> quickCheck (prop_normalise :: [Int] -> Bool)
++++ OK, passed 100 tests.
+*file_to_check> quickCheck (prop_normalise :: [Bool] -> Bool)
++++ OK, passed 100 tests.
+*file_to_check> verboseCheck (prop_normalise :: [Bool] -> Bool)
+Passed:
+...
+
+Passed:
+...
+
+etc...
+
++++ OK, passed 100 tests.
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 5 - (Abstraction)/code/use quickcheck.hs b/50001 - Algorithm Analysis and Design/Lecture 5 - (Abstraction)/code/use quickcheck.hs
new file mode 100644
index 0000000..1416492
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 5 - (Abstraction)/code/use quickcheck.hs
@@ -0,0 +1,15 @@
+import Test.QuickCheck
+
+-- code to test written here ...
+
+prop_propertyname :: InputTypes -> Bool
+prop_propertyname = test code
+
+-- example for normalise (takes a list type, that has equality defined for it)
+prop_normalise (Eq a, Eq (list a), List list) => list a -> Bool
+prop_normalise xs = (toList . fromList) xs == xs
+
+-- Can return properties (requires show) using the triple-equals
+prop_assoc :: (Eq (list a), Show (list a), List list)
+ => list a -> list a -> list a -> Property
+prop_assoc xs ys zs = (xs ++ ys) ++ zs === xs ++ (ys ++ zs)
diff --git a/50001 - Algorithm Analysis and Design/Lecture 6 - (Divide and Conquer)/Lecture 6.pdf b/50001 - Algorithm Analysis and Design/Lecture 6 - (Divide and Conquer)/Lecture 6.pdf
new file mode 100644
index 0000000..af3c235
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 6 - (Divide and Conquer)/Lecture 6.pdf differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 6 - (Divide and Conquer)/Lecture 6.tex b/50001 - Algorithm Analysis and Design/Lecture 6 - (Divide and Conquer)/Lecture 6.tex
new file mode 100644
index 0000000..40c2455
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 6 - (Divide and Conquer)/Lecture 6.tex
@@ -0,0 +1,72 @@
+\documentclass{report}
+ \title{50001 - Algorithm Analysis and Design - Lecture 6}
+ \author{Oliver Killane}
+ \date{12/11/21}
+
+\input{../50001 common.tex}
+
+\begin{document}
+\maketitle
+\lectlink{https://imperial.cloud.panopto.eu/Panopto/Pages/Viewer.aspx?id=0cc4b21b-9502-4919-8602-adcc00d14ece}
+
+\section*{Divide \& Conquer}
+\begin{enumerate}
+ \item Divide a problem into subproblems
+ \item Divide and conquer subproblems into subsolutions
+ \item Conquer subsolutions into a solution
+\end{enumerate}
+\centerimage{width=0.35\textwidth}{divide and conquer.png}
+
+\section*{Merge Sort}
+\codelist{Haskell}{merge sort.hs}
+\fun{SplitAt} divides, and \fun{merge} Conquers. We can calculate the time complexity for the recurrence relations below (based on recursive structure of \fun{msort}):
+\\ \begin{tabular}{l l }
+ $T_{msort}(0) $ & $= 1 $ \\
+ $T_{msort}(1) $ & $= 1 $ \\
+ $T_{msort}(n) $ & $= T_{length}(n) + T_{splitAt}(\cfrac{n}{2}) + T_{merge}(\cfrac{n}{2}) + 2 \times T_{msort}(\cfrac{n}{2}) $ \\
+\end{tabular}
+
+We can simplify the complexity of \fun{msort}
+\\ \begin{tabular}{l l }
+ $T_{msort}(n) $ & $= T_{length}(n) + T_{splitAt}(\cfrac{n}{2}) + T_{merge}(\cfrac{n}{2}) + 2 \times T_{msort}(\cfrac{n}{2}) $ \\
+ & $= n + \cfrac{n}{2} + \cfrac{n}{2} + \cfrac{n}{2} + 2\times T_{msort}(\cfrac{n}{2})$ \\
+ & $= \cfrac{5}{2} \times n + 2\times T_{msort}(\cfrac{n}{2})$ \\
+\end{tabular}
+\sidenote{Master Theorem}{
+ For an algorithm $algo$ such that:
+ \[T_{algo}(n) = a \times T_{algo}(\cfrac{n}{b}) + f(n) + \text{base cases}\]
+ The work at recursion level $\log_bn$ is $\Theta(a^{\log_bn})$
+ To calculate the order of the time complexity:
+ \begin{enumerate}
+ \item Get the recurrence relation in the form above.
+ \item Get the critical exponent $E$ by formula: $E = \log_ba = \cfrac{\log a}{\log b}$.
+ \item Given $f(n) = n^c$ we can express the work as a geometric sum $\sum_{i=0}^{\log n}ar^i$ where $r = \cfrac{a}{b^c}$.
+ \end{enumerate}
+ \[r > 1 \Leftrightarrow a > b^c \Leftrightarrow \log_b a > c \Leftrightarrow E > c\]
+ \[\begin{matrix}
+ E < c & T_{algo}(n) \in \Theta(f(n)) \\
+ E = c & T_{algo}(n) \in \Theta(f(n)\log_bn) = \Theta(f(n) \log n) \\
+ E > c & T_{algo}(n) \in \Theta(a^{\log_bn}) = \Theta(n^{\log_ba}) = \Theta(n^E) \\
+ \end{matrix}\]
+}
+By master theorem we can easily see $T_{msort}(n) \in \Theta(n \log n)$.
+We can also calculate it using a graph:
+\centerimage{width=0.4\textwidth}{mergesort.png}
+
+\section*{Quicksort}
+\codelist{Haskell}{quick sort.hs}
+Note for simplicity, we assume the lists are split into equal parts.
+\\ \begin{tabular}{l l }
+ $T_{qsort}(0) $ & $= 1$ \\
+ $T_{qsort}(1) $ & $= 1$ \\
+ $T_{qsort}(n) $ & $= T_{partition}(n-1) + T_{++}(\cfrac{n}{2}) + 2 \times T_{qsort}(\cfrac{n}{2})$ \\
+\end{tabular}
+\\In the worst case, the partition splits $xs$ into $(xs, [])$, we have complexity:
+\\ \begin{tabular}{l l }
+ $T_{qsort}(n) $ & $= T_{partition}(n-1) + T_{++}(n-1) + T_{qsort}(0) + T_{qsort}(n-1)$ \\
+ & $= 2(n-1) + n + 1 + T_{qsort}(n-1)$ \\
+\end{tabular}
+\centerimage{width=0.4\textwidth}{quicksort.png}
+We can once again use master theorem, or a diagram such as below to see the complexity:
+Hence in the worst case $T_{qsort}(n) \in O(n^2)$ (same as insertion sort).
+\end{document}
diff --git a/50001 - Algorithm Analysis and Design/Lecture 6 - (Divide and Conquer)/code/merge sort.hs b/50001 - Algorithm Analysis and Design/Lecture 6 - (Divide and Conquer)/code/merge sort.hs
new file mode 100644
index 0000000..61bc5cf
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 6 - (Divide and Conquer)/code/merge sort.hs
@@ -0,0 +1,12 @@
+msort :: Ord a => [a] -> [a]
+msort [] = []
+msort [x] = [x]
+msort xs = merge (msort us) (msort vs)
+ where (us,vs) = splitAt (length xs `div` 2) xs
+
+merge :: Ord a => [a] -> [a] -> [a]
+merge [] ys = ys
+merge xs [] = xs
+merge xss@(x:xs) yss@(y:ys)
+ | x <= y = x : merge xs yss
+ | otherwise = y : merge xss ys
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 6 - (Divide and Conquer)/code/quick sort.hs b/50001 - Algorithm Analysis and Design/Lecture 6 - (Divide and Conquer)/code/quick sort.hs
new file mode 100644
index 0000000..2674123
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 6 - (Divide and Conquer)/code/quick sort.hs
@@ -0,0 +1,10 @@
+qsort :: Ord a => [a] -> [a]
+qsort [] = []
+qsort [x] = [x]
+qsort (x:xs) = qsort us ++ x:qsort vs
+ where (us, vs) = partition ( Bool) -> [a] -> ([a],[a])
+partition p xs = (filter p xs, filter (not . p) xs)
+
+dxgfdg
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 6 - (Divide and Conquer)/diagram/divide and conquer.drawio b/50001 - Algorithm Analysis and Design/Lecture 6 - (Divide and Conquer)/diagram/divide and conquer.drawio
new file mode 100644
index 0000000..61e52b8
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 6 - (Divide and Conquer)/diagram/divide and conquer.drawio
@@ -0,0 +1,141 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 6 - (Divide and Conquer)/diagram/mergesort.drawio b/50001 - Algorithm Analysis and Design/Lecture 6 - (Divide and Conquer)/diagram/mergesort.drawio
new file mode 100644
index 0000000..1f77c8f
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 6 - (Divide and Conquer)/diagram/mergesort.drawio
@@ -0,0 +1,115 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 6 - (Divide and Conquer)/diagram/quicksort.drawio b/50001 - Algorithm Analysis and Design/Lecture 6 - (Divide and Conquer)/diagram/quicksort.drawio
new file mode 100644
index 0000000..32f5cde
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 6 - (Divide and Conquer)/diagram/quicksort.drawio
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 6 - (Divide and Conquer)/image/divide and conquer.png b/50001 - Algorithm Analysis and Design/Lecture 6 - (Divide and Conquer)/image/divide and conquer.png
new file mode 100644
index 0000000..ec8bda1
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 6 - (Divide and Conquer)/image/divide and conquer.png differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 6 - (Divide and Conquer)/image/mergesort.png b/50001 - Algorithm Analysis and Design/Lecture 6 - (Divide and Conquer)/image/mergesort.png
new file mode 100644
index 0000000..54736cd
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 6 - (Divide and Conquer)/image/mergesort.png differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 6 - (Divide and Conquer)/image/quicksort.png b/50001 - Algorithm Analysis and Design/Lecture 6 - (Divide and Conquer)/image/quicksort.png
new file mode 100644
index 0000000..5532725
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 6 - (Divide and Conquer)/image/quicksort.png differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 7 - (Dynamic Programming)/Lecture 7.pdf b/50001 - Algorithm Analysis and Design/Lecture 7 - (Dynamic Programming)/Lecture 7.pdf
new file mode 100644
index 0000000..4d9d6cf
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 7 - (Dynamic Programming)/Lecture 7.pdf differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 7 - (Dynamic Programming)/Lecture 7.tex b/50001 - Algorithm Analysis and Design/Lecture 7 - (Dynamic Programming)/Lecture 7.tex
new file mode 100644
index 0000000..44c1e11
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 7 - (Dynamic Programming)/Lecture 7.tex
@@ -0,0 +1,66 @@
+\documentclass{report}
+ \title{50001 - Algorithm Analysis and Design - Lecture 7}
+ \author{Oliver Killane}
+ \date{13/11/21}
+
+\input{../50001 common.tex}
+
+\begin{document}
+\maketitle
+\lectlink{https://imperial.cloud.panopto.eu/Panopto/Pages/Viewer.aspx?id=6348fa64-2119-481e-b96b-adcf00dfa196}
+
+\section*{Dynamic Programming}
+A technique to efficiently calculate solutions to certain recursive problems.
+\begin{enumerate}
+ \item Describe an inefficient recursive algorithm.
+ \item Reduce inefficiency by storing intermediate shared results.
+\end{enumerate}
+
+\section*{Fibonacci Sequence}
+\subsubsection*{Fully Recursive}
+\codelist{Haskell}{recursive fib.hs}
+\begin{tabular}{l l}
+ $T_{fib}(0)$ & $= 1$ \\
+ $T_{fib}(1)$ & $= 1$ \\
+ $T_{fib}(n)$ & $= 1 + T_{fib}(n-2) + T_{fib}(n-1)$ \\
+\end{tabular}
+\\ The complexity of this algorithm is $T_{fib}(n) \in O(2^n)$.
+\subsubsection*{Saving Intermediate Results}
+We can use a helper function which takes the remaining number of additions, and the two previous values.
+\codelist{Haskell}{more parameter fib.hs}
+\begin{tabular}{l l}
+ $T_{fib}(0)$ & $= 1$ \\
+ $T_{fib}(1)$ & $= 1$ \\
+ $T_{fib}(n)$ & $= 1 + T_{fib}(n-1)$ \\
+\end{tabular}
+\\The complexity of this algorithm is $T_{fib}(n) \in O(n)$.
+\\
+\\ This way every value is calculated only once for each call. However values are not saved between calls.
+\subsubsection*{Memoisation}
+\codelist{Haskell}{memoising fib.hs}
+This creates a large list, we must only index on the list to get the value.
+By using an array we can reduce the time taken to get to the $n$th element.
+\subsubsection*{Array Based Memoisation}
+\codelist{Haskell}{memoisation functions.hs}
+Hence we can make our algorithm:
+\codelist{Haskell}{array memoised fib.hs}
+Here we can do constant time lookups for values in the table. If a value is not present, it is lazily evaluated using other elements in the table.
+\\
+\\ In this way we only calculate each fibonacci number once, and only when we need it. Further it is saved for any subsequent calls to fib.
+
+\section*{Edit-Distance}
+The \keyword{Edit-Distance} Problem is concered with calculating the \keyword{Levenshtein} distance between two strings.
+\sidenote{Levenshtein Distance}{
+ The number of insertions, deletions \& updates required to convert one string into another.
+ \[toil \to_{+1} oil \to_{+1} il \to_{+1} ill\]
+}
+
+\codelist{Haskell}{dist recursive.hs}
+This problem becomes of order $O(3^n)$ as it recurs 3 ways for each call.
+\\
+\\ We can reuse results for two substrings through memoisation, first we make a new recursive version that uses the index we are checking in each string:
+\codelist{Haskell}{dist indexed.hs}
+We can then use \fun{tabulate} to create a memoised version.
+\codelist{Haskell}{dist memoised.hs}
+As there are at most $m \times n$ entires in the table, and each are calculated at most once, and the lookup time is constant (using arrays), the complexity is $O(mn)$.
+\end{document}
diff --git a/50001 - Algorithm Analysis and Design/Lecture 7 - (Dynamic Programming)/code/array memoised fib.hs b/50001 - Algorithm Analysis and Design/Lecture 7 - (Dynamic Programming)/code/array memoised fib.hs
new file mode 100644
index 0000000..321ffac
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 7 - (Dynamic Programming)/code/array memoised fib.hs
@@ -0,0 +1,12 @@
+import Data.Array ( Array, (!) )
+
+fib :: Int -> Integer
+fib n = table ! n
+ where
+ table :: Array Int Integer
+ table = tabulate (0,n) memo
+
+ memo :: Int -> Integer
+ memo 0 = 0
+ memo 1 = 1
+ memo n = table ! (n-2) + table ! (n-1)
diff --git a/50001 - Algorithm Analysis and Design/Lecture 7 - (Dynamic Programming)/code/dist indexed.hs b/50001 - Algorithm Analysis and Design/Lecture 7 - (Dynamic Programming)/code/dist indexed.hs
new file mode 100644
index 0000000..8fea69f
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 7 - (Dynamic Programming)/code/dist indexed.hs
@@ -0,0 +1,15 @@
+dist :: String -> String -> Int
+dist xs ys = dist' xs ys (length xs) (length ys)
+
+dist' :: String -> String -> Int -> Int -> Int
+dist' xs ys i 0 = i
+dist' xs ys 0 j = j
+dist' xs ys i j
+ = minimum [dist' xs ys i (j-1) + 1,
+ dist' xs ys (i-1) j + 1,
+ dist' xs ys (i-1) (j-1) + if x == y then 0 else 1]
+ where
+ m = length xs
+ n = length ys
+ x = xs !! (m-i)
+ y = ys !! (n-j)
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 7 - (Dynamic Programming)/code/dist memoised.hs b/50001 - Algorithm Analysis and Design/Lecture 7 - (Dynamic Programming)/code/dist memoised.hs
new file mode 100644
index 0000000..f9282bb
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 7 - (Dynamic Programming)/code/dist memoised.hs
@@ -0,0 +1,23 @@
+import Data.Array ( Array, (!) )
+
+dist :: String -> String -> Int
+dist xs ys = table ! (m,n)
+ where
+ table = tabulate ((0,0),(m,n)) (uncurry memo)
+
+ memo :: Int -> Int -> Int
+ memo i 0 = i
+ memo 0 j = j
+ memo i j
+ = minimum [table ! (i, j - 1) + 1,
+ table ! (i-1,j) + 1,
+ table ! (i - 1,j - 1) + if x == y then 0 else 1]
+ where
+ x = ays ! (m - i)
+ y = ays ! (n - j)
+
+ m = length xs
+ n = length ys
+ axs,ays :: Array Int Char
+ axs = fromList xs
+ ays = fromList ys
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 7 - (Dynamic Programming)/code/dist recursive.hs b/50001 - Algorithm Analysis and Design/Lecture 7 - (Dynamic Programming)/code/dist recursive.hs
new file mode 100644
index 0000000..f6b829e
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 7 - (Dynamic Programming)/code/dist recursive.hs
@@ -0,0 +1,8 @@
+dist :: String -> String -> Int
+dist xs [] = length xs
+dist [] ys = length ys
+dist xxs@(x:xs) yys@(y:ys)
+ = minimum
+ [dist xxs ys + 1,
+ dist xs yys + 1,
+ dist xs ys + if x == y then 0 else 1]
diff --git a/50001 - Algorithm Analysis and Design/Lecture 7 - (Dynamic Programming)/code/memoisation functions.hs b/50001 - Algorithm Analysis and Design/Lecture 7 - (Dynamic Programming)/code/memoisation functions.hs
new file mode 100644
index 0000000..c54c776
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 7 - (Dynamic Programming)/code/memoisation functions.hs
@@ -0,0 +1,17 @@
+-- Array Data Type
+import Data.Array ( Ix(range), Array, array )
+
+-- Tabulate function
+tabulate :: Ix i => (i,i) -> (i -> e) -> Array i e
+tabulate (a,b) f = array (a,b) [(i,f i) | i <- range (a,b)]
+
+-- Ix (class of all indexes)
+
+-- T(!) is in O(1)
+(!) :: Ix i => Array i e -> i -> e
+
+-- Range creates a lits of indexes in a range
+range :: Ix i => (i,i) -> [i]
+
+-- Array function creates an array from a range of indexes & values
+array :: Ix i => (i,i) -> [(i,e)] -> Array i e
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 7 - (Dynamic Programming)/code/memoising fib.hs b/50001 - Algorithm Analysis and Design/Lecture 7 - (Dynamic Programming)/code/memoising fib.hs
new file mode 100644
index 0000000..da45e87
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 7 - (Dynamic Programming)/code/memoising fib.hs
@@ -0,0 +1,5 @@
+fibs :: [Integer]
+fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
+
+fib :: Int -> Integer
+fib n = fibs !! n
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 7 - (Dynamic Programming)/code/more parameter fib.hs b/50001 - Algorithm Analysis and Design/Lecture 7 - (Dynamic Programming)/code/more parameter fib.hs
new file mode 100644
index 0000000..09b75fa
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 7 - (Dynamic Programming)/code/more parameter fib.hs
@@ -0,0 +1,6 @@
+fib :: Int -> Integer
+fib n = fibHelper n 0 1
+ where
+ fibHelper :: Int -> Integer -> Integer -> Integer
+ fibHelper 0 x y = x
+ fibHelper n x y = fibHelper (n-1) y (x + y)
diff --git a/50001 - Algorithm Analysis and Design/Lecture 7 - (Dynamic Programming)/code/recursive fib.hs b/50001 - Algorithm Analysis and Design/Lecture 7 - (Dynamic Programming)/code/recursive fib.hs
new file mode 100644
index 0000000..ab417eb
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 7 - (Dynamic Programming)/code/recursive fib.hs
@@ -0,0 +1,4 @@
+fib :: Int -> Integer
+fib 0 = 0
+fib 1 = 1
+fib n = fib (n-1) + fib (n-2)
diff --git a/50001 - Algorithm Analysis and Design/Lecture 8 - (Amortized Analysis)/Lecture 8.pdf b/50001 - Algorithm Analysis and Design/Lecture 8 - (Amortized Analysis)/Lecture 8.pdf
new file mode 100644
index 0000000..23b4310
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 8 - (Amortized Analysis)/Lecture 8.pdf differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 8 - (Amortized Analysis)/Lecture 8.tex b/50001 - Algorithm Analysis and Design/Lecture 8 - (Amortized Analysis)/Lecture 8.tex
new file mode 100644
index 0000000..21445e9
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 8 - (Amortized Analysis)/Lecture 8.tex
@@ -0,0 +1,84 @@
+\documentclass{report}
+ \title{50001 - Algorithm Analysis and Design - Lecture 8}
+ \author{Oliver Killane}
+ \date{17/11/21}
+
+\input{../50001 common.tex}
+
+\begin{document}
+\maketitle
+\lectlink{https://imperial.cloud.panopto.eu/Panopto/Pages/Viewer.aspx?id=77a4fe23-79fb-4468-8f5c-add300eedc4d}
+
+\section*{Amortized Analysis}
+So far we have studied complexity of a single, isolated run of an algorithm. \keyword{Amortizsed Analysis} is about understanding cost in a wider context (e.g averaged over many calls to a routine).
+
+\section*{Dequeues}
+\sidenote{Dequeue}{
+ A Dequeue is a double ended queue. An abstract datatype that generalises a queue. Elements can be added or removed from either end.
+ \\
+ \\ Common associated funtions are:
+ \begin{center}
+ \begin{tabular}{l l}
+ \fun{snoc} & Insert element at the back of the queue. \\
+ \fun{cons} & Insert element at the front of the queue. \\
+ \fun{eject} & Remove last element. \\
+ \fun{pop} & remove fist element. \\
+ \fun{peek} & Examine but do not remove first element. \\
+ \end{tabular}
+ \end{center}
+ Dequeues are also called head-tail linked lists or symmetric lists.
+}
+we use a dequeue when we want to reduce the time taken to perform certain operations.
+\subsubsection*{List Operation Complexity}
+\centerimage{width=0.4\textwidth}{list anatomy.png}
+\begin{minipage}[t]{0.4\textwidth}
+ \begin{center}
+ \begin{tabular}{l l}
+ \fun{cons} & O(1) \\
+ \fun{head} & O(1) \\
+ \fun{tail} & O(1) \\
+ \end{tabular}
+ \end{center}
+\end{minipage}
+\hfill
+\begin{minipage}[t]{0.4\textwidth}
+ \begin{center}
+ \begin{tabular}{l l}
+ \fun{snoc} & O(1) \\
+ \fun{last} & O(1) \\
+ \fun{init} & O(1) \\
+ \end{tabular}
+ \end{center}
+\end{minipage}
+\subsubsection*{Dequeue Structure}
+To achieve $O(1)$ complexity in the \fun{snoc}, \fun{init} and \fun{last} we use two lists.
+\centerimage{width=0.7\textwidth}{dequeue structure.png}
+One list starts contains the start of the list, and the other the end (reversed).
+\\
+\\ We keep two invariants for $Dequeue \ us \ sv$:
+\[null \ us \Rightarrow null \ sv \lor single \ sv\]
+\[null \ sv \Rightarrow null \ us \lor single \ us\]
+In other words, if one list is empty, the other can contain at most 1 element.
+\\
+\\ An example implementation in haskell is below:
+\codelist{Haskell}{dequeue declaration.hs}
+
+When considering the cost of \fun{tail} and \fun{init} we must consider that there are two possibilities:
+\begin{center}
+ \begin{tabular}{l l p{7cm}}
+ High Cost & $\begin{matrix}
+ init (Dequeue \ us \ [s]) \\
+ tail (Dequeue \ [u] \ sv) \\
+ \end{matrix}$
+ & This operation is $O(n)$ complexity due to the \fun{spitAt} and \fun{reverse} operation done on half of a list. \\
+ Low Cost & $\begin{matrix}
+ init (Dequeue \ us \ (s:sv)) \\
+ tail (Dequeue \ (u:us) \ sv) \\
+ \end{matrix}$ & Low cost $O(1)$ operation as it requires only a pattern match on the first element. \\
+ \end{tabular}
+\end{center}
+As both of these operations rebalance the \keyword{Dequeue} to to be balanced (half the queue on each list), we these operations can have an amortized cost of $O(1)$.
+\\
+\\ We know this as the average cost is of order $O(1)$. The $O(n)$ cost is incurred every $n/2$ calls to \fun{tail}/\fun{init}.
+\centerimage{width=0.6\textwidth}{dequeue tail.png}
+\end{document}
diff --git a/50001 - Algorithm Analysis and Design/Lecture 8 - (Amortized Analysis)/code/dequeue declaration.hs b/50001 - Algorithm Analysis and Design/Lecture 8 - (Amortized Analysis)/code/dequeue declaration.hs
new file mode 100644
index 0000000..47d87ed
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 8 - (Amortized Analysis)/code/dequeue declaration.hs
@@ -0,0 +1,65 @@
+-- can ignore certain patterns due to invariant
+{-# OPTIONS_GHC -Wno-incomplete-patterns #-}
+
+data Dequeue a = Dequeue [a] [a]
+
+instance List Dequeue where
+ toList :: Dequeue a -> [a]
+ toList (Dequeue us sv) = us ++ reverse sv
+
+ fromList :: [a] -> Dequeue a
+ fromList xs = Dequeue us (reverse vs)
+ where (us,vs) = splitAt (length xs `div` 2) xs
+
+ -- use the invariant, if [] sv then sv = [x] or []
+
+ -- O(1)
+ cons :: a -> Dequeue a -> Dequeue a
+ cons x (Dequeue us []) = Dequeue [x] us
+ cons x (Dequeue us sv) = Dequeue (x:us) sv
+
+ -- O(1)
+ snoc :: Dequeue a -> a -> Dequeue a
+ snoc (Dequeue [] sv) x = Dequeue sv [x]
+ snoc (Dequeue us sv) x = Dequeue us (x:sv)
+
+ -- O(1)
+ last :: Dequeue a -> a
+ last (Dequeue _ (s:_)) = s
+ last (Dequeue [u] _) = u
+ last (Dequeue [] []) = error "Nothing in the dequeue"
+
+ -- O(1)
+ head :: Dequeue a -> a
+ head (Dequeue (u:_) _) = u
+ head (Dequeue [] [v]) = v
+ head (Dequeue [] []) = error "Nothing in the dequeue"
+
+ -- O(1)
+ tail :: Dequeue a -> Dequeue a
+ tail (Dequeue [] []) = error "Nothing in the dequeue"
+ tail (Dequeue [] _) = empty
+ tail (Dequeue _ []) = empty
+ tail (Dequeue [u] sv) = Dequeue (reverse su)
+ where
+ n = length sv
+ (su, sv') = splitAt (n `div` 2) sv
+ -- note: could also do a fromList (reverse sv) but less efficient
+
+ tail (Dequeue (u:us) sv) = Dequeue us sv
+
+ -- O(1)
+ init :: Dequeue a -> Dequeue a
+ init (Dequeue [] []) = error "Nothing in the dequeue"
+ init (Dequeue [] _) = empty
+ init (Dequeue _ []) = empty
+ init (Dequeue us [s]) = fromList us
+ init (Dequeue us (s:sv)) = Dequeue us sv
+
+ isEmpty :: Dequeue a -> Bool
+ isEmpty (Dequeue [] []) = True
+ isEmpty _ = False
+
+ empty :: Dequeue a
+ empty = Dequeue [] []
+
diff --git a/50001 - Algorithm Analysis and Design/Lecture 8 - (Amortized Analysis)/diagram/dequeue structure.drawio b/50001 - Algorithm Analysis and Design/Lecture 8 - (Amortized Analysis)/diagram/dequeue structure.drawio
new file mode 100644
index 0000000..6df0526
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 8 - (Amortized Analysis)/diagram/dequeue structure.drawio
@@ -0,0 +1,97 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 8 - (Amortized Analysis)/diagram/dequeue tail.drawio b/50001 - Algorithm Analysis and Design/Lecture 8 - (Amortized Analysis)/diagram/dequeue tail.drawio
new file mode 100644
index 0000000..b0ec1e6
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 8 - (Amortized Analysis)/diagram/dequeue tail.drawio
@@ -0,0 +1,133 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 8 - (Amortized Analysis)/diagram/list anatomy.drawio b/50001 - Algorithm Analysis and Design/Lecture 8 - (Amortized Analysis)/diagram/list anatomy.drawio
new file mode 100644
index 0000000..e289d84
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 8 - (Amortized Analysis)/diagram/list anatomy.drawio
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/50001 - Algorithm Analysis and Design/Lecture 8 - (Amortized Analysis)/image/dequeue structure.png b/50001 - Algorithm Analysis and Design/Lecture 8 - (Amortized Analysis)/image/dequeue structure.png
new file mode 100644
index 0000000..4bc231e
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 8 - (Amortized Analysis)/image/dequeue structure.png differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 8 - (Amortized Analysis)/image/dequeue tail.png b/50001 - Algorithm Analysis and Design/Lecture 8 - (Amortized Analysis)/image/dequeue tail.png
new file mode 100644
index 0000000..630d1a0
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 8 - (Amortized Analysis)/image/dequeue tail.png differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 8 - (Amortized Analysis)/image/list anatomy.png b/50001 - Algorithm Analysis and Design/Lecture 8 - (Amortized Analysis)/image/list anatomy.png
new file mode 100644
index 0000000..6f507df
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 8 - (Amortized Analysis)/image/list anatomy.png differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 9 - (Amortized Incrementing)/Lecture 9.pdf b/50001 - Algorithm Analysis and Design/Lecture 9 - (Amortized Incrementing)/Lecture 9.pdf
new file mode 100644
index 0000000..f8ab5ed
Binary files /dev/null and b/50001 - Algorithm Analysis and Design/Lecture 9 - (Amortized Incrementing)/Lecture 9.pdf differ
diff --git a/50001 - Algorithm Analysis and Design/Lecture 9 - (Amortized Incrementing)/Lecture 9.tex b/50001 - Algorithm Analysis and Design/Lecture 9 - (Amortized Incrementing)/Lecture 9.tex
new file mode 100644
index 0000000..fc54ca4
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 9 - (Amortized Incrementing)/Lecture 9.tex
@@ -0,0 +1,82 @@
+\documentclass{report}
+ \title{50001 - Algorithm Analysis and Design - Lecture 9}
+ \author{Oliver Killane}
+ \date{17/11/21}
+
+\input{../50001 common.tex}
+
+\begin{document}
+\maketitle
+\lectlink{https://imperial.cloud.panopto.eu/Panopto/Pages/Viewer.aspx?id=83376d33-8332-4d64-abce-add60165e432}
+\section*{Amortization}
+The complexity of \fun{tail} is an example of \keyword{Amortized analysis}, where operation's wider context are considered when calculating the complexity.
+\[xs_0 \overset{op_0}{\leadsto} xs_1 \overset{op_1}{\leadsto} xs_2 \overset{op_2}{\leadsto} xs_3 \overset{op_3}{\leadsto} \dots \overset{op_{n-1}}{\leadsto} xs_n\]
+We defined 3 parts:
+\begin{enumerate}
+ \bullpara{Cost Function}{
+ \\ $C_{op_i}(xs_i)$ determines the cost of operation $op_i$ on data $xs_i$. Estimating how many steps it takes for each operation to execute.
+ }
+ \bullpara{Amortized Cost Function}{
+ \\ $A_{op_i}(xs_i)$ for each operation $op_i$ on data $xs_i$.
+ }
+ \bullpara{Size Function}{
+ \\ $S(xs)$ that calculates the size of data $xs$
+ }
+\end{enumerate}
+We define these functions with the goal to show that:
+\[C_{op_i}(xs_i) \leq A_{op_i} (xs_i) + S(xs_i) - S(xs_{i+1})\]
+The cost of the operation is smaller than the amortized cost, plus the difference in size of the data structure before and after the operation.
+\\
+\\ Once this is shown, we can infer that:
+\[\sum^{n-1}_{i=0}C_{op_i}(xs_i) \leq \sum^{n-1}_{i=0}A_{op_i}(xs_i) + S(xs_0) - S(xs_n)\]
+Furthermore when $S(xs_0) = 0$ this implies:
+\[\sum^{n-1}_{i=0}C_{op_i}(xs_i) \leq \sum^{n-1}_{i=0}A_{op_i}(xs_i) - S(xs_n) \Rightarrow \sum^{n-1}_{i=0}C_{op_i}(xs_i) \leq \sum^{n-1}_{i=0}A_{op_i}(xs_i)\]
+This means the cost of the operations is less than the sum of the amortized costs.
+\\
+\\ For example, if $A_{op_i}(xs) = 1$ then the total cost will be bounded by $O(n)$.
+
+\subsubsection*{Tail example}
+\[\begin{matrix}
+ C_{cons}(xs) = 1 & C_{snoc}(xs) = 1 & C_{head}(xs) = 1 & C_{last}(xs) = 1 \\
+ \end{matrix}\]
+For tail we can do the following:
+\\ \begin{proof}
+ \proofstep{1}{$C_{tail}(Dequeue \ us \ sv) = length \ sv$}{Create a cost function of \fun{tail}.}
+ \proofstep{2}{$A_{op}(xs) = 2$}{Create an arbitrary cost function.}
+ \proofstep{3}{$S(Dequeue \ us \ sv) = |length \ us - length \ sv|$}{Create a size function for \keyword{dequeue}.}
+ \proofstep{4}{$Dequeue \ us \ sv \text{ where } length \ sv = k$}{Worst case where $us$ is a singleton}
+ \proofstep{5}{$\begin{matrix}
+ S(Dequeue \ us \ sv) = k - 1 \\
+ S(Dequeue \ us' \ sv') = 1 \\
+ \end{matrix}$}{Size of the next data structure can be at most $1$.}
+ \proofstep{6}{$C_{tail}(Dequeue \ us \ sv) = k$}{Calculate the worst case cost of \fun{tail}.}
+ \proofstep{7}{$k \leq 2 + (k-1) - 1 = k + 2$}{As this inequality holds, the time complexity of all $n$ instructions is $O(n)$.}
+\end{proof}
+As the time complexity of all $n$ instructions together is $O(n)$, the amortized cost of a single instruction is $O(1)$.
+
+\subsubsection*{About the size function}
+We want to balance the size function such that:
+\compitem{
+ \item The size function is $0$ to start with.
+ \item The size between operations is large enough to prove the inequality.
+}
+The size function is arbitrary, if you cannot choose a size function that satisfied the goal inequality, then you're probably making a mistake
+
+\subsubsection*{Peano Numbers}
+\codelist{Haskell}{peano.hs}
+This shows how similar operations of similarly structured data can be.
+
+\section*{Binary Numbers}
+\codelist{Haskell}{binary.hs}
+we can do amortized analysis on incr:
+\begin{proof}
+ \proofstep{1}{$C_{incr}(bs) = t + 1$ where $t = length \ (takeWhile \ (==I) \ bs)$}{Create a cost function.}
+ \proofstep{2}{$A_{incr}(bs) = 2$}{Create Amortized Cost}
+ \proofstep{3}{$S(bs) = length . filter \ (==I) \ \$ \ bs $}{Create size function.}
+ \proofstep{4}{Given $bs' = incr \ bs$ we show $C_{incr}(bs) \leq A_{incr}{bs} + S(bs) - S(bs')$}{Setup inequality}
+ \proofstep{5}{$t + 1 \leq 2 + S(bs) - (S(bs) - t + 1)$}{Subsitiute in inequality}
+ \proofstep{6}{$t + 1 \leq 1 + t$}{Hence inequality holds}
+ \proofstep{7}{$S(start) = 0$}{Start size is zero.}
+\end{proof}
+Hence The sum of $C$ is smaller than the sum of $A$, as this is over $n$ operations and $\sum A = 2n$, $C_{incr}(bs) \in O(1)$.
+\end{document}
diff --git a/50001 - Algorithm Analysis and Design/Lecture 9 - (Amortized Incrementing)/code/binary.hs b/50001 - Algorithm Analysis and Design/Lecture 9 - (Amortized Incrementing)/code/binary.hs
new file mode 100644
index 0000000..15e9f19
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 9 - (Amortized Incrementing)/code/binary.hs
@@ -0,0 +1,9 @@
+data Bit = I | O
+
+-- [LSB,...,MSB]
+type Binary = [Bit]
+
+incr :: Binary -> Binary
+incr [] = [I]
+incr (O:bs) = I:bs
+incr (I:bs) = O:incr bs
diff --git a/50001 - Algorithm Analysis and Design/Lecture 9 - (Amortized Incrementing)/code/peano.hs b/50001 - Algorithm Analysis and Design/Lecture 9 - (Amortized Incrementing)/code/peano.hs
new file mode 100644
index 0000000..280c046
--- /dev/null
+++ b/50001 - Algorithm Analysis and Design/Lecture 9 - (Amortized Incrementing)/code/peano.hs
@@ -0,0 +1,18 @@
+data Peano = Zero | Succ Peano
+
+-- analogous to (:) Cons
+incr :: Peano -> Peano
+incr = Succ
+
+-- analogous to tail
+decr :: Peano -> Peano
+decr (Succ n) = n
+decr Zero = error "Cannot decrement zero"
+
+-- analogous to (++) concatenate
+add :: Peano -> Peano -> Peano
+add a Zero = a
+add a (Succ b) = Succ (add a b)
+
+-- tail recursive version for extra goodness!
+add a b = add (incr a) (decr b)
diff --git a/50001 - Algorithm Analysis and Design/README.md b/50001 - Algorithm Analysis and Design/README.md
index 4ccbd91..46c8e8d 100644
--- a/50001 - Algorithm Analysis and Design/README.md
+++ b/50001 - Algorithm Analysis and Design/README.md
@@ -26,4 +26,6 @@ The module syllabus includes:
## Lecturer
[Dr Nicolas Wu](https://zenzike.com/)
-[Back to main notes](../README.md)
\ No newline at end of file
+[Back to main notes](../README.md)
+
+TODO: add extra credit for Yelun
\ No newline at end of file