diff --git a/.idea/Hash-Tables.iml b/.idea/Hash-Tables.iml new file mode 100644 index 000000000..7576af97f --- /dev/null +++ b/.idea/Hash-Tables.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 000000000..105ce2da2 --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 000000000..662af4a04 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 000000000..f61a7ebb3 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 000000000..94a25f7f4 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 000000000..0bacd2cf7 --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1583772559332 + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/chains.py b/src/chains.py new file mode 100644 index 000000000..e52688ff3 --- /dev/null +++ b/src/chains.py @@ -0,0 +1,23 @@ +import random + +def longest_linked_list_chain(keys, buckets, loops=10): + """roll keys number of keys into buckets number of random buckets and count collisions""" + + for i in range(loops): + # dictionary pythongs implementation of a hashtable + key_counts = {} + for i in range(buckets): + key_counts[i] = 0 + for i in range(keys): + random_key = str(random.random()) + hash_index = hash(random) % buckets + key_counts[hash_index] += 1 + + largest_number = 0 + for key in key_counts: + if key_counts[key] > largest_number: + largest_number = key_counts[key] + + print(f"Longest Linked list chain for {keys} keys in {buckets} buckets (load factor: {keys/buckets:.2f}): {largest_number}") + +longest_linked_list_chain(5, 100, 5) \ No newline at end of file diff --git a/src/collisions.py b/src/collisions.py new file mode 100644 index 000000000..2c44a58de --- /dev/null +++ b/src/collisions.py @@ -0,0 +1,24 @@ +import random + +def how_many_before_collisions(buckets, loops=1): + # roll random hashes indexes into buckets and p[rint how many rolls before a collision + # run loops times + + for i in range(loops): + tries = 0 + tried = set() + + while True: + random_key = str(random.random()) + hash_index = hash(random_key) % buckets + if hash_index not in tried: + tried.add(hash_index) + tries += 1 + + else: + # we have collision + break + # 1 decimal format + print(f"{buckets} buckets, {tries} hashes before collision. ({tries/buckets * 100:.1f}%") + +how_many_before_collisions(1000, 1) \ No newline at end of file diff --git a/src/dynamic_array.py b/src/dynamic_array.py new file mode 100644 index 000000000..e3be3e8bb --- /dev/null +++ b/src/dynamic_array.py @@ -0,0 +1,42 @@ +class DynamicArray: + # my_array = [4] + def __init__(self, capacity): + self.capacity = capacity + self.count = 0 + self.storage = [None] * self.capacity + + def insert(self, index, value): + # 2nd- make sure we have open space + if self.count >= self.capacity: + self.double_size + # 3rd- make sure index is in range + if index > self.count: + print("error out of range") + return + + # shift everything over + # 4th - start with the last one, move it 1: int right + for i in range(self.count, index, -1): + self.storage[i] = self.storage[i-1] + + # 1st- insert out value + self.storage[index] = value + self.count += 1 + + def append(self, value): + self.insert(self.count, value) + + def double_size(self): + self.capacity *= 2 + new_storage = [None] * self.capacity + + + +my_array = DynamicArray(4) +my_array.insert(0, 1) +my_array.insert(0, 2) +my_array.insert(1, 3) +my_array.insert(3, 4) +my_array.insert(0, 5) +my_array.append(20) +print(my_array.storage) \ No newline at end of file diff --git a/src/hashes.py b/src/hashes.py new file mode 100644 index 000000000..7365d82a2 --- /dev/null +++ b/src/hashes.py @@ -0,0 +1,26 @@ +import hashlib + +n = 10 +# b turns into byte array +key = b"string" +# same as above +key2 = "string".encode() +key3 = b"lunchtime" + + +index = hash(key) % 8 +index = hash(key2) % 8 +index = hash(key3) % 8 +print(index1) +print(index2) +print(index3) + +# for i in range(n): +# print(hash(key)) +# print(hashlib.sha256(key).hexdigest()) +# +# for i in range(n): +# print(hash(key) +# +# for i in range(n): +# print(hash(key2) \ No newline at end of file diff --git a/src/hashtable.py b/src/hashtable.py index a68c6ea1c..8b79f7ccb 100644 --- a/src/hashtable.py +++ b/src/hashtable.py @@ -1,6 +1,7 @@ +import hashlib # ''' # Linked List hash table key/value pair -# ''' +# Singly linked list -- LinkedPair''' class LinkedPair: def __init__(self, key, value): self.key = key @@ -23,7 +24,7 @@ def _hash(self, key): You may replace the Python hash with DJB2 as a stretch goal. ''' - return hash(key) + return hashlib.sha256(key.encode()) def _hash_djb2(self, key): @@ -51,7 +52,12 @@ def insert(self, key, value): Fill this in. ''' - pass + index = self._hash_mod(key) + + if self.storage[index] is not None: + print("error: key in use") + else: + self.storage[index] = value @@ -63,7 +69,12 @@ def remove(self, key): Fill this in. ''' - pass + index = self._hash_mod(key) + + if self.storage[index] is not None: + self.storage[index] = None + else: + print('warning key not found') def retrieve(self, key): @@ -74,7 +85,10 @@ def retrieve(self, key): Fill this in. ''' - pass + index = self._hash_mod(key) + # if its none it meets spec, still works + return self.storage[index] + def resize(self): @@ -84,7 +98,17 @@ def resize(self): Fill this in. ''' - pass + + + old_storage = self.storage.copy() + self.capacity = self.capacity * 2 + self.storage = [None] * self.capacity + + for bucket_item in old_storage: + self.insert(bucket_item) + + +