Unlucky number 13

前端 未结 6 997
面向向阳花
面向向阳花 2021-01-18 06:37

I came across this problem Unlucky number 13! recently but could not think of efficient solution this.

Problem statement :

N is taken as input.

6条回答
  •  春和景丽
    2021-01-18 07:36

    Let f(n) be the number of sequences of length n that have no "13" in them, and g(n) be the number of sequences of length n that have "13" in them.

    Then f(n) = 10^n - g(n) (in mathematical notation), because it's the number of possible sequences (10^n) minus the ones that contain "13".

    Base cases:

    f(0) = 1
    g(0) = 0
    f(1) = 10
    g(1) = 0
    

    When looking for the sequences with "13", a sequence can have a "13" at the beginning. That will account for 10^(n-2) possible sequences with "13" in them. It could also have a "13" in the second position, again accounting for 10^(n-2) possible sequences. But if it has a "13" in the third position, and we'd assume there would also be 10^(n-2) possible sequences, we could those twice that already had a "13" in the first position. So we have to substract them. Instead, we count 10^(n-4) times f(2) (because those are exactly the combinations in the first two positions that don't have "13" in them).

    E.g. for g(5):

    g(5) = 10^(n-2) + 10^(n-2) + f(2)*10^(n-4) + f(3)*10^(n-5)
    

    We can rewrite that to look the same everywhere:

    g(5) = f(0)*10^(n-2) + f(1)*10^(n-3) + f(2)*10^(n-4) + f(3)*10^(n-5)
    

    Or simply the sum of f(i)*10^(n-(i+2)) with i ranging from 0 to n-2.

    In Python:

    from functools import lru_cache
    
    @lru_cache(maxsize=1024)
    def f(n):
        return 10**n - g(n)
    
    @lru_cache(maxsize=1024)
    def g(n):
        return sum(f(i)*10**(n-(i+2)) for i in range(n-1))  # range is exclusive
    

    The lru_cache is optional, but often a good idea when working with recursion.


    >>> [f(n) for n in range(10)]
    [1, 10, 99, 980, 9701, 96030, 950599, 9409960, 93149001, 922080050]
    

    The results are instant and it works for very large numbers.

提交回复
热议问题