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
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)
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))
# 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])
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)