Learn

Great job so far! You are certainly an expert when it comes to searching for patterns using brute force. But judging from how long it took the last program to run, naive pattern-matching seems to be approaching the limits of its abilities. Fortunately, we can do better with a bit of help from an old friend of ours — hashing.

Let’s create a simple hash function to calculate the hash values of strings involving only the uppercase alphabet. Of course, not all strings where we want to find patterns will consist of well-arranged characters from `A-Z`, but this is a good way to get some practice before dealing with all kinds of strings.

To calculate unique hash values for a given string of uppercase letters, we must first calculate a unique value for each character somehow. How can we do this?

One idea is to map each character in the string to its corresponding ASCII value and take the product of the ASCII values. We will call this the ASCII hash. Let’s calculate the ASCII hash of some strings using this approach.

### Instructions

1.

Complete the function `ascii_hash()` to return the ASCII hash of a generic substring `s` of `uppercase` by multiplying the ASCII value corresponding to each character `c` in the substring `s` using the `ord()` function.

2.

Use string slicing and a `for` loop to access all the substrings of length `4` in `uppercase`. Find the ASCII hash of each of these substrings using the `ascii_hash()` function you have just implemented.

Create a dictionary `ascii_hash_values` and store the mapping of each substring of length `4` to its corresponding ASCII hash in this dictionary. Print out `ascii_hash_values` to see the results!

3.

Challenge: Can you find a pair of strings with different characters that hash to the same value using this approach?

Find two such strings and store them in the variables `string1` and `string2`.

Create a dictionary `colliding_hash_values` that maps `string1` and `string2` to the same hash value. Print out `colliding_hash_values` to see the results!