def largest_adjacent_product_in_grid(grid, num_adjacent_in_product): if num_adjacent_in_product == 0 or len(grid) == 0 or len(grid[0]) == 0: return 0 if num_adjacent_in_product == 1: return max((max(row) for row in grid)) assert all(len(grid[0]) == len(row) for row in grid), 'Not all rows are the same length!' largest_product = 0 x_max, y_max = len(grid), len(grid[0]) n = num_adjacent_in_product - 1 for x in range(x_max): for y in range(y_max): if x + n < x_max: largest_product = max( largest_product, prod((grid[x][y] for x in range(x, x + n)))) if y + n < y_max: largest_product = max( largest_product, prod((grid[x][y] for y in range(y, y + n)))) if x + n < x_max and y + n < x_max: largest_product = max( largest_product, prod((grid[x + i][y + i] for i in range(num_adjacent_in_product)))) if x - n >= 0 and y + n < y_max: largest_product = max( largest_product, prod((grid[x - i][y + i] for i in range(num_adjacent_in_product)))) return largest_product
def num_proper_permutations_of_digits(digits, zero_value=0): digit_counts = Counter(digits) num_zeros = digit_counts.get(zero_value) n = len(digits) if num_zeros is None: return factorial(n) / prod(map(factorial, digit_counts.values())) else: del digit_counts[zero_value] return comb(n - 1, num_zeros) * (factorial(n - num_zeros) / prod( map(factorial, digit_counts.values())))
def eulers_totient(n): """ Euler's totient function counts the positive integers up to a given integer n that are relatively prime to n. """ return prod( (base**(exp - 1) * (base - 1) for base, exp in prime_factors(n)))
def aliquot_sum(n): """The aliquot sum s(n) of a positive integer n is the sum of all proper divisors of n (all divisors of n other than n itself). """ if 0 < n < 4: return 0 return prod((base**(exponent + 1) - 1) // (base - 1) for base, exponent in prime_factors(n)) - n
def smallest_number_with_exactly_n_divisors(n): assert n > 0 if n == 1 or n == 2: return n return min( prod(prime**(divisor - 1) for prime, divisor in zip(prime_numbers(), partition)) for partition in multiplicative_partitions(n))
def get_largest_product_of_adjacent_digits(n, n_digits): digits = list(map(int, str(n))) assert n_digits <= len(digits) largest_product = 0 for i in range(len(digits) - n_digits): largest_product = max(largest_product, prod(digits[i:i + n_digits])) return largest_product
def smallest_number_evenly_divisible_by_all(max_val): assert max_val > 0 if max_val == 1: return 1 if max_val == 2: return 2 max_power_of_prime_factors = {} for n in range(2, max_val + 1): for factor, exponent in prime_factors(n): max_power_of_prime_factors[factor] = max( max_power_of_prime_factors.get(factor, 0), exponent) return prod( (factor**exponent for factor, exponent in max_power_of_prime_factors.items()))
def factorial(n): assert n >= 0 return prod(range(1, n + 1))
def num_divisors(n): if n == 0 or n == 1 or n == 2: return n return prod(((exponent + 1) for _, exponent in prime_factors(n)))
def get_answer(self): n_digits = (1, 10, 100, 1000, 10000, 100000, 1000000) return prod(map(self.nth_digit_of_concatenated_positive_integers, n_digits))