From bbb0bd0e2141760d938ce442687dedccfa3949c9 Mon Sep 17 00:00:00 2001 From: elishamutang Date: Sun, 23 Jun 2024 06:59:18 +0800 Subject: [PATCH 1/3] Added hash map tests after assignment section. Also fixed some Ruby syntax in Assignment section. --- ruby/computer_science/project_hash_map.md | 51 +++++++++++++++++++++-- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/ruby/computer_science/project_hash_map.md b/ruby/computer_science/project_hash_map.md index 2a88507481e..986f911a291 100644 --- a/ruby/computer_science/project_hash_map.md +++ b/ruby/computer_science/project_hash_map.md @@ -36,18 +36,20 @@ You already know the magic behind hash maps, now it's time to write your own imp You might find yourself confusing keys with hash codes while accessing key-value pairs later. We would like to stress that the key is what your `hash` function will take as an input. In a way, we could say that the key is important for us only inside the `hash` function. But we never access a bucket directly with the key. Instead we do so with the hash code.
+ Hash maps could accommodate various data types for keys like numbers, strings, and even other hashes. But for this project, only handle keys of type strings. +
- 1. `set(key, value)` takes two arguments, the first is a key and the second is a value that is assigned to this key. If a key already exists, then the old value is overwritten or we can say that we *update* the key's value (e.g. `Carlos` is our key but it is called twice: once with value `I am the old value.`, and once with value `I am the new value.`. From the logic stated above, `Carlos` should contain only the latter value). + 1. `#set(key, value)` takes two arguments, the first is a key and the second is a value that is assigned to this key. If a key already exists, then the old value is overwritten or we can say that we *update* the key's value (e.g. `Carlos` is our key but it is called twice: once with value `I am the old value.`, and once with value `I am the new value.`. From the logic stated above, `Carlos` should contain only the latter value). In the meantime, a collision is when *TWO DIFFERENT* keys sit inside the same bucket, because they generate the same hash code (e.g. `Carlos` and `Carla` are both hashed to `3`, so `3` becomes a location for `Carlos` AND `Carla`. However, we know that it is the collision. It means we should find a way how to resolve it — how to *deal with collisions*, which was mentioned in the previous lesson). - - Remember to grow your buckets size when it needs to, by calculating if your bucket has reached the `load factor`. Some of the methods in this assignment that are mentioned later could be reused to help you handle that growth logic more easily. So you may want to hold onto implementing your growing functionality just for now. However, the reason why we mention it with `set()` is because it's important to grow buckets exactly when they are being expanded. + - Remember to grow your buckets size when it needs to, by calculating if your bucket has reached the `load factor`. Some of the methods in this assignment that are mentioned later could be reused to help you handle that growth logic more easily. So you may want to hold onto implementing your growing functionality just for now. However, the reason why we mention it with `#set` is because it's important to grow buckets exactly when they are being expanded. 1. `#get(key)` takes one argument as a key and returns the value that is assigned to this key. If key is not found, return `nil`. - 1. `#has?(key)` takes a key as an argument and returns `true` or `false` based on whether or not the key is in the hash map. + 1. `#has(key)` takes a key as an argument and returns `true` or `false` based on whether or not the key is in the hash map. 1. `#remove(key)` takes a key as an argument. If the given key is in the hash map, it should remove the entry with that key and return the deleted entry's value. If the key isn't in the hash map, it should return `nil`. @@ -63,6 +65,49 @@ You already know the magic behind hash maps, now it's time to write your own imp Remember that our hash map does not preserve insertion order when you are retrieving your hash map's data. It is normal and expected for keys and values to appear out of the order you inserted them in. +#### Test Your Hash Map + +1. Create a new Ruby file. + +1. Create a new instance of your hash map and set the load factor to be `0.75`. + + ```ruby + test = HashMap.new + ``` + +1. Populate your hash map using the `#set(key, value)` method by copying the following: + + ```ruby + test.set('apple', 'red') + test.set('banana', 'yellow') + test.set('carrot', 'orange') + test.set('dog', 'brown') + test.set('elephant', 'gray') + test.set('frog', 'green') + test.set('grape', 'purple') + test.set('hat', 'black') + test.set('ice cream', 'white') + test.set('jacket', 'blue') + test.set('kite', 'pink') + test.set('lion', 'golden') + ``` + +1. After populating your hash map with the data above, your hash map's actual capacity should now be at `0.75` (full capacity). + +1. Now with a full hash map, try overwriting a few nodes using `#set(key, value)`. By right, this should only over-write the existing `values` of your nodes and not add new ones. + +1. After that, populate your hash map with the last node below (doing this will make your hash map exceed your current load factor, hence expanding your buckets and growing your hash map): + + ```ruby + test.set('moon', 'silver') + ``` + +1. If you have implemented your hash map correctly, the capacity of your new hash map will drop well below your load factor and you will notice that the nodes in your hash map are spread much evenly among your buckets. + +1. With your new hash map, try overwriting a few nodes using `#set(key, value)`. Again, this should only over-write existing `values` of your nodes. + +1. Test the other methods of your hash maps such as `#get(key)`, `#has(key)`, `#remove(key)`, `#length`, `#clear`, `#keys`, `#values`, and `#entries` to check if they are still working as expected after expanding your hash map. + #### Extra Credit - Create a class `HashSet` that behaves the same as a `HashMap` but only contains `keys` with no `values`. From 2cbbc1be7a54b4172a252838cbee26d6eae32a49 Mon Sep 17 00:00:00 2001 From: elishamutang Date: Sun, 23 Jun 2024 23:14:19 +0800 Subject: [PATCH 2/3] Revert to original text for has method. --- ruby/computer_science/project_hash_map.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/computer_science/project_hash_map.md b/ruby/computer_science/project_hash_map.md index 986f911a291..72636447b65 100644 --- a/ruby/computer_science/project_hash_map.md +++ b/ruby/computer_science/project_hash_map.md @@ -49,7 +49,7 @@ You already know the magic behind hash maps, now it's time to write your own imp 1. `#get(key)` takes one argument as a key and returns the value that is assigned to this key. If key is not found, return `nil`. - 1. `#has(key)` takes a key as an argument and returns `true` or `false` based on whether or not the key is in the hash map. + 1. `#has?(key)` takes a key as an argument and returns `true` or `false` based on whether or not the key is in the hash map. 1. `#remove(key)` takes a key as an argument. If the given key is in the hash map, it should remove the entry with that key and return the deleted entry's value. If the key isn't in the hash map, it should return `nil`. From 722597840f34a7ea841d43adc7a33ee5aab12878 Mon Sep 17 00:00:00 2001 From: Elisha <138951172+elishamutang@users.noreply.github.com> Date: Tue, 25 Jun 2024 09:07:19 +0800 Subject: [PATCH 3/3] Added ? to #has method Co-authored-by: Josh Smith --- ruby/computer_science/project_hash_map.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/computer_science/project_hash_map.md b/ruby/computer_science/project_hash_map.md index 72636447b65..106a0731831 100644 --- a/ruby/computer_science/project_hash_map.md +++ b/ruby/computer_science/project_hash_map.md @@ -106,7 +106,7 @@ You already know the magic behind hash maps, now it's time to write your own imp 1. With your new hash map, try overwriting a few nodes using `#set(key, value)`. Again, this should only over-write existing `values` of your nodes. -1. Test the other methods of your hash maps such as `#get(key)`, `#has(key)`, `#remove(key)`, `#length`, `#clear`, `#keys`, `#values`, and `#entries` to check if they are still working as expected after expanding your hash map. +1. Test the other methods of your hash maps such as `#get(key)`, `#has?(key)`, `#remove(key)`, `#length`, `#clear`, `#keys`, `#values`, and `#entries` to check if they are still working as expected after expanding your hash map. #### Extra Credit