diff --git a/python/e114.py b/python/e114.py new file mode 100644 index 0000000..eb8fab2 --- /dev/null +++ b/python/e114.py @@ -0,0 +1,51 @@ +from functools import lru_cache + + +@lru_cache() +def block_combinations(row_length: int): + + if row_length == 0: + return 1 + + min_block_length = 3 + result = 0 + + # Moving from left to right. Let's say we have four spaces (____), then + # there are three options + + # Use a blank: + # -___ + result = block_combinations(row_length - 1) + + # Or add 3: + # ooo_ + # For this case, the issue is that if we call block_combinations again with + # _, then it could happen that we will up with further o and double count. + # Therefore, for all cases where the spaces are not all filled, we will add + # a space. + for new_block in range(min_block_length, row_length): + result += block_combinations(row_length - new_block - 1) + + # Or add 4: + # oooo + if row_length >= min_block_length: + result += 1 + + return result + + +def euler_114(): + assert block_combinations(0) == 1 + assert block_combinations(1) == 1 + assert block_combinations(2) == 1 + assert block_combinations(3) == 2 + assert block_combinations(4) == 4 + assert block_combinations(7) == 17 + return block_combinations(50) + + +if __name__ == "__main__": + solution = euler_114() + print("e114.py: " + str(solution)) + # assert(solution == 0) + diff --git a/python/e115.py b/python/e115.py new file mode 100644 index 0000000..b309131 --- /dev/null +++ b/python/e115.py @@ -0,0 +1,28 @@ +from functools import lru_cache + + +@lru_cache() +def block_combinations(row_length: int, min_block_length: int = 3): + if row_length == 0: + return 1 + result = 0 + result = block_combinations(row_length - 1, min_block_length) + for new_block in range(min_block_length, row_length): + result += block_combinations(row_length - new_block - 1, min_block_length) + if row_length >= min_block_length: + result += 1 + return result + + +def euler_115(): + for n in range(1000): + if block_combinations(n, 50) > 10**6: + return n + return -1 + + +if __name__ == "__main__": + solution = euler_115() + print("e115.py: " + str(solution)) + assert(solution == 168) + diff --git a/python/e116.py b/python/e116.py new file mode 100644 index 0000000..d198642 --- /dev/null +++ b/python/e116.py @@ -0,0 +1,31 @@ +from functools import lru_cache + + +@lru_cache() +def block_combinations(row_length: int, block_length: int = 3): + if row_length < 0: + return 0 + + if row_length == 0: + return 1 + + result = block_combinations(row_length - 1, block_length) + result += block_combinations(row_length - block_length, block_length) + return result + + +def solve(row_length: int): + r = block_combinations(row_length, 2) - 1 + r += block_combinations(row_length, 3) - 1 + r += block_combinations(row_length, 4) - 1 + return r + + +def euler_116(): + return solve(50) + + +if __name__ == "__main__": + solution = euler_116() + print("e116.py: " + str(solution)) + assert(solution == 20492570929) diff --git a/python/e117.py b/python/e117.py new file mode 100644 index 0000000..4cecf45 --- /dev/null +++ b/python/e117.py @@ -0,0 +1,30 @@ +from functools import lru_cache + + +@lru_cache() +def block_combinations(row_length: int): + block_sizes = [2, 3, 4] + if row_length < 0: + return 0 + + if row_length == 0: + return 1 + + # space + result = block_combinations(row_length - 1) + + # one of the blocks + for block_length in block_sizes: + result += block_combinations(row_length - block_length) + + return result + + +def euler_117(): + return block_combinations(50) + + +if __name__ == "__main__": + solution = euler_117() + print("e117.py: " + str(solution)) + assert(solution == 100808458960497)