diff --git a/applications/expensive_seq/expensive_seq.py b/applications/expensive_seq/expensive_seq.py index 5c82b8453..00d155e21 100644 --- a/applications/expensive_seq/expensive_seq.py +++ b/applications/expensive_seq/expensive_seq.py @@ -1,8 +1,23 @@ # Your code here - - +# exps(x, y, z) = + # if x <= 0: y + z + # if x > 0: exps(x-1,y+1,z) + exps(x-2,y+2,z*2) + exps(x-3,y+3,z*3) + +nums = {} def expensive_seq(x, y, z): # Your code here + if (x, y, z) in nums.keys(): + return nums[(x, y, z)] + + if x <= 0: + return y + z + + if x > 0: + value = expensive_seq(x-1, y+1, z) + expensive_seq(x-2, + y+2, z*2) + expensive_seq(x-3, y+3, z*3) + + nums[(x, y, z)] = value + return value diff --git a/applications/histo/histo.py b/applications/histo/histo.py index 6014a8e13..1fae32588 100644 --- a/applications/histo/histo.py +++ b/applications/histo/histo.py @@ -1,2 +1,3 @@ # Your code here - +with open("applications/histo/robin.txt") as f: + words = f.read() diff --git a/applications/lookup_table/lookup_table.py b/applications/lookup_table/lookup_table.py index 05b7d37fa..e631da6ad 100644 --- a/applications/lookup_table/lookup_table.py +++ b/applications/lookup_table/lookup_table.py @@ -1,4 +1,8 @@ # Your code here +import math +import random + + def slowfun_too_slow(x, y): @@ -9,12 +13,24 @@ def slowfun_too_slow(x, y): return v +nums = {} + def slowfun(x, y): """ Rewrite slowfun_too_slow() in here so that the program produces the same output, but completes quickly instead of taking ages to run. """ # Your code here + if (x, y) in nums.keys(): + return nums[(x, y)] + + v = math.pow(x, y) + v = math.factorial(v) + v //= (x + y) + v %= 982451653 + nums[(x, y)] = v + + return v @@ -24,3 +40,8 @@ def slowfun(x, y): x = random.randrange(2, 14) y = random.randrange(3, 6) print(f'{i}: {x},{y}: {slowfun(x, y)}') + +# for i in range(50000): +# x = random.randrange(2, 14) +# y = random.randrange(3, 6) +# print(f'{i}: {x},{y}: {slowfun_too_slow(x, y)}') diff --git a/applications/markov/markov.py b/applications/markov/markov.py index 1d138db10..5230a5157 100644 --- a/applications/markov/markov.py +++ b/applications/markov/markov.py @@ -1,13 +1,72 @@ import random # Read in all the words in one go -with open("input.txt") as f: +with open("applications/markov/input.txt") as f: words = f.read() # TODO: analyze which words can follow other words # Your code here + word_list = words.split() + markov = {} + last_word = None + for index in range(1, len(word_list)): + last_word = word_list[index - 1] + word = word_list[index] + if last_word not in markov.keys(): + markov[last_word] = [word] + else: + markov[last_word].append(word) + + # print(markov) # TODO: construct 5 random sentences -# Your code here + select_word = word_list[random.randint(0, len(word_list)-1)] + sentence = select_word + " " + for word in range(20): + words = markov[select_word] + select_word = words[random.randint(0, len(words)-1)] + sentence += select_word + " " + + print("") + print(sentence) + + select_word = word_list[random.randint(0, len(word_list)-1)] + sentence = select_word + " " + for word in range(20): + words = markov[select_word] + select_word = words[random.randint(0, len(words)-1)] + sentence += select_word + " " + + print("") + print(sentence) + + select_word = word_list[random.randint(0, len(word_list)-1)] + sentence = select_word + " " + for word in range(20): + words = markov[select_word] + select_word = words[random.randint(0, len(words)-1)] + sentence += select_word + " " + + print("") + print(sentence) + + select_word = word_list[random.randint(0, len(word_list)-1)] + sentence = select_word + " " + for word in range(20): + words = markov[select_word] + select_word = words[random.randint(0, len(words)-1)] + sentence += select_word + " " + + print("") + print(sentence) + + select_word = word_list[random.randint(0, len(word_list)-1)] + sentence = select_word + " " + for word in range(20): + words = markov[select_word] + select_word = words[random.randint(0, len(words)-1)] + sentence += select_word + " " + print("") + print(sentence) diff --git a/applications/no_dups/no_dups.py b/applications/no_dups/no_dups.py index caa162c8c..bffff484e 100644 --- a/applications/no_dups/no_dups.py +++ b/applications/no_dups/no_dups.py @@ -1,5 +1,16 @@ def no_dups(s): # Your code here + duplicates = {} + sentence = "" + + words = s.split() + + for word in words: + if word not in duplicates.keys(): + duplicates[word] = word + sentence += word + " " + sentence = sentence[:-1] + return sentence diff --git a/applications/word_count/word_count.py b/applications/word_count/word_count.py index a20546425..a0171541a 100644 --- a/applications/word_count/word_count.py +++ b/applications/word_count/word_count.py @@ -1,6 +1,41 @@ def word_count(s): - # Your code here + # Your code here + words = s.replace(",", "") + words = words.replace(".", "") + words = words.replace("\"", "") + words = words.replace(":", "") + words = words.replace(";", "") + words = words.replace("-", "") + words = words.replace("+", "") + words = words.replace("=", "") + words = words.replace("/", "") + words = words.replace("\\", "") + words = words.replace("|", "") + words = words.replace("[", "") + words = words.replace("]", "") + words = words.replace("{", "") + words = words.replace("}", "") + words = words.replace("(", "") + words = words.replace(")", "") + words = words.replace("*", "") + words = words.replace("^", "") + words = words.replace("&", "") + words = words.lower() + words = words.split() + + + count = {} + for word in words: + # if not word.isalpha(): + # continue + if word in count.keys(): + count[word] += 1 + else: + count[word] = 1 + + + return count if __name__ == "__main__": diff --git a/hashtable/hashtable.py b/hashtable/hashtable.py index 0205f0ba9..df6b136b4 100644 --- a/hashtable/hashtable.py +++ b/hashtable/hashtable.py @@ -6,6 +6,8 @@ def __init__(self, key, value): self.key = key self.value = value self.next = None + # def __repr__(self): + # return f"{self.key}, {self.value}" # Hash table can't have fewer than this many slots @@ -22,28 +24,21 @@ class HashTable: def __init__(self, capacity): # Your code here + self.capacity = capacity + self.storage = [None] * capacity + self.total = 0 + def get_num_slots(self): - """ - Return the length of the list you're using to hold the hash - table data. (Not the number of items stored in the hash table, - but the number of slots in the main list.) - - One of the tests relies on this. - - Implement this. - """ - # Your code here + + return len(self.storage) def get_load_factor(self): - """ - Return the load factor for this hash table. - - Implement this. - """ - # Your code here + + return self.total / self.capacity + # pass def fnv1(self, key): @@ -54,6 +49,7 @@ def fnv1(self, key): """ # Your code here + pass def djb2(self, key): @@ -63,6 +59,10 @@ def djb2(self, key): Implement this, and/or FNV-1. """ # Your code here + hash_value = 5381 + for c in key: + hash_value = ((hash_value << 5) + hash_value) + ord(c) + return hash_value & 0xFFFFFFFF def hash_index(self, key): @@ -74,48 +74,102 @@ def hash_index(self, key): return self.djb2(key) % self.capacity def put(self, key, value): - """ - Store the value with the given key. - - Hash collisions should be handled with Linked List Chaining. - - Implement this. - """ - # Your code here + + + # Day 1 + # new_node = HashTableEntry(key, value) + # index = self.hash_index(key) + # if self.storage[index] == None: + # self.storage[index] = new_node + + # elif self.storage[index].key == key: + # self.storage[index].value = value + index = self.hash_index(key) + cur_entry = self.storage[index] + + while cur_entry is not None and cur_entry != key: + cur_entry = cur_entry.next + + if cur_entry is not None: + cur_entry.value = value + else: + new_entry = HashTableEntry(key, value) + new_entry.next = self.storage[index] + self.storage[index] = new_entry + + self.total += 1 + if self.get_load_factor() > 0.7: + self.resize(self.capacity * 2) + + def delete(self, key): - """ - Remove the value stored with the given key. - - Print a warning if the key is not found. - - Implement this. - """ - # Your code here - - + + # Day 1 + # index = self.hash_index(key) + # if self.storage[index].key == key: + # self.storage[index] = None + index = self.hash_index(key) + + current_entry = self.storage[index] + last_entry = None + + while current_entry is not None and current_entry.key != key: + last_entry = current_entry + current_entry = last_entry.next + + if current_entry is None: + print("ERROR: Unable to remove entry with key " + key) + else: + if last_entry is None: + self.storage[index] = current_entry.next + else: + last_entry.next = current_entry.next + + self.total -= 1 + if self.get_load_factor() < 0.2: + if self.capacity > MIN_CAPACITY: + new_capacity = self.capacity // 2 + if new_capacity < MIN_CAPACITY: + new_capacity = MIN_CAPACITY + + self.resize(new_capacity) + def get(self, key): - """ - Retrieve the value stored with the given key. - - Returns None if the key is not found. - Implement this. - """ - # Your code here + # Day 1 + # index = self.hash_index(key) + # node = self.storage[index] + + # if node is not None: + + # if node.key == key: + # return node.value + index = self.hash_index(key) + + if (self.storage[index] and self.storage[index].key == key): + return self.storage[index].value + else: + return None + def resize(self, new_capacity): + old_storage = self.storage + self.capacity = new_capacity + self.storage = [None] * self.capacity - def resize(self, new_capacity): - """ - Changes the capacity of the hash table and - rehashes all key/value pairs. + cur_entry = None + old_total = self.total - Implement this. - """ - # Your code here + for total_item in old_storage: + cur_entry = total_item + while cur_entry is not None: + self.put(cur_entry.key, cur_entry.value) + cur_entry = cur_entry.next + self.total = old_total + if __name__ == "__main__": ht = HashTable(8) @@ -136,6 +190,10 @@ def resize(self, new_capacity): print("") # Test storing beyond capacity + print("Should only print 8 lines") + print(" ") + print(f"Prints {ht.capacity} lines") + print(" ") for i in range(1, 13): print(ht.get(f"line_{i}")) diff --git a/hashtable/test_hashtable_resize.py b/hashtable/test_hashtable_resize.py index 02ba7b316..bf074c203 100644 --- a/hashtable/test_hashtable_resize.py +++ b/hashtable/test_hashtable_resize.py @@ -170,6 +170,7 @@ def test_hash_table_resize(self): ht.resize(1024) self.assertTrue(ht.get_num_slots() == 1024) + return_value = ht.get("key-0") self.assertTrue(return_value == "val-0")