Skip to content

Commit

Permalink
add pset6 solutions
Browse files Browse the repository at this point in the history
  • Loading branch information
mareksuscak committed Apr 14, 2018
1 parent 99ed1f4 commit 025ea8c
Show file tree
Hide file tree
Showing 40 changed files with 1,010 additions and 0 deletions.
1 change: 1 addition & 0 deletions pset6/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
https://docs.cs50.net/2018/x/psets/6/pset6.html
1 change: 1 addition & 0 deletions pset6/sentimental/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
https://docs.cs50.net/2018/x/psets/6/sentimental/sentimental
1 change: 1 addition & 0 deletions pset6/sentimental/caesar/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
https://docs.cs50.net/2018/x/psets/2/caesar/caesar.html
33 changes: 33 additions & 0 deletions pset6/sentimental/caesar/caesar.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import sys
from cs50 import get_string


def main():
if len(sys.argv) != 2:
print("Usage: ./caesar k")
sys.exit(1)

k = int(sys.argv[1])
plaintext = get_string("plaintext: ")

print("ciphertext: ", end="")

for ch in plaintext:
if not ch.isalpha():
print(ch, end="")
continue

ascii_offset = 65 if ch.isupper() else 97

pi = ord(ch) - ascii_offset
ci = (pi + k) % 26

print(chr(ci + ascii_offset), end="")

print()

return 0


if __name__ == "__main__":
main()
1 change: 1 addition & 0 deletions pset6/sentimental/cash/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
https://docs.cs50.net/2018/x/psets/1/cash/cash.html
22 changes: 22 additions & 0 deletions pset6/sentimental/cash/cash.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from cs50 import get_float
from math import floor


def main():
while True:
dollars_owed = get_float("Change owed: ")
cents_owed = floor(dollars_owed * 100)

if cents_owed > 0:
break

quarters = cents_owed // 25
dimes = (cents_owed % 25) // 10
nickels = ((cents_owed % 25) % 10) // 5
pennies = ((cents_owed % 25) % 10) % 5

print(f"{quarters + dimes + nickels + pennies}")


if __name__ == "__main__":
main()
1 change: 1 addition & 0 deletions pset6/sentimental/crack/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
https://docs.cs50.net/2018/x/psets/2/crack/crack.html
27 changes: 27 additions & 0 deletions pset6/sentimental/crack/crack.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import sys
import crypt


def main():
if len(sys.argv) != 2:
print("Usage: crack <hash>")
sys.exit(1)

ahash = sys.argv[1]
salt = ahash[0:2]
letters = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"

for fifth in letters:
for fourth in letters:
for third in letters:
for second in letters:
for first in letters[1:]:
candidate = f"{first}{second}{third}{fourth}{fifth}".strip()

if crypt.crypt(candidate, salt) == ahash:
print(candidate)
sys.exit(0)


if __name__ == "__main__":
main()
1 change: 1 addition & 0 deletions pset6/sentimental/credit/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
https://docs.cs50.net/2018/x/psets/1/credit/credit.html
40 changes: 40 additions & 0 deletions pset6/sentimental/credit/credit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from cs50 import get_int
from math import floor


def main():
digit1 = 0
digit2 = 0
num_digits = 0
sum_of_double_odds = 0
sum_of_evens = 0
cc_number = get_int("Number: ")

while cc_number > 0:
digit2 = digit1
digit1 = cc_number % 10

if num_digits % 2 == 0:
sum_of_evens += digit1
else:
multiple = 2 * digit1
sum_of_double_odds += (multiple // 10) + (multiple % 10)

cc_number //= 10
num_digits += 1

is_valid = (sum_of_evens + sum_of_double_odds) % 10 == 0
first_two_digits = (digit1 * 10) + digit2

if digit1 == 4 and num_digits >= 13 and num_digits <= 16 and is_valid:
print("VISA\n")
elif first_two_digits >= 51 and first_two_digits <= 55 and num_digits == 16 and is_valid:
print("MASTERCARD\n")
elif (first_two_digits == 34 or first_two_digits == 37) and num_digits == 15 and is_valid:
print("AMEX\n")
else:
print("INVALID\n")


if __name__ == "__main__":
main()
1 change: 1 addition & 0 deletions pset6/sentimental/hello/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
https://docs.cs50.net/2018/x/psets/1/hello/hello.html
5 changes: 5 additions & 0 deletions pset6/sentimental/hello/hello.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
def main():
print("hello, world")

if __name__ == "__main__":
main()
1 change: 1 addition & 0 deletions pset6/sentimental/mario/less/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
https://docs.cs50.net/2018/x/psets/1/mario/less/mario.html
20 changes: 20 additions & 0 deletions pset6/sentimental/mario/less/mario.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from cs50 import get_int


def main():
while True:
height = get_int("Height: ")
width = height + 1
if height >= 0 and height <= 23:
break

for i in range(1, height + 1):
num_hashes = i + 1
num_spaces = width - num_hashes

print(" " * num_spaces, end="")
print("#" * num_hashes)


if __name__ == "__main__":
main()
1 change: 1 addition & 0 deletions pset6/sentimental/mario/more/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
https://docs.cs50.net/2018/x/psets/1/mario/more/mario.html
24 changes: 24 additions & 0 deletions pset6/sentimental/mario/more/mario.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from cs50 import get_int


def main():
while True:
height = get_int("Height: ")
width = height
if height >= 0 and height <= 23:
break

for i in range(1, height + 1):
num_hashes = i
num_spaces = width - num_hashes

print(" " * num_spaces, end="")
print("#" * num_hashes, end="")

print(" ", end="")

print("#" * num_hashes)


if __name__ == "__main__":
main()
1 change: 1 addition & 0 deletions pset6/sentimental/vigenere/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
https://docs.cs50.net/2018/x/psets/2/vigenere/vigenere.html
43 changes: 43 additions & 0 deletions pset6/sentimental/vigenere/vigenere.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import sys
from cs50 import get_string


def is_valid(k):
for ch in k:
if not ch.isalpha():
return False
return True


def main():
if len(sys.argv) != 2 or not is_valid(sys.argv[1]):
print("Usage: ./vigenere k")
sys.exit(1)

k = sys.argv[1]
plaintext = get_string("plaintext: ")
j = 0

print("ciphertext: ", end="")

for ch in plaintext:
if not ch.isalpha():
print(ch, end="")
continue

ascii_offset = 65 if ch.isupper() else 97

pi = ord(ch) - ascii_offset
kj = ord(k[j % len(k)].upper()) - 65
ci = (pi + kj) % 26
j += 1

print(chr(ci + ascii_offset), end="")

print()

return 0


if __name__ == "__main__":
main()
1 change: 1 addition & 0 deletions pset6/similarities/less/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
https://docs.cs50.net/2018/x/psets/6/similarities/less/similarities.html
138 changes: 138 additions & 0 deletions pset6/similarities/less/application.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import cs50
import re
from flask import Flask, abort, redirect, render_template, request
from html import escape
from werkzeug.exceptions import default_exceptions, HTTPException

from helpers import lines, sentences, substrings

# Web app
app = Flask(__name__)


@app.after_request
def after_request(response):
"""Disable caching"""
response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
response.headers["Expires"] = 0
response.headers["Pragma"] = "no-cache"
return response


@app.route("/")
def index():
"""Handle requests for / via GET (and POST)"""
return render_template("index.html")


@app.route("/compare", methods=["POST"])
def compare():
"""Handle requests for /compare via POST"""

# Read files
if not request.files["file1"] or not request.files["file2"]:
abort(400, "missing file")
try:
file1 = request.files["file1"].read().decode("utf-8")
file2 = request.files["file2"].read().decode("utf-8")
except Exception:
abort(400, "invalid file")

# Compare files
if not request.form.get("algorithm"):
abort(400, "missing algorithm")
elif request.form.get("algorithm") == "lines":
regexes = [f"^{re.escape(match)}$" for match in lines(file1, file2)]
elif request.form.get("algorithm") == "sentences":
regexes = [re.escape(match) for match in sentences(file1, file2)]
elif request.form.get("algorithm") == "substrings":
if not request.form.get("length"):
abort(400, "missing length")
elif not int(request.form.get("length")) > 0:
abort(400, "invalid length")
regexes = [re.escape(match) for match in substrings(
file1, file2, int(request.form.get("length")))]
else:
abort(400, "invalid algorithm")

# Highlight files
highlights1 = highlight(file1, regexes)
highlights2 = highlight(file2, regexes)

# Output comparison
return render_template("compare.html", file1=highlights1, file2=highlights2)


def highlight(s, regexes):
"""Highlight all instances of regexes in s."""

# Get intervals for which strings match
intervals = []
for regex in regexes:
if not regex:
continue
matches = re.finditer(regex, s, re.MULTILINE)
for match in matches:
intervals.append((match.start(), match.end()))
intervals.sort(key=lambda x: x[0])

# Combine intervals to get highlighted areas
highlights = []
for interval in intervals:
if not highlights:
highlights.append(interval)
continue
last = highlights[-1]

# If intervals overlap, then merge them
if interval[0] <= last[1]:
new_interval = (last[0], interval[1])
highlights[-1] = new_interval

# Else, start a new highlight
else:
highlights.append(interval)

# Maintain list of regions: each is a start index, end index, highlight
regions = []

# If no highlights at all, then keep nothing highlighted
if not highlights:
regions = [(0, len(s), False)]

# If first region is not highlighted, designate it as such
elif highlights[0][0] != 0:
regions = [(0, highlights[0][0], False)]

# Loop through all highlights and add regions
for start, end in highlights:
if start != 0:
prev_end = regions[-1][1]
if start != prev_end:
regions.append((prev_end, start, False))
regions.append((start, end, True))

# Add final unhighlighted region if necessary
if regions[-1][1] != len(s):
regions.append((regions[-1][1], len(s), False))

# Combine regions into final result
result = ""
for start, end, highlighted in regions:
escaped = escape(s[start:end])
if highlighted:
result += f"<span>{escaped}</span>"
else:
result += escaped
return result


@app.errorhandler(HTTPException)
def errorhandler(error):
"""Handle errors"""
return render_template("error.html", error=error), error.code


# https://github.com/pallets/flask/pull/2314
for code in default_exceptions:
app.errorhandler(code)(errorhandler)
Loading

0 comments on commit 025ea8c

Please sign in to comment.