コード例 #1
0
def Problem62(n: int):
    ''' For a positive integer n, returns the smallest
    cube that has n digit permutations which are also cubes'''

    # Initialise some numbers
    start_time = time.time()
    digits = 1
    cubes = {}
    permutations = []

    if (n == 1):
        return 1

    i = 1
    while True:
        new_cube = i * i * i

        # If we hit a number with more digits than the previous, we can reset the problem
        if (len(str(new_cube)) > digits):
            cubes = {}
            permutations = []
            digits += len(str(new_cube))

        found_permutation = False
        # First of all, let's try to find a permutation in the existing permutation groups
        for permutation in permutations:
            if (euler.is_permutation(new_cube, permutation[0])):
                found_permutation = True
                permutation.append(new_cube)
                # If this permutation has now reached n items, we return the smallest (always the first) number
                if (len(permutation) == n):
                    return permutation[0], '%.3f s' % (time.time() -
                                                       start_time)

        # If we didn't find any permutations so far, we search for one amongst the so far unused cubes
        if (not found_permutation):
            # cubes is a dict where values are grouped by a key which is the digit sum
            # this is useful because all candidate permutations will necessary have equal digit sum
            key = euler.sum_digits(new_cube)
            if (key in cubes):
                for cube in cubes[key]:
                    # If we find a permutation, we insert the new pair in the permutations list
                    # We also remove the cube from the singles collection, for we don't need to check it again
                    if (euler.is_permutation(new_cube, cube)):
                        found_permutation = True
                        permutations.append([cube, new_cube])
                        cubes[key].remove(cube)
                        # In the special case where n is 2, the first found permutation gives us the result
                        if (n == 2):
                            return cube, '%.3f s' % (time.time() - start_time)

                #If no permutations were found, we add this to the singles list
                if (not found_permutation):
                    cubes[key].append(new_cube)

            else:
                cubes[key] = []
                cubes[key].append(new_cube)

        i = i + 1
コード例 #2
0
ファイル: p07x.py プロジェクト: jpaeng/PE
def minimum_totient_ratio_permuation(max_n):
    """Return number n < max_n with minimum n/totient(n) ratio where n and totient(n) are permutations of each other.
    Euler's product formula:
        n = (p1**k1) * (p2**k2) * ...
        totient(n)  = n * (1 - 1/p1) * (1 - 1/p2) * ...
                = n * (p1 - 1)/p1 * (p2 -1)/p2 * ...
        n/totient(n) = (p1*p2*...)/((p1-1)*(p2-1)*...) -> increases as more prime are added.
        where p1, p2, ... are primes.

    :param max_n:   maximum n to check
    :return:        n with the minimum n/totient(n) ratio in the form:  (n, totient(n), n/totient(n))
    """

    prime_list = common.prime_list_mr(2, (max_n+1)//2)
    
    # Find index of prime closest to sqrt(max_n)
    sqrt_max_n = math.sqrt(max_n)
    a = int(sqrt_max_n)
    while True:
        if a in prime_list:
            break
        else:
            a -= 1
    index_mid = prime_list.index(a)
    min_ratio = (0, 0, 0, 0, 10.0)

    # a loops down from sqrt(max_n), b loops up from sqrt(max_n)
    for index_a in reversed(range(index_mid//2, index_mid)):
        for index_b in range(index_mid, len(prime_list)):
            a = prime_list[index_a]
            b = prime_list[index_b]
            prod = a * b
            if prod > max_n:
                break
            else:
                ratio = a*b/((a-1)*(b-1))
                f = int(0.5 + prod/ratio)
                if common.is_permutation(str(prod), str(f)):
                    # print(a, b, prod, f, ratio)
                    if ratio < min_ratio[-1]:
                        min_ratio = (a, b, prod, f, ratio)
                    break

    return min_ratio
コード例 #3
0
def Problem49():
    ''' Supposedly solves Problem 49!'''

    # Initialise some numbers
    start_time = time.time()
    res = 0
    n = euler.next_prime(1000)
    primes = {}
    permutations = []

    while (n < 10000):
        s = euler.sum_digits(n)
        if s in primes:
            primes[s].append(n)
        else:
            primes[s] = [n]

        n = euler.next_prime(n)

    for k in primes:
        while (len(primes[k]) > 0):
            candidate_permutation = [
                p for p in primes[k] if euler.is_permutation(primes[k][0], p)
            ]
            if (len(candidate_permutation) > 2):
                permutations.append(candidate_permutation)

            primes[k] = [
                p for p in primes[k] if p not in candidate_permutation
            ]

    for permutation in permutations:
        for i in range(len(permutation) - 2):
            for j in range(i + 1, len(permutation) - 1):
                if (2 * permutation[j] - permutation[i]) in permutation:
                    print('%d%d%d' % (permutation[i], permutation[j],
                                      (2 * permutation[j] - permutation[i])))

    return res, '%.3f s' % (time.time() - start_time)
コード例 #4
0
ファイル: p06x.py プロジェクト: jpaeng/PE
def cube_permutations(perm_count):
    """Return the smallest set of perm_count cubes that are permutations of each other.

    :param perm_count:  the number of cube permutations to look for
    :return:            list of cube permutations of the first cube that has at least perm_count permutations
    """

    found = False
    perm_list = []
    max_digit_count = 14
    stop_base = 3
    for digit_count in range(2, max_digit_count+1):
        # first create list of cubes of the same length
        start_base = stop_base
        stop_base = int(math.pow(10**digit_count, 0.3333333333)) + 1
        cube_list = [base**3 for base in range(start_base, stop_base)]
        for cube in cube_list:
            count = 0
            perm_list = []
            # count the number of permutations of cube
            for cube2 in cube_list:
                if common.is_permutation(str(cube), str(cube2)):
                    perm_list.append(cube2)
                    count += 1
                    if count >= perm_count:
                        found = True
                        break
            if found:
                break
        if found:
            break

    if len(perm_list) >= perm_count:
        return perm_list
    else:
        return []