[+] A4 Add starter files

This commit is contained in:
Hykilpikonna
2021-11-07 13:33:56 -05:00
parent 320a6163d3
commit 70b9976e8f
6 changed files with 422 additions and 0 deletions
+119
View File
@@ -0,0 +1,119 @@
\documentclass[fontsize=11pt]{article}
\usepackage{amsfonts}
\usepackage{amsmath}
\usepackage{amsthm}
\usepackage[utf8]{inputenc}
\usepackage[margin=0.75in]{geometry}
\title{CSC110 Assignment 4: Number Theory, Cryptography, and Algorithm Running Time}
\author{TODO: FILL IN YOUR NAME HERE}
\date{\today}
% Some useful LaTeX commands. You are free to use these or not, and also add your own.
\newcommand{\N}{\mathbb{N}}
\newcommand{\Z}{\mathbb{Z}}
\newcommand{\R}{\mathbb{R}}
\newcommand{\cO}{\mathcal{O}}
\newcommand{\floor}[1]{\left\lfloor #1 \right\rfloor}
\begin{document}
\maketitle
\section*{Part 1: Practice with Proofs}
\begin{enumerate}
\item[1.] Statement to prove:
$$\forall a, k, n \in \Z,~ \gcd(a, n) = 1 \Rightarrow \gcd(a + kn, n) = 1$$
\begin{proof}
TODO: Your proof goes here.
\end{proof}
\item[2.] Statement to prove (we've expanded the definition of Omega for you!):
$$\exists c, n_0 \in \R^+,~ \forall n \in \N,~ n \geq n_0 \Rightarrow \log_{3} n - \log_{11} n \geq c \cdot \log_{14} n$$
\begin{proof}
TODO: Your proof goes here.
\end{proof}
\item[3.] Statement to prove (we haven't expanded the definition of Big-O for you, but we encourage you to do so yourself):
$$\forall f, g: \N \to \R^{\geq 0},~ g \in \cO(f) \land \big(\forall m \in \N,~ f(m) \geq 1 \big) \Rightarrow g \in \cO(\floor{f})$$
\begin{proof}
TODO: Your proof goes here.
\end{proof}
\end{enumerate}
\newpage
\section*{Part 2: Generating Coprime Numbers}
\begin{enumerate}
\item[1.]
Not to be handed in.
\item[2.]
Complete this part in the provided \texttt{a4\_part2.py} starter file.
Do \textbf{not} include your solution in this file.
\item[3.]
Prove that each loop invariant holds.
\begin{enumerate}
\item[a.] Loop Invariant 1
\begin{proof}
TODO: Your proof goes here.
\end{proof}
\item[b.] Loop Invariant 2
\begin{proof}
TODO: Your proof goes here.
\end{proof}
\item[c.] Loop Invariant 3
\begin{proof}
TODO: Your proof goes here.
\end{proof}
\item[d.] Loop Invariant 4
\begin{proof}
TODO: Your proof goes here.
\end{proof}
\end{enumerate}
\item[4.]
Complete this part in the provided \texttt{a4\_part2.py} starter file.
Do \textbf{not} include your solution in this file.
\item[5.]
Complete this part in the provided \texttt{a4\_part2.py} starter file.
Do \textbf{not} include your solution in this file.
\end{enumerate}
\newpage
\section*{Part 3: Running-Time Analysis}
\begin{enumerate}
\item[1.]
TODO: Running-time analysis of \texttt{coprime\_to\_2\_and\_3}.
\item[2.]
TODO: Running-time analysis of \texttt{starting\_coprime\_numbers}.
\item[3.]
TODO: Running-time analysis of \texttt{coprime\_to\_all}.
\end{enumerate}
\section*{Part 4: Two New Cryptosystems}
Complete this part in the provided \texttt{a4\_part4.py} starter file.
Do \textbf{not} include your solution in this file.
\end{document}
+118
View File
@@ -0,0 +1,118 @@
"""CSC110 Fall 2021 Assignment 4, Part 2: Generating coprime numbers
Instructions (READ THIS FIRST!)
===============================
Implement each of the functions in this file. As usual, do not change any function headers
or preconditions. You do NOT need to add doctests.
You may create additional helper functions to help break up your code into smaller parts.
Copyright and Usage Information
===============================
This file is provided solely for the personal and private use of students
taking CSC110 at the University of Toronto St. George campus. All forms of
distribution of this code, whether as given or with any changes, are
expressly prohibited. For more information on copyright for CSC110 materials,
please consult our Course Syllabus.
This file is Copyright (c) 2021 David Liu, Mario Badr, and Tom Fairgrieve.
"""
import math
def coprime_to_2_and_3(n: int) -> list[int]:
"""Return the natural numbers less than n that are coprime to both 2 and 3.
The returned list is sorted.
Preconditions:
- n >= 6
>>> coprime_to_2_and_3(20)
[1, 5, 7, 11, 13, 17, 19]
Implementation note: recall negative list indexing from Assignment 3.
For all lists lst and integers i between 0 and len(lst) - 1 inclusive,
lst[-i] == lst[len(lst) - i].
"""
nums_so_far = [1, 5]
while nums_so_far[-2] + 6 < n:
# Note: Write four assert statements here expressing the four loop invariants from the
# assignment handout. These statements should be at the top of the loop body.
next_number = nums_so_far[-2] + 6
list.append(nums_so_far, next_number)
return nums_so_far
def coprime_to_all(primes: set[int], n: int) -> list[int]:
"""Return the positive integers less than n that are coprime to every number in primes.
The returned list is sorted.
Pay attention to the preconditions, as they are designed to help simplify your work for this
question.
Preconditions:
- primes != set()
- every element of primes is prime
- n >= math.prod(primes)
>>> coprime_to_all({2, 3}, 20)
[1, 5, 7, 11, 13, 17, 19]
>>> coprime_to_all({2, 3, 7}, 50)
[1, 5, 11, 13, 17, 19, 23, 25, 29, 31, 37, 41, 43, 47]
Implementation notes:
- You MUST use the provided helper function starting_coprime_numbers in your implementation,
and may NOT modify it (even though it is not as efficient as it could be!!).
- You will find the math.prod function useful.
"""
def starting_coprime_numbers(primes: set[int]) -> list[int]:
"""Return the numbers up to the product of the given primes that are coprime to all of them.
Note: the length of the returned list is is exactly equal to phi(math.prod(primes)), where
phi is the Euler totient function.
Preconditions:
- primes != set()
- every element of primes is prime
>>> starting_coprime_numbers({2, 3})
[1, 5]
>>> starting_coprime_numbers({3, 11})
[1, 2, 4, 5, 7, 8, 10, 13, 14, 16, 17, 19, 20, 23, 25, 26, 28, 29, 31, 32]
"""
nums_so_far = []
m = math.prod(primes)
for k in range(1, m):
is_coprime = True
for p in primes:
if k % p == 0:
is_coprime = False
if is_coprime:
list.append(nums_so_far, k)
return nums_so_far
if __name__ == '__main__':
# When you are ready to check your work with python_ta, uncomment the following lines.
# (Delete the "#" and space before each line.)
# IMPORTANT: keep this code indented inside the "if __name__ == '__main__'" block
# Leave this code uncommented when you submit your files.
# import python_ta
#
# python_ta.check_all(config={
# 'extra-imports': ['python_ta.contracts', 'math'],
# 'max-line-length': 100,
# 'disable': ['R1705', 'C0200']
# })
import doctest
doctest.testmod()
+182
View File
@@ -0,0 +1,182 @@
"""CSC110 Fall 2021 Assignment 4, Part 4: Two New Cryptosystems
Instructions (READ THIS FIRST!)
===============================
Implement each of the functions in this file. As usual, do not change any function headers
or preconditions. You do NOT need to add doctests.
You may create some additional helper functions to help break up your code into smaller parts.
Copyright and Usage Information
===============================
This file is provided solely for the personal and private use of students
taking CSC110 at the University of Toronto St. George campus. All forms of
distribution of this code, whether as given or with any changes, are
expressly prohibited. For more information on copyright for CSC110 materials,
please consult our Course Syllabus.
This file is Copyright (c) 2021 David Liu, Mario Badr, and Tom Fairgrieve.
"""
################################################################################
# Task 1 - The Grid Transpose Cryptosystem
################################################################################
def grid_encrypt(k: int, plaintext: str) -> str:
"""Encrypt the given plaintext using the grid cryptosystem.
Preconditions:
- k >= 1
- len(plaintext) % k == 0
- plaintext != ''
>>> grid_encrypt(8, 'DAVID AND MARIO TEACH COMPUTER SCIENCE!!')
'DDTMCA EPIVMAUEIACTNDRHEC I REAOC !N OS!'
"""
def grid_decrypt(k: int, ciphertext: str) -> str:
"""Decrypt the given ciphertext using the grid cryptosystem.
Preconditions:
- k >= 1
- len(ciphertext) % k == 0
- ciphertext != ''
>>> grid_decrypt(8, 'DDTMCA EPIVMAUEIACTNDRHEC I REAOC !N OS!')
'DAVID AND MARIO TEACH COMPUTER SCIENCE!!'
"""
def plaintext_to_grid(k: int, plaintext: str) -> list[list[str]]:
"""Return the grid with k columns from the given plaintext.
Preconditions:
- k >= 1
- len(plaintext) % k == 0
- plaintext != ''
"""
def grid_to_ciphertext(grid: list[list[str]]) -> str:
"""Return the ciphertext corresponding to the given grid.
Preconditions:
- grid != []
- grid[0] != []
- all({len(row1) == len(row2) for row1 in grid for row2 in grid})
"""
def ciphertext_to_grid(k: int, ciphertext: str) -> list[list[str]]:
"""Return the grid corresponding to the given ciphertext.
Note that this grid should be the one that is used to generate the ciphertext.
Preconditions:
- k >= 1
- len(ciphertext) % k == 0
- ciphertext != ''
"""
def grid_to_plaintext(grid: list[list[str]]) -> str:
"""Return the plaintext message corresponding to the given grid.
Preconditions:
- grid != []
- grid[0] != []
- all({len(row1) == len(row2) for row1 in grid for row2 in grid})
"""
################################################################################
# Task 2 - Breaking The Grid Transpose Cryptosystem
################################################################################
def grid_break(ciphertext: str, candidates: set[str]) -> set[int]:
"""Return the set of possible secret keys that decrypt the given ciphertext into a message
that contains at least one of the candidate words.
>>> candidate_words = {'DAVID', 'MINE'}
>>> grid_break('DDTMCA EPIVMAUEIACTNDRHEC I REAOC !N OS!', candidate_words) == {8, 10}
True
"""
def run_example_break(ciphertext_file: str, candidates: set[str]) -> list[str]:
"""Return a list of possible plaintexts for the ciphertext found in the given file.
Based on the A4 directory structure, you can call this function like this:
>>> possible_plaintexts = run_example_break('ciphertexts/grid_ciphertext1.txt', {'climate'})
"""
with open(ciphertext_file, encoding='utf-8') as f:
ciphertext = f.read()
# (Not to be handed in) Try completing this function by calling grid_break and returning a
# list of the possible plaintext messages.
return [ciphertext] + list(candidates) # This is a dummy line, please replace it!
################################################################################
# Task 3 - The Permuted Grid Transpose Cryptosystem
################################################################################
def permutation_grid_encrypt(k: int, perm: list[int], plaintext: str) -> str:
"""Encrypt the given plaintext using the grid cryptosystem.
Preconditions:
- k >= 1
- len(plaintext) % k == 0
- sorted(perm) == list(range(0, k))
- plaintext != ''
>>> permutation_grid_encrypt(8, [0, 1, 2, 3, 4, 5, 6, 7],
... 'DAVID AND MARIO TEACH COMPUTER SCIENCE!!')
'DDTMCA EPIVMAUEIACTNDRHEC I REAOC !N OS!'
>>> permutation_grid_encrypt(8, [3, 2, 5, 0, 7, 1, 6, 4],
... 'DAVID AND MARIO TEACH COMPUTER SCIENCE!!')
'IACTNVMAUE I REDDTMCN OS!A EPIAOC !DRHEC'
"""
def permutation_grid_decrypt(k: int, perm: list[int], ciphertext: str) -> str:
"""Return the grid corresponding to the given ciphertext.
Note that this grid should be the one that is used to generate the ciphertext.
Preconditions:
- k >= 1
- len(ciphertext) % k == 0
- sorted(perm) == list(range(0, k))
- ciphertext != ''
>>> permutation_grid_decrypt(8, [0, 1, 2, 3, 4, 5, 6, 7],
... 'DDTMCA EPIVMAUEIACTNDRHEC I REAOC !N OS!')
'DAVID AND MARIO TEACH COMPUTER SCIENCE!!'
>>> permutation_grid_decrypt(8, [3, 2, 5, 0, 7, 1, 6, 4],
... 'IACTNVMAUE I REDDTMCN OS!A EPIAOC !DRHEC')
'DAVID AND MARIO TEACH COMPUTER SCIENCE!!'
"""
if __name__ == '__main__':
# When you are ready to check your work with python_ta, uncomment the following lines.
# (Delete the "#" and space before each line.)
# IMPORTANT: keep this code indented inside the "if __name__ == '__main__'" block
# Leave this code uncommented when you submit your files.
#
# import python_ta
# python_ta.check_all(config={
# 'extra-imports': ['python_ta.contracts'],
# 'allowed-io': ['run_example_break'],
# 'max-line-length': 100,
# 'disable': ['R1705', 'C0200']
# })
import python_ta.contracts
python_ta.contracts.check_all_contracts()
import doctest
doctest.testmod()
@@ -0,0 +1 @@
Ea hadcrvlstai hnmo'carsetb eica tlne idrtm ahar ate-tet rachenhaadast n ,ogc fehw aihtntuhghmee a dtna h mtecoh iuravnobiturl guiohpzfota u tsteio nolhdnai .rso tfMeo onrtseyhtr.e g oyJlf ua osstutthr e iispncel e at cnhaleegit em l araatesbecto e uci6thv5 ae01ns,1g.0,e 07s(00 W 0aey rbeye ae sraaosrtu strt rchaieegb:rou e th methadtar pvktseio: n /bgv/e ecetrlnhyi e ms saebmtveaeegl.niln n acnvsyiaacnr.lgige aosotv fi/o oeftnv hsige dl ieamnnco cidEeaea/lrr) nt
@@ -0,0 +1 @@
Gavnst tlbeghswns ol i ooewbesuftuwaaa hpthl vler eadole fuedt cescfna rcv.lekraseue ic,lncsrl(mt idiur hasie elirtt crtntniteoe,rt gsp n eif:esc opesr :htnlstola/ah a smon/nerna sdcg itrhgs leev eal li nea dooomhvrnf bfnaaisdlpa gtsr orlsee oaawe er.annnedca,nlmdiril are miciimsenlantmcoaatalgeaer.d.k dt,egy ers e o Gsaoi aivhl nonccn/aaign hctedcseetaeef i srhnlnfoeb .egesebrrhE erecsseafp a te avfaathsrhkeesree/vai cteda)
File diff suppressed because one or more lines are too long