Write the function smallest_table(keys, hash_fn, max_bucket). Assume keys is a list of strings (a key may appear more than once), hash_fn is a function that takes one key and returns a non-negative int, and max_bucket is a positive int.
A hash table with size slots puts a key in slot hash_fn(key) % size. A bigger table wastes memory; a smaller one piles keys into the same slot. Return the smallest table size (at least 1) for which no slot receives more than max_bucket distinct keys — a repeated key is stored only once. An empty keys list fits in a table of size 1. You may assume that some size of at most 10 000 works.
def letter_sum(key): return sum(ord(c) - ord('a') + 1 for c in key.lower()) names = ['Ana', 'Eric', 'John', 'Eve'] print(smallest_table(names, letter_sum, 2)) # 2 print(smallest_table(names, letter_sum, 1)) # 7 print(smallest_table(['Eve', 'Eve', 'Eve'], letter_sum, 1)) # 1