def recursive_paths(dimensions, path_history=""): """ calculates the number of paths through an m x n grid dimensions (list): specifies an m x n grid as [m, n] returns (int): number of paths """ # logging stub = Stub() stub.start() # base case if dimensions == [0, 0]: stub.msg(path_history, "path found") return 1 # path and history initialization paths = 0 path_history_r = path_history_d = path_history # recursion if dimensions[0] > 0: path_history_r += "r" paths += recursive_paths([dimensions[0]-1, dimensions[1]], path_history_r) if dimensions[1] > 0: path_history_d += "d" paths += recursive_paths([dimensions[0], dimensions[1]-1], path_history_d) return paths
def longest_collatz_sequence(limit): """ exhaustively finds the longest collatz sequence from starting numbers up to a certain limit, exclusive limit (int): limit, exclusive returns (int): starting number """ stub = Stub() stub.start() max_steps = 0 max_start_num = 1 collatz_branches = {} for num in range(1, limit): next_num = next_collatz_number if next_num in collatz_branches: collatz_sequence = [num] + collatz_branches[next_num] else: collatz_sequence = get_collatz_sequence(num) steps = len(collatz_sequence) if steps > max_steps: max_steps = steps max_start_num = num stub.msg(str(max_steps) + " steps", max_start_num) collatz_branches[num] = collatz_sequence return max_start_num
def largest_palindrome_product(minimum=100, maximum=999): """ exhaustively finds the largest palindromic product in a range minimum, maximum (int): defines range, inclusive returns (int): solution """ stub = Stub() #stub.start() candidate_solution = None palindrome_products = [] candidate_factors = [None, None] for i in range(maximum, minimum-1, -1): for j in range(i, minimum-1, -1): product = i*j if is_palindrome(product): palindrome_products.append(product) if product > candidate_solution: candidate_solution = product candidate_factors = [i, j] stub.msg(candidate_factors, "factors") return candidate_solution
def get_fib_with_digits(num_digits): """ finds the first Fibonacci number with a certain amount of digits """ stub = Stub() stub.start() counter = 0 for num in gen_fibonacci(): if count_digits(num) >= num_digits: return counter if counter % 1000 == 0: stub.msg(count_digits(num), counter) counter += 1
def summation_of_primes(limit): """ adds all the primes up to some limit limit (int): limit, exclusive returns (int): result """ stub = Stub() stub.start() result = 0 for prime in gen_primes(limit): result += prime return result
def sum_square_difference(limit): """ finds the difference of the square of sums and sum of squares for numbers 1 through some number limit (int): limit, inclusive returns (int): difference """ stub = Stub() #stub.start() sum_of_squares = sum([num**2 for num in range(limit+1)]) square_of_sums = sum([num for num in range(limit+1)])**2 stub.msg(sum_of_squares, "sum") stub.msg(square_of_sums, "square") return square_of_sums - sum_of_squares
def special_pythagorean_triplet(): """ finds the special pythagorean triplet that also sums to 1000 returns (int): product of triplet """ stub = Stub() # stub.start() # generate power set of numbers that sum to 1000 counter = 0 for triplet in gen_triplets_that_sum_to(1000): if is_pythagorean(*triplet): stub.msg(triplet, counter) return product(triplet) counter += 1 raise ValueError("unable to find special pythagorean triplet after " + str(counter) + " trials.")
def largest_prime_factor(num): """ finds the largest prime factor of a number num (int): some number returns (int): solution """ stub = Stub() #stub.start() j = 0 for i in range(2, int(num**0.5)): j += 1 while num % i == 0: stub.msg(i, j) num //= i if num == 1 or num == i: return i
def sum_of_amicable_numbers(limit): """ finds the sum of "amicable numbers" up to some limit limit (int): limit, exclusive > 1 returns (int): solution """ stub = Stub() stub.start() stack = [] for num in range(2, limit): if num in stack: continue elif is_amicable(num): stack.append(num) stack.append(sum_of_proper_divisors(num)) stub.msg(stack[-2:]) return sum(stack)
def largest_product_in_a_grid(grid, chunk_len): """ finds the largest consecutive product in a grid (horiz, vert, diag) grid (list): 2d list or array representing grid dimensions and values chunk_len (int): length of consecutive numbers to check returns (int): solution """ stub = Stub() #stub.start() grid_rows = len(grid) grid_cols = len(grid[0]) largest = 0 # check N-S, W-E, NW-SE products for i in range(grid_rows - chunk_len): for j in range(grid_cols - chunk_len): n_s = [grid[i+n][j] for n in range(chunk_len)] w_e = grid[i][j:j+chunk_len] nw_se = [grid[i+n][j+n] for n in range(chunk_len)] for chunk in [n_s, w_e, nw_se]: if product(chunk) > largest: stub.msg(chunk) largest = product(chunk) # check SW-NE products for i in range(chunk_len-1, grid_rows): for j in range(grid_cols - chunk_len): sw_ne = [grid[i-n][j+n] for n in range(chunk_len)] if product(sw_ne) > largest: stub.msg(sw_ne) largest = product(sw_ne) return largest
def large_sum(large_numbers, first_digits): """ finds an estimated sum of several large numbers large_numbers (list): unordered list of large numbers first_digits (int): number of leading digits to calculate returns (int or long): solution """ stub = Stub() #stub.start() max_digits = len(str(large[0])) places_to_check = first_digits + int(log10(len(large_numbers)*10)) stub.msg(places_to_check, "places to check") sum_estimate = 0 for place in range(max_digits, max_digits-places_to_check, -1): temp_sum = sum([int(str(num)[max_digits-place]) for num in large_numbers]) stub.msg((str(temp_sum) + "*10^" + str(place)), "intermediate sum") sum_estimate += temp_sum * 10**place stub.msg(sum_estimate, "final sum") return sum_estimate
triangle (list): e.g. [[3], [7, 4], [2, 4, 6], [8, 5, 9, 3]] returns (int): max path sun """ # base case peak = triangle[0][0] new_path = path + [peak] if len(triangle) == 1: stub.msg(path, peak + sum(path)) return sum(new_path) # recursion left_triangle = [row[:-1] for row in triangle[1:]] left_sum = exhaustive_max_path_sum(left_triangle, new_path) right_triangle = [row[1:] for row in triangle[1:]] right_sum = exhaustive_max_path_sum(right_triangle, new_path) return max(left_sum, right_sum) if __name__ == "__main__": stub = Stub() stub.start() triangle = [[75], [95, 64], [17, 47, 82], [18, 35, 87, 10], [20, 4, 82, 47, 65], [19, 1, 23, 75, 3, 34], [88, 2, 77, 73, 7, 63, 67], [99, 65, 4, 28, 6, 16, 70, 92], [41, 41, 26, 56, 83, 40, 80, 70, 33], [41, 48, 72, 33, 47, 32, 37, 16, 94, 29], [53, 71, 44, 65, 25, 43, 91, 52, 97, 51, 14], [70, 11, 33, 28, 77, 73, 17, 78, 39, 68, 17, 57], [91, 71, 52, 38, 17, 14, 91, 43, 58, 50, 27, 29, 48], [63, 66, 4, 68, 89, 53, 67, 30, 73, 16, 69, 87, 40, 31], [04, 62, 98, 27, 23, 9, 70, 98, 73, 93, 38, 53, 60, 4, 23]] euler_test(18, max_path_sum(triangle))