def is_pandigital(x: int, digits: int) -> bool: if num_size(x) != digits: return False digits_set = set(range(1, digits + 1)) if digits == 10: digits_set.remove(10) digits_set.add(0) return set(num_to_list(x)) == digits_set
def digits_sum_first_n(max_n: int, inclusive=True): """ sum of the digits of first n numbers: [1,2,3,...,max_n] """ digs = num_to_list(max_n)[::-1] s = 0 for i, d in enumerate(digs): s += d * 10 ** i * sum(digs[i + 1:]) + sum_digits_to_power_10_multiple(d * 10 ** i) return s - int(not inclusive) * digits_sum(max_n)
def need_check(num: int, digits: List[int]) -> bool: """ check if this is the min number of this family. we want the min value for each digit: the left digit must be 1, all others must be 0 :param num: num to check :param digits: digits of family :return: True if valid """ ntl: List[int] = num_to_list(num) for i in digits: if i == 0: if ntl[0] != 1: return False else: if ntl[i] != 0: return False return True
def ans(): # get all primes four_digits_primes: List[int] = list(primerange(10 ** 3, 10 ** 4)) # split primes by digits primes_by_digs: Dict[Tuple[int, ...], Set[int]] = defaultdict(set) for prime in four_digits_primes: primes_by_digs[tuple(sorted(num_to_list(prime)))].add(prime) results: List[str] = [] # for all 4-digits perms that have 3 or more primes for four_digs, primes in primes_by_digs.items(): if len(primes) < 3: continue for triple in combinations(primes, 3): ts: Tuple[int, ...] = tuple(sorted(triple)) # if arithmetic sequence, add to results if ts[2] - ts[1] == ts[1] - ts[0]: results.append(str(ts[0]) + str(ts[1]) + str(ts[2])) return results[1]
def is_bouncy(x: int) -> bool: """ :param x: input number :return: True if the number is bouncy """ digs: List[int] = num_to_list(x) form = 0 for i in range(len(digs) - 1): if form == 0: if digs[i] > digs[i + 1]: form = -1 elif digs[i] < digs[i + 1]: form = 1 else: if digs[i] > digs[i + 1] and form == 1: return True if digs[i] < digs[i + 1] and form == -1: return True return False
def create_nums(num=0) -> None: """ create all numbers with this property :param num: current number :return: None """ if num_size(num) == 10: # stop all_numbers.add(num) if num == 0: # add digs for i in range(1, 10): create_nums(i) else: for i in digits.difference(num_to_list(num)): # add possible digits if num_size(num * 10 + i) <= 3 or ( (num * 10 + i) % 1000) % primes_list[num_size(num * 10) - 4] == 0: create_nums(num * 10 + i)
def max_value_from_pair(p: (str, str)) -> int: """ :param p: a pair of words :return: all values gotten from the pair """ result = -1 w1: str = p[0] w2: str = p[1] number_of_chars = len(w1) for i in range( int(sqrt(10**(number_of_chars - 1))) + 1, int(sqrt(10**number_of_chars)) + 1): # map digits to letters: digits = num_to_list(i**2) # calculate for both sides w1w2 = handle_one_side(w1, w2, digits) w2w1 = handle_one_side(w2, w1, digits) # if we found a result if w2w1 != -1 or w1w2 != -1: result = max([result, i, w1w2, w2w1]) return result
def replace_digits(num: int, digits_places: List[int], new_digit: int) -> int: s = num_to_list(num) for i in digits_places: s[i] = new_digit return list_to_num(s)
def digs_count(x: int) -> Dict[int, int]: return Counter(num_to_list(x))
def contains_all_of_digits(x: int, digits: Collection) -> bool: return set(digits) <= set(num_to_list(x))
def contains_any_of_digits(x: int, digits: Collection) -> bool: return len(set(num_to_list(x)).intersection(digits)) != 0
def all_same_digits(x: int): return len(set(num_to_list(x))) == 1