fixed merge issues from older commit

This commit is contained in:
shockrahwow 2019-05-05 21:15:06 -07:00
commit af38c55ecc
12 changed files with 389 additions and 106 deletions

View File

@ -1,9 +1,11 @@
cc=javac
fxlib=--module-path /home/shockrah/Downloads/javafx-sdk-11.0.2/lib
ctrl=--add-modules javafx.controls
env=java
cfile="adsf"
#fxlib=--module-path /home/shockrah/Downloads/javafx-sdk-11.0.2/lib
#ctrl=--add-modules javafx.controls
jfile="Main.java"
# Target class file to run(no extension)
cfile="Main"
default: %.java
# takes a java file as entry to build

View File

@ -1,94 +1,20 @@
import queue
class Node():
import heapq
class Node:
def __init__(self, c, weight):
self.c = c
self.freq = weight
self.left = None
self.right = None
self.code = ''
def __repr__(self):
return f'{self.c}|{self.freq}'
class MinHeap():
def __init__(self):
self.data = []
def empty(self):
return self.size() == 0
def size(self):
return len(self.data)
def print(self):
for x in self.data:
print(x.c + str(x.freq))
def insert(self, val):
self.data.append(val)
self.__heapifyUp(len(self.data) - 1)
def extractMin(self):
temp = self.data[0]
self.__swap(0, -1)
self.data.remove(self.data[-1])
self.__heapifyDown(0)
return temp
def __swap(self,i,j):
self.data[i], self.data[j] = self.data[j], self.data[i]
def __heapifyUp(self, idx):
if idx > 0:
parent = (idx - 1) // 2
if (self.data[parent].freq > self.data[idx].freq):
self.__swap(parent, idx)
self.__heapifyUp(parent)
def __heapifyDown(self, idx):
data = self.data
left = 2 * idx + 1
right = 2 * idx + 2
mini = idx
if (left < len(data) and (data[left].freq < data[mini].freq)):
mini = left
if (right < len(data) and (data[right].freq < data[mini].freq)):
mini = right
if (mini is not idx):
self.__swap(mini, idx)
self.__heapifyDown(mini)
def printChar(self, c):
# TODO: this method
curr = self.data[0]
for i in bin:
if i == '1' and curr.right is not None:
curr = curr.right
if i == '0' and curr.left is not None:
curr = curr.left
def main():
pq = MinHeap()
pq.insert(Node(' ', 1))
pq.insert(Node('d', 4))
pq.insert(Node('e', 10))
pq.insert(Node('i', 13))
pq.insert(Node('s', 2))
pq.insert(Node('m', 8))
pq.insert(Node('o', 6))
assert(list(map(lambda x: x.freq, pq.data)) == [1, 2, 6, 13, 4, 10, 8])
assert(pq.extractMin().freq == 1)
assert(list(map(lambda x: x.freq, pq.data)) == [2, 4, 6, 13, 8, 10])
assert(pq.extractMin().freq == 2)
assert(list(map(lambda x: x.freq, pq.data)) == [4, 8, 6, 13, 10])
assert(pq.extractMin().freq == 4)
pq.print()
print("Heap works")
def __lt__(self, other):
return self.weight < other.weight
def frequencyMap(string):
ret = []
@ -103,31 +29,50 @@ def frequencyMap(string):
if k.c == i:
k.freq += 1
# Sort the charmap based on the frequencies
ret.sort(key=lambda x: x.freq)
# Sort the charmap alphabetically
ret.sort(key=lambda x: x.c)
return ret
def buildMinHeap(freqs):
heap = MinHeap()
_queue = queue.Queue()
while _queue.qsize() >= 2:
left = _queue.get()
right = _queue.get()
weight = left.freq+ right.freq
root = Node('*', weight)
def encode(freqs):
# add things to our min heap
heap = [i for i in freqs]
heapq.heapify(heap)
# insert the new sub-tree into the minheap and add the tree to the queue
heap.insert(root)
_queue.put(root)
# now we can merge all the nodes together
while len(heap) > 1:
# pop two items from the queuee
left = heapq.heappop(heap)
right = heapq.heappop(heap)
# Once there is one item in the queue left we can simply return the new thing
heap.print()
# setup the new root node
root = Node('*', left.weight + right.weight)
root.left = left
root.right = right
# re-insert the new subtree into the minheap
heapq.heappush(heap, root)
# return the heap itself so we cna do stuff with it
return heap
def decode(root, binaryStr):
string = ''
curr = root
for i in binaryStr:
if i == '0':
curr = curr.left
else:
curr = curr.right
# check if we're at a leaf
if curr.left is None and curr.right is None:
string += curr.c
curr = root
print(string)
def printEncoding(text, heap):
# prints out the encoding for a given string
for i in text:
heap.printChar(i)
@ -136,8 +81,15 @@ def printEncoding(text, heap):
if __name__ == "__main__":
text = input()
binary = input()
#print(f'{text}\n{binary}\n===================')
# calculate the frequency of each character
frequencies = frequencyMap(text)
print(frequencies)
heap = buildMinHeap(frequencies)
printEncoding(binary, heap)
# build up our heap to display info from
heap = encode(frequencies)[0]
#print(heap)
# decode the binary
decode(heap, binary)

View File

@ -21,7 +21,12 @@ Time: O(VlogV + E)
## Dijkstra's
O(V)
O(V^2 + E)
## A\*
O(V^2 = E)
Worst case is the same as Dijkstra's time
O(V^2 + E)

View File

@ -7,7 +7,7 @@ _time complexity will be in terms of height_
* impl: _root will typically have the largest height value_
> Balance:
| left_height - right_height |
left_height - right_height
we can discard the || if we want negative balance vals but it really shouldn't matter
basically: we want the balance for each node to be 1 or 0.

53
370/notes/dynamic.md Normal file
View File

@ -0,0 +1,53 @@
# """"Dynamic Programming""""
> Take a large problem
> Break it up
> Solve the pieces
# Definitions
_Recursive dynamic programming_
: Memoization a.k.a. top-down approach
: Go from big problems and build downward
_Tabulation_
: Bottom up approach
: Go from little problems and build up
# Recursive compiler tricks
Normal iterative:
```
start:
...
jcond start
```
Normal recursion(under non-priveleged procs):
Each "iteration" creates a new frame of whatever size:
hence we approach the hard stack limit
_Sick guess_:
```
At compile we should be able to predict an incoming iteration from a
recusive endpoint.
? is it just parameterized jumps ?
```
_Answer:_
```
Tail recusion optimization
Takes the last statement of function
Assuming its a recursive call, we can replace our current stack frame's arguments
The only state that changes between calls then is just the arguments
```
In this sense we are turning a recusive functino into an iterative one because the whole state is held in one frame & we only ever jump within our routines address space.
However, this tail optimization can only happen at the tail of a routine.

View File

@ -0,0 +1,17 @@
# Single Source Shortest Path
# Bellman-ford Algorithm
Time: O(VE)
# Floyd-Warshall
Space: O(V^2)
That space is because we're using a matrix to store the paths, which of course is going to take up two dimensions
Main idea: Shortest path between any two nodes in a graph w/ V nodes _will_ go through at most V nodes
Iterative idea: Path's can visit i intermediary node. Does that many any path shorter?
Advantages: we can find negative cycles(Cycle where there is a negative edge)

View File

@ -0,0 +1,19 @@
# Spanning tree
Graph in a graph where all nodes are connected but there are
1. no cycles
2. |V-1| edges
__Minimum__
: total edge weight minimized
Things needed for next two sections:
: _time complexity_
: _space complexity_
## Kruskal
## Prim

53
370/past-midterms/2.md Normal file
View File

@ -0,0 +1,53 @@
# Time/space complexity
For basically everthing, just list it out somewhere on sheet
# AVL Tree's
Get some functions for them written out
Insert/Deletion/Lookup Functions
# No pathfinding code
_mainly cuz we never did any for homework/class_
Time/space complexities should be straightforward memorization
# Tries
# Huffman
Decoding:
: Time - O(n) {n = number of input bits}
Encoding
: Time O(nlog(n))
: Where n is the number of unique bits in the string
# Pathfinding - Conceptual things
Admissability: allowed to underestimate but not overestimate.
> Heuristic?
* A-star
* Best-first
> Multiple sources
* Floyd's Algorithm
> Multiple destination
* Floyd's
* Bellman-Ford
> Negative edges
* Floyd
* Bellman-Ford
> Negative Cycles
None

96
370/past-midterms/2.py Normal file
View File

@ -0,0 +1,96 @@
class HuffmanNode:
# $ will represent a dummy node
# anything else is a regular node
def __init__(self, data, freq):
self.data = data
self.freq = freq
class HuffmanTree:
def __init__(self, node):
self.root = node
def frequencyMap(self, string):
ret = {}
for i in string:
if i not in ret:
ret[i] = Node(i, 1)
else:
ret[i].freq += 1
return ret
def encode(self, string):
f = self.frequencyMap(string)
class TrieNode:
def __init__(self):
# 1 ref for each character in the alphabet
self.isleaf = False
self.edges = [0] * 26
class TrieTree:
def __init__(self, root):
self.root = root
# just not going to bother with capitals
def _charIndex(self, char):
return ord(char) - ord('a')
def insert(self, string):
curr = self.root
for i in string:
alphabetIndex = _charIndex(i)
if curr[alphabetIndex] is None:
curr.edges[alphabetIndex] = Node()
# go to the nexxt thing
curr = curr.edges[alphabetIndex]
else:
# Finally mark the last node as a leaf
curr.isleaf = True
def lookup(self, string):
curr = self.root
# First we should go straight to the end of the string
# That's why we don't do any checks
for i in string:
alphaIndex = _charIndex(i)
curr = curr.edges[alphaIndex]
return curr.isleaf
def remove(self, string):
pass
def traverse(self, node, preFix):
if node:
if n.isleaf:
print(prefix)
# recursively go through the tree
for i in prefix:
traverse(node.edges[_i], prefix+_charIndex(i))
class AVLNode:
def __init__(self, data):
self.data = data
self.height = 0
self.left = None
self.Right = None
class AVLTree:
def __init__(self,node):
self.root = node
def rotateLeft(self, node):
tmp = node.right
node.left = tmp.right
tmp.right = node
# Set the heights on each node
node.height = 1 + max(node.left.height, node.right.height)
tmp.height = 1 + max(tmp.left.height, tmp.right.height)
return tmp
def rotateRight(self, node):
pass

Binary file not shown.

27
370/past-midterms/tmp.py Normal file
View File

@ -0,0 +1,27 @@
class Trie:
def __init__(self, *words):
self.root = {}
for word in words:
self.insert(word)
def insert(self, word):
curr = self.root
for c in word:
if c not in curr:
curr[c] = {}
else:
curr = curr[c]
# add a marker to show that we are a leaf
curr['.'] = '.'
self.root = curr
def remove(self, word):
pass
def printWord(self, word):
pass
def all(self):
pass

59
370/past-midterms/trie.py Normal file
View File

@ -0,0 +1,59 @@
class Node:
def __init__(self, leaf=False):
# refs list of next valid characters
self.letters = [None] * 26
self.isLeaf = leaf
class Trie:
def __init__(self):
self.root = Node()
def _charIndex(self, char):
return ord(char) - ord('a')
def insert(self, string):
curr = self.root
for i in string:
refIndex = self._charIndex()
# create nodes if we have to
if curr.letters[refIndex] is None:
curr.letters[refIndex] = Node()
curr = curr.letters[refIndex]
# Set the last letter to be a leaf
curr.isLeaf = True
def remove(self, string):
# Lazy removal
curr = self.root
for i in string:
refIndex = self._charIndex(i)
if curr.letters[refIndex] is None:
break
curr = curr.letters[refIndex]
curr.isLeaf = False
# We're also going to be printing things as we go along the thing
def lookup(self, string):
curr = self.root
for i in string:
refIndex = self._charIndex(i)
# Make sure we don't walk into nothing
if curr.letters[refIndex] is None:
return False
curr = curr.letters[refIndex]
print(i, end='')
return curr.isLeaf
def all(self, node, word):
if node is None:
return
if node.isLeaf:
# Print out the word we have so far
self.lookup(word)