Advertisement
Kaelygon

Terrible python code all numbers divisibility test

Nov 22nd, 2024 (edited)
299
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.94 KB | None | 0 0
  1. import math
  2. import sys
  3. import gmpy2
  4. from sympy import factorint
  5. from functools import reduce
  6.  
  7. # This terrible python code is provided by Kaelygon
  8. #
  9. # Find divisibility rule by prime P: P * N = a * 10^b + c
  10. # such that an integer can be split in two parts A and B
  11. # and reduced to a smaller number by simulating 10^b division and modulus
  12. # using string manipulation and addition: B*a-A*c
  13. # Matt Parker explanation https://youtu.be/6pLz8wEQYkA
  14.  
  15. #Find divisibility rules P * N = a * 10^b + c
  16. def findDivRules(P, aRange, bRange, cRange):
  17.     rules = []
  18.    
  19.     bMin=int(math.log10(abs(P))+1)+(bRange[0]-1)
  20.     for b in range(bMin, bRange[1]):
  21.         bPowTen=10**b # 10^b
  22.         for a in range(aRange[0], aRange[1]):
  23.             ab = a*bPowTen # a*b^10
  24.             if ab<P: continue
  25.             for c in range(cRange[0], cRange[1]):
  26.                 PN = ab + c # P * N = a * 10^b + c
  27.                 if PN<=P or PN%P!=0 or c==0: continue # skip trivial solutions
  28.                 N = PN//P
  29.                 rules.append((P, N, a, b, c))
  30.    
  31.     if not rules: return (P, 0, 0, 0, 0)
  32.    
  33.     # Sort by smallest b and c
  34.     bestRule = min(rules, key=lambda x: (x[3], abs(x[4])))
  35.     return bestRule
  36.  
  37. def printParkerStyle(isPrime,rule):
  38.     if isPrime:
  39.         P, N, a, b, c = rule
  40.         aSign=""
  41.         cSign=""
  42.         if c<0 and a >0:
  43.             cSing="add to"
  44.             aSing="add"
  45.         else:
  46.             if c>0: cSing="add to"
  47.             else: cSing="subtract from"
  48.             if a<0: aSing="add"
  49.             else: aSing="subtract"
  50.         print(f"{P} is a prime and has the tests:")
  51.         print(f"Take the {(10**b):,}s, ",end="")
  52.         if(abs(c)>1): print(f"multiply by {c},")
  53.         print(f"and {cSing} the rest. ",end="")
  54.         print(f"Multiply the units by {a} and ",end="")
  55.         print(f"{aSing}.",end="")
  56.     else:
  57.         if len(rule)<2: return
  58.         P=rule[0]
  59.         print(f"{P}: test for ",end="")
  60.         print(f"{rule[1]} ",end="")
  61.         for factor in rule[2:]:
  62.             print(f"and {factor} ",end="")
  63.     print("")
  64.  
  65. #Output formatting
  66. def printRuleTable(isPrime,rule):
  67.     if isPrime:
  68.         P, N, a, b, c = rule
  69.         row = f"P:{P:<6} N:{N:<6} a:{a:<6} b:{b:<6} c:{c:<6} P*N:{P * N:<6}"
  70.         print(row,end="")
  71.     else:
  72.         if len(rule)<1: return
  73.         print(f"P:{rule[0]} Factors {rule[1:]}",end="")
  74.         parkerPrinter()
  75.        
  76. #79662*94-1*16
  77.  
  78. def extendRuleSearch(P,aMax,bMax,cMax):
  79.     inc=0
  80.     while(True):
  81.         inc+=1
  82.         aStart=inc*aMax
  83.         bStart=inc+bMax #Extending exponent is not that useful
  84.         cStart=inc*cMax
  85.         rule=[]
  86.        
  87.         aRange = [1+aStart,2*aStart]
  88.         bRange = [1,bStart]
  89.         cRange = [-2*cStart,-cStart]
  90.         rule.extend(findDivRules(P, aRange, bRange, cRange)) #extend negative c search
  91.         if rule[2]:
  92.             return rule, 2*inc-1
  93.             break
  94.        
  95.         rule=[]
  96.         cRange = [cStart,2*cStart]
  97.         rule.extend(findDivRules(P, aRange, bRange, cRange)) #extend positive c search
  98.         if rule[2]:
  99.             return rule, 2*inc
  100.             break
  101.  
  102. def main():
  103.     printComposites=True
  104.     parkerPrinting=True
  105.    
  106.     if not parkerPrinting:
  107.         print("Test number 'num' divisibility by P")
  108.         print("using iterative formula B*a-A*c")
  109.         print("where A=num/&10^b B=num%10^b.")
  110.         print("a, b and c are constants listed below.\n")
  111.  
  112.     aMax=10
  113.     printFunc = [printRuleTable,printParkerStyle]
  114.    
  115.     for P in range(1,30000+1,1):
  116.         if(P==0):continue
  117.         digitCount=int(math.log10(abs(P))+1)
  118.        
  119.         bMax=digitCount*2+1
  120.         cMax=abs(P//20)
  121.         #minimums
  122.         if bMax<5 : bMax=5
  123.         if cMax<16 : cMax=16
  124.        
  125.         if not gmpy2.is_prime(P):
  126.             if not printComposites: continue
  127.            
  128.             composite=[P]
  129.             factors = factorint(P)
  130.             for prime, exponent in factors.items():
  131.                 composite.append(int(prime ** exponent))
  132.                 printFunc[parkerPrinting](False,composite)
  133.             print("")
  134.             continue
  135.  
  136.         aRange = [1,aMax] # Second split 'B' multiplier
  137.         bRange = [1,bMax] # 'b' sets the tested number split right to left
  138.         cRange = [-cMax,cMax] # First split 'A' multiplier
  139.  
  140.         rule=[]
  141.         rule.extend(findDivRules(P, aRange, bRange, cRange))
  142.        
  143.         if rule[2]: #if results found
  144.             printFunc[parkerPrinting](True,rule)
  145.             print("")
  146.         else: #extend range if not
  147.             rule,inc=extendRuleSearch(P,aMax,bMax,cMax)
  148.             printFunc[parkerPrinting](True,rule)
  149.             if not parkerPrinting:
  150.                 print(f" Extended search ",end="")
  151.                 if inc==1:
  152.                     print("once.")
  153.                 else:
  154.                     print(f"{inc} times.")
  155.            
  156.     print("")
  157.  
  158.  
  159.    
  160.  
  161. if __name__=="__main__":
  162.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement