public static bool StateSeenBefore(EquivalentState newState) { // make arequivalent(state1,state2) which for each material finds the int pairs of floors where its chip and gen are. // Then order these pairs by floor1,floor2 // equivalence means the pairs are identical (including dups) - the actual material is not important but its pattern still is: //So these are equivalent: // //hydrogen - chip hydrogen - generator //lithium - chip //lithium - generator // //and // //lithium - chip lithium - generator //hydrogen - chip //hydrogen - generator // //however if middle row in lower example above was cobalt-chip instead of hydrogen-chip it wouldn't be equivalent // because the lower 2 floors chip and gen are different materials now, whereas they were the same before if (Previous == null) { Previous = new List <EquivalentState>(); return(false); } return(Previous.Any(s => s.Equals(newState))); }
public void SaveState() { if (Current != null) { var currentEquivalent = new EquivalentState(Current, Materials); if (!StateSeenBefore(currentEquivalent)) { Previous.Add(currentEquivalent); } } }
public Facility MoveToTop(Facility rootFacility) { var toProcess = new Queue <Facility>(); toProcess.Enqueue(rootFacility); Facility result = null; int maxMoves = 0; int batchMaxMoves = 0; int batchCount = 0; while (toProcess.Any()) { var facility = toProcess.Dequeue(); if (facility.MovesMade > maxMoves) { maxMoves = facility.MovesMade; } if (facility.MovesMade > batchMaxMoves) { batchMaxMoves = facility.MovesMade; } if (facility.MovesMade > 2980) { Console.WriteLine("Burned"); continue; } if (batchCount++ % 1000 == 0) { Console.WriteLine(string.Format("Combos={0}, batchMax={1}, max={2}, queueLength={3}", batchCount, batchMaxMoves, maxMoves, toProcess.Count())); } if (facility.Floors.Where(f => f.FloorNum != 4).All(f => !f.Items.Any())) { Console.WriteLine(string.Format(">>>=>{0}", facility.MovesMade)); if (result == null || (facility.MovesMade < result.MovesMade)) { result = facility; // return result; } return(facility); } var moves = facility.GetValidMoves(); if (!moves.Any()) { continue; } //foreach (var move in moves) //Facility parallelResult = null; //object myLock = new object(); //Parallel.ForEach(moves, move => foreach (var move in moves) { var withMove = facility.Clone().DoMove(move); //Console.WriteLine(string.Format("{0} : {1}{2}", // string.Join("|", withMove.Floors.Select(f => string.Format("{0},{1}", f.Items.Count(i => i.ItemType == ItemType.generator), f.Items.Count(i => i.ItemType == ItemType.microchip)))), // string.Join("", Enumerable.Repeat(" ", facility.MovesMade)), // move)); var equiv = new EquivalentState(withMove.Current, Facility.Materials); if (!Facility.StateSeenBefore(equiv)) { toProcess.Enqueue(withMove); Facility.Previous.Add(equiv); } //lock (myLock) // { // if (result != null) // { // Console.WriteLine(string.Format(">>>=>{0}", result.MovesMade)); // parallelResult = result; // return parallelResult; // break; // } // } } //); } return(result); }