private static void GenerateFormulaHelper(double lowMass, double highMass, double[] masses, int[] max, int index, int[] currentFormula, List<ChemicalFormula> formulas)
{
while (index > 0 && max[index] == 0)
{
index--;
}
if (index > 0)
{
int maxCount = Math.Min((int) Math.Ceiling(highMass/masses[index]), max[index]);
for (int count = 0; count <= maxCount; count++)
{
currentFormula[index] = count;
GenerateFormulaHelper(lowMass, highMass, masses, max, index - 1, currentFormula, formulas);
}
}
else
{
double massAtIndex = masses[index];
currentFormula[index] = 0;
double currentMass = currentFormula.Zip(masses, (i, m) => i*m).Sum();
int minCount = Math.Max((int) Math.Floor((lowMass - currentMass)/massAtIndex), 0);
int value = (int) Math.Ceiling((highMass - currentMass)/massAtIndex);
int maxCount = Math.Min(value, max[index]);
for (int count = minCount; count <= maxCount; count++)
{
currentMass += count*massAtIndex;
currentFormula[index] = count;
if (currentMass >= lowMass && currentMass <= highMass)
{
ChemicalFormula formula = new ChemicalFormula(currentFormula);
if (!formula.MassEquals(0.0))
formulas.Add(formula);
}
currentMass -= count*massAtIndex;
}
}
}