/// <summary> /// Sorts a series of small rings ready for determining double bond placement /// see DOI: 10.1002/minf.201200171 /// Rendering molecular sketches for publication quality output /// Alex M Clark /// </summary> /// <returns>List of rings</returns> // ReSharper disable once InconsistentNaming public List <Ring> SortRingsForDBPlacement() { // Debug.Assert(HasRings); //no bloody point in running this unless it has rings Debug.Assert(RingsCalculated); //make sure that if the molecule contains rings that we have calculated them //1) All rings of sizes 6, 5, 7, 4 and 3 are discovered, in that order, and added to a list R. var R = Rings.Where(x => x.Priority > 0).OrderBy(x => x.Priority).ToList(); //Define B as an array of size equal to the number of atoms, where each value is equal to the number of times the atom occurs in any of the rings R Dictionary <Atom, int> B = new Dictionary <Atom, int>(); foreach (Atom atom in Atoms) { B[atom] = atom.Rings.Count; } //Define Q as an array of size equal to length of R, where each value is equal to sum of B[r], where r iterates over each of the atoms within the ring. Dictionary <Ring, int> Q = new Dictionary <Ring, int>(); foreach (Ring ring in R) { int sumBr = 0; foreach (Atom atom in ring.Atoms) { sumBr += B[atom]; } Q[ring] = sumBr; } //Perform a stable sort of the list of rings, R, so that those with the lowest values of Q are listed first. var R2 = R.OrderBy(r => Q[r]); //Define D as an array of size equal to length of R, where each value is equal to the number of double bonds within the corresponding ring Dictionary <Ring, int> D = new Dictionary <Ring, int>(); foreach (Ring ring in R2) { D[ring] = ring.Bonds.Count(b => b.OrderValue == 2); } //Perform a stable sort of the list of rings, R, so that those with highest values of D are listed first var R3 = R2.OrderByDescending(r => D[r]); return(R3.ToList()); }
/// <summary> /// indicates which side of bond to draw subsidiary double bond /// </summary> /// if bond order is not 2, returns null /// if bond is in single ring, vector points to centre of ring /// if bond is in cisoid bond (excluding hydrogens) points to area /// including both bonds /// if bond is in 3 rings vector is null /// /// this is not foolproof as we may need to make a benzene ring consistent /// <returns></returns> public Vector?GetPrettyCyclicDoubleBondVector() { Debug.Assert(Parent.RingsCalculated); Vector?vector = null; Ring theRing = PrimaryRing; List <Ring> ringList = Rings.Where(x => x.Priority > 0).OrderBy(x => x.Priority).ToList(); if (ringList.Any()) //no rings { Point?ringCentroid = theRing.Centroid; vector = ringCentroid - MidPoint; } return(vector); }
protected (int, int) CostOfFighting(string[] input) { var boss = ReadStats(input); var minCostForWinning = int.MaxValue; var maxCostForLosing = 0; foreach (var weapon in Weapons) { foreach (var armor in Armors) { foreach (var ring1 in Rings) { foreach (var ring2 in Rings.Where(r => r != ring1)) { var cost = weapon.Cost + armor.Cost + ring1.Cost + ring2.Cost; var you = new Stats { Hitpoints = 100, Damage = weapon.Damage + armor.Damage + ring1.Damage + ring2.Damage, Armor = weapon.Armor + armor.Armor + ring1.Armor + ring2.Armor }; if (YouWinFight(boss, you)) { if (cost < minCostForWinning) { minCostForWinning = cost; } } else { if (cost > maxCostForLosing) { maxCostForLosing = cost; } } } } } } return(minCostForWinning, maxCostForLosing); }