diff --git a/DIRECTORY.md b/DIRECTORY.md index 2e9c03cbcd9b..1ee106252ce2 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -444,6 +444,7 @@ * [Scoring Functions](machine_learning/scoring_functions.py) * [Sequential Minimum Optimization](machine_learning/sequential_minimum_optimization.py) * [Similarity Search](machine_learning/similarity_search.py) + * [Support Vector Machines](machine_learning/support_vector_machines.py) * [Word Frequency Functions](machine_learning/word_frequency_functions.py) ## Maths @@ -500,6 +501,7 @@ * [Gaussian](maths/gaussian.py) * [Greatest Common Divisor](maths/greatest_common_divisor.py) * [Greedy Coin Change](maths/greedy_coin_change.py) + * [Hamming Numbers](maths/hamming_numbers.py) * [Hardy Ramanujanalgo](maths/hardy_ramanujanalgo.py) * [Integration By Simpson Approx](maths/integration_by_simpson_approx.py) * [Is Ip V4 Address Valid](maths/is_ip_v4_address_valid.py) @@ -938,6 +940,7 @@ * [Bogo Sort](sorts/bogo_sort.py) * [Bubble Sort](sorts/bubble_sort.py) * [Bucket Sort](sorts/bucket_sort.py) + * [Circle Sort](sorts/circle_sort.py) * [Cocktail Shaker Sort](sorts/cocktail_shaker_sort.py) * [Comb Sort](sorts/comb_sort.py) * [Counting Sort](sorts/counting_sort.py) diff --git a/project_euler/problem_145/sol1.py b/project_euler/problem_145/sol1.py index 09d8daff57be..e9fc1a199161 100644 --- a/project_euler/problem_145/sol1.py +++ b/project_euler/problem_145/sol1.py @@ -1,6 +1,6 @@ """ Project Euler problem 145: https://projecteuler.net/problem=145 -Author: Vineet Rao +Author: Vineet Rao, Maxim Smolskiy Problem statement: Some positive integers n have the property that the sum [ n + reverse(n) ] @@ -13,44 +13,82 @@ How many reversible numbers are there below one-billion (10^9)? """ +EVEN_DIGITS = [0, 2, 4, 6, 8] +ODD_DIGITS = [1, 3, 5, 7, 9] -def odd_digits(num: int) -> bool: +def reversible_numbers( + remaining_length: int, remainder: int, digits: list[int], length: int +) -> int: """ - Check if the number passed as argument has only odd digits. - >>> odd_digits(123) - False - >>> odd_digits(135797531) - True + Count the number of reversible numbers of given length. + Iterate over possible digits considering parity of current sum remainder. + >>> reversible_numbers(1, 0, [0], 1) + 0 + >>> reversible_numbers(2, 0, [0] * 2, 2) + 20 + >>> reversible_numbers(3, 0, [0] * 3, 3) + 100 """ - while num > 0: - digit = num % 10 - if digit % 2 == 0: - return False - num //= 10 - return True + if remaining_length == 0: + if digits[0] == 0 or digits[-1] == 0: + return 0 + for i in range(length // 2 - 1, -1, -1): + remainder += digits[i] + digits[length - i - 1] -def solution(max_num: int = 1_000_000_000) -> int: + if remainder % 2 == 0: + return 0 + + remainder //= 10 + + return 1 + + if remaining_length == 1: + if remainder % 2 == 0: + return 0 + + result = 0 + for digit in range(10): + digits[length // 2] = digit + result += reversible_numbers( + 0, (remainder + 2 * digit) // 10, digits, length + ) + return result + + result = 0 + for digit1 in range(10): + digits[(length + remaining_length) // 2 - 1] = digit1 + + if (remainder + digit1) % 2 == 0: + other_parity_digits = ODD_DIGITS + else: + other_parity_digits = EVEN_DIGITS + + for digit2 in other_parity_digits: + digits[(length - remaining_length) // 2] = digit2 + result += reversible_numbers( + remaining_length - 2, + (remainder + digit1 + digit2) // 10, + digits, + length, + ) + return result + + +def solution(max_power: int = 9) -> int: """ To evaluate the solution, use solution() - >>> solution(1000) + >>> solution(3) 120 - >>> solution(1_000_000) + >>> solution(6) 18720 - >>> solution(10_000_000) + >>> solution(7) 68720 """ result = 0 - # All single digit numbers reverse to themselves, so their sums are even - # Therefore at least one digit in their sum is even - # Last digit cannot be 0, else it causes leading zeros in reverse - for num in range(11, max_num): - if num % 10 == 0: - continue - num_sum = num + int(str(num)[::-1]) - num_is_reversible = odd_digits(num_sum) - result += 1 if num_is_reversible else 0 + for length in range(1, max_power + 1): + result += reversible_numbers(length, 0, [0] * length, length) return result