% vim: set ts=2 sw=2 tw=80 et:
\documentclass[12pt]{article}

\usepackage[margin=3cm]{geometry}
\usepackage{xcolor}
\usepackage{lmodern}
\usepackage{listings}

\title{Graded Assignment 2 -- DSA}
\author{Claudio Maggioni}

% listings configuration
\lstset{
  basicstyle=\small\ttfamily,
  frame=shadowbox,
  rulesepcolor=\color{black},
  columns=fullflexible,
  commentstyle=\color{gray},
  keywordstyle=\bfseries,
  keywords={,while,if,elif,else,FUNCTION,return,for,from,to,TRUE,FALSE},
  mathescape=true,
  aboveskip=2em,
  captionpos=b,
  abovecaptionskip=1em,
  belowcaptionskip=1em
}

\begin{document}

\maketitle
\tableofcontents
\lstlistoflistings
\newpage

\section{Exercise 1}

\subsection{Mergesort}

\begin{verbatim}
[5, 6, 12, 8, 4, 10, 3, 12, 11, 1]
[5, 6, 12, 8, 4] [10, 3, 12, 11, 1]
[5, 6, 12, 8, 4]
[5, 6], [12, 8, 4]
[5, 6]
[5], [6]
[5]
[6]
[5, 6]
[12, 8, 4]
[12] [8, 4]
[12]
[8, 4]
[8], [4]
[8]
[4]
[4, 8]
[4, 8, 12]
[4, 5, 6, 8, 12]
[10, 3, 12, 11, 1]
[10, 3], [12, 11, 1]
[10], [3]
[10]
[3]
[3, 10]
[12, 11, 1]
[12], [11, 1]
[12]
[11, 1]
[11], [1]
[11]
[1]
[1, 11]
[1, 11, 12]
[1, 3, 10, 11, 12]
[1, 3, 4, 5, 6, 8, 10, 11, 12, 12]
\end{verbatim}

\subsection{Selection sort}
\begin{verbatim}
[4, 6, 12, 8, 5, 10, 3, 12, 11, 1]
[3, 6, 12, 8, 5, 10, 4, 12, 11, 1]
[1, 6, 12, 8, 5, 10, 4, 12, 11, 3]
[1, 5, 12, 8, 6, 10, 4, 12, 11, 3]
[1, 4, 12, 8, 6, 10, 5, 12, 11, 3]
[1, 3, 12, 8, 6, 10, 5, 12, 11, 4]
[1, 3, 8, 12, 6, 10, 5, 12, 11, 4]
[1, 3, 6, 12, 8, 10, 5, 12, 11, 4]
[1, 3, 5, 12, 8, 10, 6, 12, 11, 4]
[1, 3, 4, 12, 8, 10, 6, 12, 11, 5]
[1, 3, 4, 8, 12, 10, 6, 12, 11, 5]
[1, 3, 4, 6, 12, 10, 8, 12, 11, 5]
[1, 3, 4, 5, 12, 10, 8, 12, 11, 6]
[1, 3, 4, 5, 10, 12, 8, 12, 11, 6]
[1, 3, 4, 5, 8, 12, 10, 12, 11, 6]
[1, 3, 4, 5, 6, 12, 10, 12, 11, 8]
[1, 3, 4, 5, 6, 10, 12, 12, 11, 8]
[1, 3, 4, 5, 6, 8, 12, 12, 11, 10]
[1, 3, 4, 5, 6, 8, 11, 12, 12, 10]
[1, 3, 4, 5, 6, 8, 10, 12, 12, 11]
[1, 3, 4, 5, 6, 8, 10, 11, 12, 12]
[1, 3, 4, 5, 6, 8, 10, 11, 12, 12]
\end{verbatim}

\subsection{Quicksort}
\begin{verbatim}
[5, 6, 12, 8, 4, 10, 3, 12, 11, 1]
[5, 6, 3, 1, 4] 8 [12, 12, 11, 10]
[] 1 [6, 3, 4, 5]
[] 3 [5, 4, 6]
[5, 4] 6 []
[4] 5 []
[4] 5 []
[4, 5] 6 []
[] 3 [4, 5, 6]
[] 1 [3, 4, 5, 6]
[10] 11 [12, 12]
[12] 12 []
[12] 12 []
[10] 11 [12, 12]
[1, 3, 4, 5, 6] 8 [10, 11, 12, 12]
[1, 3, 4, 5, 6, 8, 10, 11, 12, 12]
\end{verbatim}

\subsection{Insertion sort}
\begin{verbatim}
[5, 6, 12, 8, 4, 10, 3, 12, 11, 1]
[5, 6, 8, 12, 4, 10, 3, 12, 11, 1]
[5, 6, 8, 4, 12, 10, 3, 12, 11, 1]
[5, 6, 4, 8, 12, 10, 3, 12, 11, 1]
[5, 4, 6, 8, 12, 10, 3, 12, 11, 1]
[4, 5, 6, 8, 12, 10, 3, 12, 11, 1]
[4, 5, 6, 8, 10, 12, 3, 12, 11, 1]
[4, 5, 6, 8, 10, 3, 12, 12, 11, 1]
[4, 5, 6, 8, 3, 10, 12, 12, 11, 1]
[4, 5, 6, 3, 8, 10, 12, 12, 11, 1]
[4, 5, 3, 6, 8, 10, 12, 12, 11, 1]
[4, 3, 5, 6, 8, 10, 12, 12, 11, 1]
[3, 4, 5, 6, 8, 10, 12, 12, 11, 1]
[3, 4, 5, 6, 8, 10, 12, 11, 12, 1]
[3, 4, 5, 6, 8, 10, 11, 12, 12, 1]
[3, 4, 5, 6, 8, 10, 11, 12, 1, 12]
[3, 4, 5, 6, 8, 10, 11, 1, 12, 12]
[3, 4, 5, 6, 8, 10, 1, 11, 12, 12]
[3, 4, 5, 6, 8, 1, 10, 11, 12, 12]
[3, 4, 5, 6, 1, 8, 10, 11, 12, 12]
[3, 4, 5, 1, 6, 8, 10, 11, 12, 12]
[3, 4, 1, 5, 6, 8, 10, 11, 12, 12]
[3, 1, 4, 5, 6, 8, 10, 11, 12, 12]
[1, 3, 4, 5, 6, 8, 10, 11, 12, 12]
\end{verbatim}

\section{Exercise 2}

\subsection{Exercise a}
The pseudocode for \textit{Sum of two} can be found in listing \ref{lst:sum2}.
The total cost of this algorithm in the worst case is the sum of the worst case
of mergesort ($O(n log(n))$) and the cost of the worst case in the partition
done afterwards (which is equivalent to not finding a sum close to the median,
i.e. $2 n = O(n)$). Therefore, the total cost is $\theta(n log(n))$.

\begin{lstlisting}[caption=Sum of two in pseudocode, label={lst:sum2}]
FUNCTION SUM-OF-TWO(A, s):
  A $\gets$ mergesort(A)
  i $\gets$ 1
  j $\gets$ A.length

  while i < j:
    sum $\gets$ $A_i$ + $A_j$
    if sum = s:
      return TRUE
    elif sum > s:
      j $\gets$ j - 1
    else:
      i $\gets$ i + 1

 return FALSE
\end{lstlisting}

\subsection{Exercise b}
The pseudocode for \textit{Sum of three} can be found in listing \ref{lst:sum3}.
\textsc{search-two} has a time cost of $O(n)$ in the worst case (if no elements
are found), and the loop of \textsc{search} has an added cost of $O(n)$. The
total cost in the worst case then, including mergesort, is $n^2 + n log(n)
= \theta(n^2)$.

\begin{lstlisting}[caption=Sum of three in pseudocode, label={lst:sum3}]
FUNCTION SEARCH-TWO(A, sum2, i_skip):
  i $\gets$ 1
  j $\gets$ A.length

  while i < j:
    if i = i_skip:
      i $\gets$ i + 1
    elif j = i_skip:
      j $\gets$ j - 1
    else:
      sum $\gets$ $A_i$ + $A_j$
      if sum = sum2:
        return TRUE
      elif sum > sum2:
        j $\gets$ j - 1
      else:
        i $\gets$ i + 1

  return FALSE

FUNCTION SUM-OF-THREE(A, s):
  A $\gets$ mergesort(A)
  l $\gets$ A.length

  for i from 1 to l:
    if SEARCH-TWO(A, s - $A_i$, i):
      return TRUE

  return FALSE
\end{lstlisting}

\subsection{Exercise c}
The \textit{Python} code used to implement \textit{Sum of three} can be found in
the listing \ref{lst:sum3py}.

\begin{lstlisting}[caption=Sum of three in Python, label={lst:sum3py},%
language=python]
#!/usr/bin/env python3

import sys

def search_two(A, sum2, i_skip):
    i = 0
    j = len(A) - 1

    while i < j:
        if i == i_skip:
            i = i + 1
        elif j == i_skip:
            j = j - 1
        else:
            cs = A[i] + A[j]
            if cs == sum2:
                return True
            elif cs > sum2:
                j = j - 1
            else:
                i = i + 1

    return False

def sum_of_three(A, sum3):
    A.sort() # assume using mergesort for worst case of O(n*log(n))
    l = len(A)

    for i in range(l):
        if search_two(A, sum3 - A[i], i):
            return True

    return False

if __name__ == "__main__":
    args = [int(x) for x in sys.argv[1:]]
    print(sum_of_three(args[1:], args[0]))
\end{lstlisting}
\end{document}
