Skip to content

Commit

Permalink
Coming up with a final list of algorithms to study.
Browse files Browse the repository at this point in the history
  • Loading branch information
jwasham committed Nov 20, 2016
1 parent 8db78bc commit 815cc7d
Show file tree
Hide file tree
Showing 5 changed files with 208 additions and 0 deletions.
61 changes: 61 additions & 0 deletions catalog-organized/array_stack.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
"""Basic example of an adapter class to provide a stack interface to Python's list."""


class Empty(Exception):
"""Exception for requesting data from an empty collection"""
pass


class ArrayStack:
"""LIFO Stack implementation using a Python list as underlying storage."""

def __init__(self):
self._data = [] # nonpublic list instance

def __len__(self):
return len(self._data)

def is_empty(self):
return len(self._data) == 0

def push(self, e):
"""Add element e to the top of the stack."""
self._data.append(e) # new item stored at end of list

def top(self):
"""Return (but do not remove) the element at the top of the stack.
Raise Empty exception if the stack is empty.
"""
if self.is_empty():
raise Empty('Stack is empty')
return self._data[-1] # the last item in the list

def pop(self):
"""Remove and return the element from the top of the stack (i.e., LIFO).
Raise Empty exception if the stack is empty.
"""
if self.is_empty():
raise Empty('Stack is empty')
return self._data.pop() # remove last item from list


if __name__ == '__main__':
S = ArrayStack() # contents: [ ]
S.push(5) # contents: [5]
S.push(3) # contents: [5, 3]
print(len(S)) # contents: [5, 3]; outputs 2
print(S.pop()) # contents: [5]; outputs 3
print(S.is_empty()) # contents: [5]; outputs False
print(S.pop()) # contents: [ ]; outputs 5
print(S.is_empty()) # contents: [ ]; outputs True
S.push(7) # contents: [7]
S.push(9) # contents: [7, 9]
print(S.top()) # contents: [7, 9]; outputs 9
S.push(4) # contents: [7, 9, 4]
print(len(S)) # contents: [7, 9, 4]; outputs 3
print(S.pop()) # contents: [7, 9]; outputs 4
S.push(6) # contents: [7, 9, 6]
S.push(8) # contents: [7, 9, 6, 8]
print(S.pop()) # contents: [7, 9, 6]; outputs 8
41 changes: 41 additions & 0 deletions catalog-organized/caesar.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
class CaesarCipher:
"""Class for doing encryption and decryption using a Caesar cipher."""

def __init__(self, shift):
"""Construct Caesar cipher using given integer shift for rotation."""
encoder = [None] * 26 # temp array for encryption
decoder = [None] * 26 # temp array for decryption
for k in range(26):
encoder[k] = chr((k + shift) % 26 + ord('A'))
decoder[k] = chr((k - shift) % 26 + ord('A'))
self._forward = ''.join(encoder) # will store as string
self._backward = ''.join(decoder) # since fixed

def encrypt(self, message):
"""Return string representing encripted message."""
return self._transform(message, self._forward)

def decrypt(self, secret):
"""Return decrypted message given encrypted secret."""
return self._transform(secret, self._backward)

def _transform(self, original, code):
"""Utility to perform transformation based on given code string."""
msg = list(original)
for k in range(len(msg)):
if msg[k].isupper():
j = ord(msg[k]) - ord('A') # index from 0 to 25
msg[k] = code[j] # replace this character
return ''.join(msg)


if __name__ == '__main__':
cipher = CaesarCipher(3)
message = "THE EAGLE IS IN PLAY; MEET AT JOE'S."
coded = cipher.encrypt(message)
print('Secret: ', coded)
answer = cipher.decrypt(coded)
print('Message:', answer)

assert coded == "WKH HDJOH LV LQ SODB; PHHW DW MRH'V."
assert answer == "THE EAGLE IS IN PLAY; MEET AT JOE'S."
21 changes: 21 additions & 0 deletions catalog-organized/insertion_sort.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
def insertion_sort(A):
"""Sort list of comparable elements into non-decreasing order."""
for i in range(1, len(A)): # from 1 to n-1
cur = A[i] # current element to be inserted
j = i # find correct index j for current
while j > 0 and A[j - 1] > cur: # element A[j-1] must be after current
A[j] = A[j - 1]
j -= 1
A[j] = cur # cur is now in the right place


"""
Tests
"""

from random import shuffle

ex1 = [-5, -2.3, 0, 1, 1, 5, 6, 6.5, 7, 12]
shuffle(ex1)
insertion_sort(ex1)
assert ex1 == [-5, -2.3, 0, 1, 1, 5, 6, 6.5, 7, 12]
19 changes: 19 additions & 0 deletions catalog-organized/match_delimiters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
"""Tests if a string of nested braces, parentheses, and brackets are all
matched and nested correctly.
"""


def is_matched(expr):
"""Return True if all delimiters are properly match; False otherwise."""
lefty = '({[' # opening delimiters
righty = ')}]' # respective closing delims
S = ArrayStack()
for c in expr:
if c in lefty:
S.push(c) # push left delimiter on stack
elif c in righty:
if S.is_empty():
return False # nothing to match with
if righty.index(c) != lefty.index(S.pop()):
return False # mismatched
return S.is_empty() # were all symbols matched?
66 changes: 66 additions & 0 deletions catalog-organized/tic_tac_toe.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
class TicTacToe:
"""Management of a Tic-Tac-Toe game (does not do strategy)."""

def __init__(self):
"""Start a new game."""
self._board = [[' '] * 3 for j in range(3)]
self._player = 'X'

def mark(self, i, j):
"""Put an X or O mark at position (i,j) for next player's turn."""
if not (0 <= i <= 2 and 0 <= j <= 2):
raise ValueError('Invalid board position')
if self._board[i][j] != ' ':
raise ValueError('Board position occupied')
if self.winner() is not None:
raise ValueError('Game is already complete')
self._board[i][j] = self._player
if self._player == 'X':
self._player = 'O'
else:
self._player = 'X'

def _is_win(self, mark):
"""Check whether the board configuration is a win for the given player."""
board = self._board # local variable for shorthand
return (mark == board[0][0] == board[0][1] == board[0][2] or # row 0
mark == board[1][0] == board[1][1] == board[1][2] or # row 1
mark == board[2][0] == board[2][1] == board[2][2] or # row 2
mark == board[0][0] == board[1][0] == board[2][0] or # column 0
mark == board[0][1] == board[1][1] == board[2][1] or # column 1
mark == board[0][2] == board[1][2] == board[2][2] or # column 2
mark == board[0][0] == board[1][1] == board[2][2] or # diagonal
mark == board[0][2] == board[1][1] == board[2][0]) # rev diag

def winner(self):
"""Return mark of winning player, or None to indicate a tie."""
for mark in 'XO':
if self._is_win(mark):
return mark
return None

def __str__(self):
"""Return string representation of current game board."""
rows = ['|'.join(self._board[r]) for r in range(3)]
return '\n-----\n'.join(rows)


if __name__ == '__main__':
game = TicTacToe()
# X moves: # O moves:
game.mark(1, 1)
game.mark(0, 2)
game.mark(2, 2)
game.mark(0, 0)
game.mark(0, 1)
game.mark(2, 1)
game.mark(1, 2)
game.mark(1, 0)
game.mark(2, 0)

print(game)
winner = game.winner()
if winner is None:
print('Tie')
else:
print(winner, 'wins')

0 comments on commit 815cc7d

Please sign in to comment.