Problem

From 2018 IMOK Cayley Q1:

How many 6 digit numbers are there where the digits are increasing, divisible by 6, and has the digits 3, 4 and 5?

Note that an increasing number is one that is not strictly decreasing. Hence, 11123 is also an increasing number.

Attempt

Let’s start with a procedural code:

def count1():
    res = []
    for i in range(100000, 1000000):
        if i % 6 != 0:
            continue
        if not increasing(i):
            continue
        if not contains345(i):
            continue
        res.append(i)
    return res

def increasing(x):
    c = 0
    for y in str(x):
        if int(y) < c:
            return False
        c = int(y)
    return True


def contains345(x):
    for i in '345':
        if i not in str(x):
            return False
    return True

Filtering

Previously we saw how to combine map into the comprehension. Now we combine filter predicates.


def count1():
    return [i for i in range(100000, 1000000) if i % 6 == 0 and increasing(i) and contains345(i)]

Using all

If we try and rephrase the predicate increasing, we can get the following:

def increasing(x):
    xstr = str(x)
    return all([xstr[i] <= xstr[i+1] for i in range(len(xstr)-1)])

def contains3452(x): 
    return all([i in str(x) for i in '345'])

Conclusion

all, exists are useful as a methods of constructing predicates.