예제 #1
0
def MNS(n,d):
    Nnd, Snd = 0, 0
    for Mnd in range(n-1,0,-1):
        mask = ([0] * (n-Mnd)) + ([1] * Mnd) # 1=replaced digit, 0=other digits
        # mask is in big endian
        hasnextpermutation = True
        while hasnextpermutation: # try all mask permutations
            if d == 0 and mask[0] == 1: # cant have 0 at start of number
                hasnextpermutation = lib.lexico_next(mask)
                continue
            # use base 9 to select digits for replacement digits
            # if the b9 digit is b, b<d --> use itself, b>=d --> use b+1
            for b9 in range(0,9**(n-Mnd)): # form numbers with the digits
                if d != 0 and mask[0] == 0 and b9 % 9 == 0:
                    continue # cant put 0 at start of number
                num = 0
                for m in mask:
                    if m == 1: num = (num*10) + d # replaced digit
                    else: # other digits
                        b = b9 % 9
                        if b >= d: b += 1
                        num = (num*10) + b
                        b9 //= 9
                if lib.miller_rabin_verified(num):
                    Nnd += 1 # count
                    Snd += num # sum
            hasnextpermutation = lib.lexico_next(mask)
        if Nnd != 0: # found primes with Mnd instances of d
            print(': M(',n,',',d,') = ',Mnd,sep='')
            print(': N(',n,',',d,') = ',Nnd,sep='')
            print(': S(',n,',',d,') = ',Snd,sep='')
            return (Mnd, Nnd, Snd)
    assert 0 # should not reach here
예제 #2
0
def recurse(exps, expi, prod,
            nextpi):  # count factorizations with required number of divisors
    global count, primes, maximum
    #    print(' '*(4*expi),prod)
    if expi == len(exps):  # finished
        count += 1


#        print(' '*(4*expi),prod,'counted')
    else:  # try selecting next prime, pi = prime index
        primesafter = sum(exps[expi + 1:])  # prime factors still needed
        for pi in range(nextpi, len(primes)):  # select larger prime
            val = prod * (primes[pi]**exps[expi])
            # amount still need to multiply is too small
            if maximum // val < primes[pi]**primesafter:
                break  # dont exceed limit
            #            print(' '*(4*expi),'*',primes[pi],'**',exps[expi])
            recurse(exps, expi + 1, val, pi + 1)

for primeexp in dfactorizations:
    primeexp = list(n - 1 for n in primeexp)  # exponents of the prime factors
    hasnextpermutation = True
    # try all permutations of prime exponents, select primes in increasing order
    while hasnextpermutation:
        print(': prime exponent order', primeexp)
        # select primes recursively
        recurse(primeexp, 0, 1, 0)
        hasnextpermutation = lib.lexico_next(primeexp)
print(count)
예제 #3
0
            for op2 in range(4):
                for op3 in range(4):
                    a, b, c, d = dset[0], dset[1], dset[2], dset[3]
                    # use parenthesis ignoring symmetry since that is considered
                    # by all possible operator orders and digit permutations
                    nums.add(
                        eval(make_expr('(', a, op1, b, ')', op2, c, op3, d)))
                    nums.add(
                        eval(make_expr(a, op1, '(', b, op2, c, ')', op3, d)))
                    nums.add(
                        eval(make_expr('(', a, op1, b, op2, c, ')', op3, d)))
                    nums.add(
                        eval(
                            make_expr('(', a, op1, b, ')', op2, '(', c, op3, d,
                                      ')')))
                    nums.add(eval(make_expr(a, op1, b, op2, c, op3, d)))
        if not lib.lexico_next(dset): break
    nums2 = set()  # use integer values for everything
    for n in nums:
        if float_near(n, round(n)): nums2.add(round(n))
    nums = nums2
    maxn = 1
    while maxn in nums:
        maxn += 1
    print(':', sorted(dset), maxn - 1)
    if maxn - 1 > max1to_n:
        bestdigits = sorted(dset)
        max1to_n = maxn - 1
print(': max 1 to n in set:', max1to_n)
print(''.join(str(d) for d in bestdigits))
예제 #4
0
# inner nums are index [0,sides)
# outer num i connects inward to index i-sides and i-sides-1 (or sides-1 if -1)
nums = list(range(1, 2 * sides + 1))
next_lexico = True
solutions = []
while next_lexico:
    linesum = nums[sides] + nums[0] + nums[sides - 1]  # first line
    samesum = True
    for start in range(sides + 1,
                       2 * sides):  # make sure each line has same sum
        if nums[start] + nums[start - sides] + nums[start - sides -
                                                    1] != linesum:
            samesum = False
            break
    if not samesum:  # try next case
        next_lexico = lib.lexico_next(nums)
        continue
    string = ''
    start = 0  # start index for outer numbers
    minouter = sides * 2 + 1  # greater than any
    for i in range(sides, 2 * sides):
        if nums[i] < minouter:
            minouter = nums[i]
            start = i
    # create string going clockwise
    # increasing index goes counterclockwise since going clockwise inward uses
    # decreasing indexes, so go in decreasing order for starting outer nodes
    for i in chain(range(start, sides - 1, -1), range(2 * sides - 1, start,
                                                      -1)):
        #    for i in chain(range(start, 2*sides), range(sides, start)):
        string += str(nums[i]) + str(nums[i - sides])
예제 #5
0
import libtkoz as lib

# for each arrangement of the 9 digits, try recursively placing dividers to
# split into subsets, once a successful split occurs, keep track of a set of
# unique number sets made since they can be repeated
# ~35sec (cpython / i5-2540m) and ~5sec (pypy / i5-2540m)

count = 0


def recurse(digits, nums, prevdiv):  # digits numbers made, last divider
    global uniquesets, count
    if prevdiv == len(digits): count += 1  # found a set with increasing primes
    else:  # make prime number with next digits and place divider
        num = 0
        for d in range(prevdiv, len(digits)):  # try each digit
            num = num * 10 + digits[d]
            # only make sets with primes in increasing order for uniqueness
            if lib.prime(num) and (len(nums) == 0 or num > nums[-1]):
                recurse(digits, nums + [num], d + 1)


digits = list(range(1, 10))
hasnextpermutation = True
# enumerate all permutations of digits and try splitting them recursively
while hasnextpermutation:
    recurse(digits, [0], 0)
    hasnextpermutation = lib.lexico_next(digits)
print(count)