public static IEnumerable<string> EquationsFromParentheses(string recipe) { var equations = new List<string>(); if (string.IsNullOrWhiteSpace(recipe)) { return equations; } recipe = "(" + recipe + ")"; // If this is a duplication of effort, we'll silently ignore it later. recipe = new Regex(@"\s+").Replace(recipe, string.Empty); // Remove all whitespace. recipe = LeveledPreparser(recipe); var multiLetterMatch = invalidLetterFinder.Match(recipe); if (multiLetterMatch.Success) { throw new ArgumentException("The gem \"" + multiLetterMatch.Value + "\" must be a single letter. Gem combinations must be expressed as individual components separated with plus signs and brackets, as needed. For example:\nob → o+b\nob+o → (o+b)+o"); } var id = 0; foreach (var c in Gem.GemInitializer) { if (recipe.IndexOf(c) > -1) { recipe = recipe.Replace(c, id.ToString(CultureInfo.InvariantCulture)[0]); equations.Add(string.Format(CultureInfo.InvariantCulture, "{0}={1}", id, c)); id++; } } if (equations.Count == 0) { throw new ArgumentException("Recipe did not contain any recognizable gems."); } // Scan for plus signs within the formula and add gems together appropriately. int plus = recipe.IndexOf('+'); string newNum = (id - 1).ToString(CultureInfo.InvariantCulture); while (plus > -1) { string thisCombine; var close = recipe.IndexOf(')', plus); if (close >= 0) { var open = recipe.LastIndexOf('(', close); if (open < 0) { throw new ArgumentException("Bracket mismatch in formula."); } thisCombine = recipe.Substring(open + 1, close - open - 1); string[] combineGems = thisCombine.Split('+'); if (combineGems.Length != 2) { throw new ArgumentException("The formula provided contains more than a single plus sign within a pair of brackets or a term that is over-bracketed (e.g., \"((o+o))\"). These are not currently supported."); } if (combineGems[0].Length == 0 || combineGems[1].Length == 0) { throw new ArgumentException("Invalid formula part: (" + thisCombine + ")"); } newNum = id.ToString(CultureInfo.InvariantCulture); recipe = recipe.Replace("(" + thisCombine + ")", newNum); equations.Add(string.Format(CultureInfo.InvariantCulture, "{0}={1}+{2}", id, combineGems[0], combineGems[1])); } else { throw new ArgumentException("Bracket mismatch in formula."); } plus = recipe.IndexOf('+'); id++; } while (recipe.StartsWith("(", StringComparison.Ordinal) && recipe.EndsWith(")", StringComparison.Ordinal)) { recipe = recipe.Substring(1, recipe.Length - 2); } if (recipe != newNum) { if (recipe.Contains("(")) { throw new ArgumentException("Bracket mismatch in formula."); } throw new ArgumentException("Invalid recipe."); } return equations; }