Returns the number of numbers below number_limit that produce chains with exactly chain_length non repeating elements. >>> solution(10.0, 1000) Traceback (most recent call last): ... TypeError: Parameters chain_length and number_limit must be int >>> solution(10, 1
(chain_length: int = 60, number_limit: int = 1000000)
| 70 | |
| 71 | |
| 72 | def solution(chain_length: int = 60, number_limit: int = 1000000) -> int: |
| 73 | """ |
| 74 | Returns the number of numbers below number_limit that produce chains with exactly |
| 75 | chain_length non repeating elements. |
| 76 | |
| 77 | >>> solution(10.0, 1000) |
| 78 | Traceback (most recent call last): |
| 79 | ... |
| 80 | TypeError: Parameters chain_length and number_limit must be int |
| 81 | |
| 82 | >>> solution(10, 1000.0) |
| 83 | Traceback (most recent call last): |
| 84 | ... |
| 85 | TypeError: Parameters chain_length and number_limit must be int |
| 86 | |
| 87 | >>> solution(0, 1000) |
| 88 | Traceback (most recent call last): |
| 89 | ... |
| 90 | ValueError: Parameters chain_length and number_limit must be greater than 0 |
| 91 | |
| 92 | >>> solution(10, 0) |
| 93 | Traceback (most recent call last): |
| 94 | ... |
| 95 | ValueError: Parameters chain_length and number_limit must be greater than 0 |
| 96 | |
| 97 | >>> solution(10, 1000) |
| 98 | 26 |
| 99 | """ |
| 100 | |
| 101 | if not isinstance(chain_length, int) or not isinstance(number_limit, int): |
| 102 | raise TypeError("Parameters chain_length and number_limit must be int") |
| 103 | |
| 104 | if chain_length <= 0 or number_limit <= 0: |
| 105 | raise ValueError( |
| 106 | "Parameters chain_length and number_limit must be greater than 0" |
| 107 | ) |
| 108 | |
| 109 | # the counter for the chains with the exact desired length |
| 110 | chains_counter = 0 |
| 111 | # the cached sizes of the previous chains |
| 112 | chain_sets_lengths: dict[int, int] = {} |
| 113 | |
| 114 | for start_chain_element in range(1, number_limit): |
| 115 | # The temporary set will contain the elements of the chain |
| 116 | chain_set = set() |
| 117 | chain_set_length = 0 |
| 118 | |
| 119 | # Stop computing the chain when you find a cached size, a repeating item or the |
| 120 | # length is greater then the desired one. |
| 121 | chain_element = start_chain_element |
| 122 | while ( |
| 123 | chain_element not in chain_sets_lengths |
| 124 | and chain_element not in chain_set |
| 125 | and chain_set_length <= chain_length |
| 126 | ): |
| 127 | chain_set.add(chain_element) |
| 128 | chain_set_length += 1 |
| 129 | chain_element = digit_factorial_sum(chain_element) |
no test coverage detected