I am 99% sure this will not end well, because the language uses indentation as part of its syntax and this does not seem possible in a forum post. However, below is some Python code that might work out a few gear trains. Hopefully it is clear where, near the top of the program, the data is entered.
With the data below, it takes about 10 seconds on my computer to complete the a/b * c/d * e/f calculation.
—
from math import pi as pi # just in case someone needs module or DP
import sys # so program can exit gracefully if not enough gears listed
import itertools as it # permutions and combinations
“”” Fill list with gear sizes, separated by comma, order unimportant “””
gears = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61,
67, 71, 73, 79, 83, 89, 97]
required_gearing = pi/3 # enter gear ratio as fraction or decimal. pi/3 is OK
compounding_number = 2 # 1 = A/B; 2 = A/B * C/D; 3 = A/B * C/D * E/F
if len(gears) < 2 * compounding_number: # check we have enough gears
print (“Not enough gears to form requested compound chain”)
sys.exit()
layout = [“A/B”, “A/B * C/D”, “A/B * C/D * E/F”]
print (“Contents of gears”) # check gears correctly entered
print (gears, “\n”)
print (“Gear layout”, layout[compounding_number-1], “\n”)
“”” Main calculations start below “””
ratio=[] # empty list to store calculated ratio
def ab_train(): # A/B
for i in it.combinations(gears, 2): # pick two gears from list
r = i[0]/i[1] # calculate their ratio
y = [abs(r – required_gearing), (i), r] # abs item is error
ratio.append(y) # add to list
return ratio
def abcd_train(): # A/B * C/D
for i in it.combinations(gears, 4): # pick four gears from list
for j in it.combinations(i,2 ):
# pick two gears from the four already selected
k = tuple(set(i).difference(j)) # store the other two
r = (j[0]*j[1])/(k[0]*k[1]) # calculate ratio
y = [abs(r – required_gearing), (j, k), r] # abs item is error
ratio.append(y) # add to list
return ratio
def abcdef_train(): # A/B * C/D * E/F
for i in it.combinations(gears, 6): # pick six gears from list
for j in it.combinations(i, 3):
# pick three gears from the six already selected
k = tuple(set(i).difference(j)) # store the other three
r = (j[0]*j[1]*j[2])/(k[0]*k[1]*k[2]) # calculate ratio
y = [abs(r – required_gearing), (j, k), r] # abs item is error
ratio.append(y) # add to list
return ratio
“”” sometimes an A/B might give closer results than a compound train “””
“”” thus we must test all lower options even when a compound is requested “””
“”” example: gears = [2, 3, 5, 7, 9, 11] required_gearing = 7/9 “””
“”” no compound train will do better than the exact 7/9 “””
match compounding_number:
case 1: # A/B
ab_train()
case 2: # A/B * C/D
ab_train()
abcd_train()
case 3: # A/B * C/D * E/F
ab_train()
abcd_train()
abcdef_train()
best = min(ratio) # nearest combination is the one with minimum error
print (“Nearest to:”, required_gearing, best[1])
print (” Actual:”, best[2])
print (” Error:”, best[0])