\documentclass[a4paper,11pt]{article}

\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{graphicx}
\usepackage{xcolor}

\renewcommand\familydefault{\sfdefault}
\usepackage{tgheros}
\usepackage[defaultmono]{droidsansmono}

\usepackage{amsmath,amssymb,amsthm,textcomp}
\usepackage{enumerate}
\usepackage{multicol}
\usepackage{tikz}

\usepackage{geometry}
\geometry{left=25mm,right=25mm,%
bindingoffset=0mm, top=20mm,bottom=20mm}

% Image path
\graphicspath{{images/}}

\linespread{1.3}

\newcommand{\linia}{\rule{\linewidth}{0.5pt}}

% custom theorems if needed
\newtheoremstyle{mytheor}
    {1ex}{1ex}{\normalfont}{0pt}{\scshape}{.}{1ex}
    {{\thmname{#1 }}{\thmnumber{#2}}{\thmnote{ (#3)}}}

\theoremstyle{mytheor}
\newtheorem{defi}{Definition}

% my own titles
\makeatletter
\renewcommand{\maketitle}{
\begin{center}
\vspace{2ex}
{\huge \textsc{\@title}}
\vspace{1ex}
\\
\linia\\
\@author \hfill \@date
\vspace{4ex}
\end{center}
}
\makeatother
%%%

% custom footers and headers
\usepackage{fancyhdr}
\pagestyle{fancy}
\lhead{}
\chead{}
\rhead{}
\lfoot{CSC 1109 Lab 9}
\cfoot{}
\rfoot{Page \thepage}
\renewcommand{\headrulewidth}{0pt}
\renewcommand{\footrulewidth}{0pt}
%

% code listing settings
\usepackage{listings}
\lstset{
    language=java,
    basicstyle=\ttfamily\small,
    aboveskip={1.0\baselineskip},
    belowskip={1.0\baselineskip},
    columns=fixed,
    extendedchars=true,
    breaklines=true,
    tabsize=4,
    prebreak=\raisebox{0ex}[0ex][0ex]{\ensuremath{\hookleftarrow}},
    frame=lines,
    showtabs=false,
    showspaces=false,
    showstringspaces=false,
    keywordstyle=\color[rgb]{0.627,0.126,0.941},
    commentstyle=\color[rgb]{0.133,0.545,0.133},
    stringstyle=\color[rgb]{01,0,0},
    numbers=left,
    numberstyle=\small,
    stepnumber=1,
    numbersep=10pt,
    captionpos=t,
    escapeinside={\%*}{*)}
}

%%%----------%%%----------%%%----------%%%----------%%%

\begin{document}

\title{CSC 1109 Lab 9}

\author{Woon Jun Wei, 2200624}

\date{\today}

\maketitle

\section*{Question 1}
\begin{lstlisting}[label={list:RandomCharacter},caption=RandomCharacter.java]

public class RandomCharacter {

    public static char getRandomLowerCaseLetter(){
        return (char)('a' + Math.random() * ('z' - 'a' + 1));
    }
    public static char getRandomUpperCaseLetter(){
        return (char)('A' + Math.random() * ('Z' - 'A' + 1));
    }
    public static char getRandomDigitCharacter(){
        return (char)('0' + Math.random() * ('9' - '0' + 1));
    }
    public static char getRandomCharacter(){
        int num = (int)(Math.random() * 3);
        return switch (num) {
            case 0 -> getRandomLowerCaseLetter();
            case 1 -> getRandomUpperCaseLetter();
            case 2 -> getRandomDigitCharacter();
            default -> ' ';
        };
    }

    public int genPrime() {
        int num;
        do {
            num = 0;
            for (int i = 0; i < 10; i++) {
                num = num * 10 + (getRandomDigitCharacter() - '0');
            }
        } while (!isPrime(num) || (int) (Math.log10(num) + 1) != 10);
        return num;
    }

    public boolean isPrime(int inputNum){
        if (inputNum <= 3 || inputNum % 2 == 0)
            return inputNum == 2 || inputNum == 3;

        int divisor = 3;
        while ((divisor <= Math.sqrt(inputNum)) && (inputNum % divisor != 0))
            divisor += 2;
        return inputNum % divisor != 0;
    }

    public static void main(String[] args) {
        for (int i = 0; i < 15; i++){
            System.out.print(getRandomLowerCaseLetter() + " ");
        }
        System.out.println();

        for (int i = 0; i < 15; i++){
            System.out.print(getRandomUpperCaseLetter() + " ");
        }
        System.out.println();

        for (int i = 0; i < 15; i++){
            System.out.print(getRandomDigitCharacter() + " ");
        }
        System.out.println();

        for (int i = 0; i < 15; i++){
            System.out.print(getRandomCharacter() + " ");
        }
        System.out.println();

        System.out.println(new RandomCharacter().genPrime());

    }
}
\end{lstlisting}
\pagebreak
\begin{lstlisting}[label={list:RandomCharacterOutput},caption=Output of RandomCharacter.java]
//Output 1
q e s o u e b e j j o s l c t
M G G C J Q T F F W Z A A J E
8 0 7 7 8 9 3 8 9 7 2 2 3 6 7
u R 7 G 4 b 2 0 n 7 a 8 6 6 X
1174095277

//Output 2
s b w w j q z u t a q l t t o
I R C J K D Z S O E Z G D B I
9 3 0 8 9 2 1 9 8 9 2 0 6 6 2
Y k N l b T M 9 R 4 8 8 d G H
1293553021
\end{lstlisting}

\pagebreak
\begin{lstlisting}[label={list:RandomCharacterTest},caption=Test cases of RandomCharacter.java, RandomCharacterTest.java]
import org.junit.Test;
import static org.junit.Assert.*;

public class RandomCharacterTest {
    @Test
    public void testGetRandomLowerCaseLetter() {
        for (int i = 0; i < 1000;i++){
            char c = RandomCharacter.getRandomLowerCaseLetter();
            assertTrue(c >= 'a' && c <= 'z');
        }
    }

    @Test
    public void testGetRandomUpperCaseLetter() {
        for (int i = 0; i < 1000;i++){
            char c = RandomCharacter.getRandomUpperCaseLetter();
            assertTrue(c >= 'A' && c <= 'Z');
        }
    }

    @Test
    public void testGetRandomDigitCharacter() {
        for (int i = 0; i < 1000;i++){
            char c = RandomCharacter.getRandomDigitCharacter();
            assertTrue(c >= '0' && c <= '9');
        }
    }

    @Test
    public void testGetRandomCharacter() {
        for (int i = 0; i < 1000;i++){
            char c = RandomCharacter.getRandomCharacter();
            assertTrue((c >= 'A' && c <= 'Z') ||
                    (c >= 'a' && c <= 'z') ||
                    (c >= '0' && c <= '9')
            );
        }
    }
}
\end{lstlisting}
\pagebreak
{\huge\textbf{RandomCharacterTest.java Output}}
% Insert image
\begin{figure}[ht]
    \centering
    \includegraphics[width=0.8\textwidth]{testcase.png}
    \caption{Output of RandomCharacterTest.java}
    \label{fig:RandomCharacterTest}
\end{figure}


\end{document}
