-1

A colourful number is one that includes no duplicates in the list of it digits + the products of the subsets of its digits. For example, the products of 263 are [2, 6, 3, 2x6, 6x3, 2x6x3]. These are all different numbers, so 263 is colourful.

I made some code to allow this for integers up to length 3. It does work. It makes a list of the digits and subsets, then converts that list into a set to remove duplicates, then compares list to set. If there are no duplicates the lengths will be the same.

However it should scale for any length of int. It is also very far from concise. How should I make it scale and make it readable?

Here is my function. It works for values up to length 3.

def is_colorful(num):

    str_num = str(num)
    combos = []

    if len(str_num) == 1:

        x = int(str_num[0])

        combos.append(x)

    if len(str_num) == 2:

        x = int(str_num[0])
        y = int(str_num[1])

        combos.append(x)
        combos.append(y)
        combos.append(x*y)

    if len(str_num) == 3:

        x = int(str_num[0])
        y = int(str_num[1])
        z = int(str_num[2])
        
        combos.append(x)
        combos.append(y)
        combos.append(z)
        combos.append(x*y)
        combos.append(y*z)
        combos.append(x*y*z)

    set_combos = set(combos)
    print(set_combos)
    
    return True if len(set_combos) == len(combos) else False
Tom Karzes
  • 22,815
  • 2
  • 22
  • 41
  • 2
    For the 263 example, don't you need to consider 2x3 as well? And doesn't that conflict with 6? So it seems 263 is *not* a colorful number. – Tom Karzes Apr 11 '23 at 21:31
  • It's done via subsets, so by splitting each digit or groups of digits. 263 splits to 2,6,3, 26, 63, it doesn't split to 23 because they aren't contiguous – Alastair909 Apr 12 '23 at 09:16
  • 1
    Then you're talking about substring, not subset. – Kelly Bundy Apr 12 '23 at 09:30
  • @Alastair909 The digits of 263 are {2, 6, 3}. One of its subsets is {2, 3}. You don't seem to understand the definition of "set" and "subset". Sets are unordered. They are not sequences. – Tom Karzes Apr 12 '23 at 12:05

1 Answers1

1

Here's a way to scale it:

def is_colorful(num):
    # disqualify as colorful if:
    #    - there are multiple digits and one of them is 0 or 1
    #    - any digit is a duplicate
    n, prods = num, set()
    while n:
        digit = n % 10
        if prods and digit in (0,1) or digit in prods:
            return False
        n, prods = n // 10, prods | {digit}
    
    # disqualify as colorful if:
    #    - the product of the digits in any subset is a duplicate
    n, prods = num, set()
    while n:
        digit, curProds = n % 10, set()
        for prd in (p * digit for p in (f for group in (prods, [1]) for f in group)):
            if prd in prods:
                return False
            curProds.add(prd)
        n, prods = n // 10, prods | curProds
    return True

top = 1
while top <= 10_000_000:
    colorful = []
    for i in range(top):
        if is_colorful(i):
            colorful.append(i)
    print(f'for 0 to {top}, ', 
        f'the count of colorful numbers is {len(colorful)}), ',
        f'percent = {100 * len(colorful) / top}%')
    top *= 10

Output:

for 0 to 1, the count of colorful numbers is 1, percent = 100.0%
for 0 to 10, the count of colorful numbers is 10, percent = 100.0%
for 0 to 100, the count of colorful numbers is 74, percent = 74.0%
for 0 to 1000, the count of colorful numbers is 454, percent = 45.4%
for 0 to 10000, the count of colorful numbers is 2194, percent = 21.94%
for 0 to 100000, the count of colorful numbers is 7690, percent = 7.69%
for 0 to 1000000, the count of colorful numbers is 17530, percent = 1.753%
for 0 to 10000000, the count of colorful numbers is 23290, percent = 0.2329%
constantstranger
  • 9,176
  • 2
  • 5
  • 19