public void DownCountSolver_Test2() { DownCountGame game = new DownCountGame(250, 50, 4, 1); Solutions solutions = DownCountSolver.Solve(game); Assert.IsTrue(solutions.Count > 0); solutions.ForEach(solution => Assert.AreEqual(250, solution.Value)); solutions = DownCountSolver.Solve(game, false); Assert.IsTrue(solutions.Count == 1); solutions.ForEach(solution => Assert.AreEqual(250, solution.Value)); }
/// <summary> /// Solve the game by solving the subset that considedrs the ith element in isolation /// </summary> /// <param name="game"></param> /// <param name="i"></param> /// <returns></returns> private static Solutions SolveSubset(DownCountGame game, int i, bool allSolutions = true) { Solutions solutions = new Solutions(); int currentNumber = game.Numbers[i]; IntegerSet subset = game.Numbers.SubsetNotIncluding(i); DownCountGame gameAdd = new DownCountGame(); gameAdd.TargetNumber = game.TargetNumber - currentNumber; gameAdd.Numbers = subset; solutions.AddRange(Solve(gameAdd, allSolutions) + new Integer(currentNumber)); if (!allSolutions && solutions.Count > 0) return solutions; DownCountGame gameMinus = new DownCountGame(); gameMinus.TargetNumber = game.TargetNumber + currentNumber; gameMinus.Numbers = subset; solutions.AddRange(Solve(gameMinus, allSolutions) - new Integer(currentNumber)); if (!allSolutions && solutions.Count > 0) return solutions; DownCountGame gameMultiply = null; if (game.TargetNumber % currentNumber == 0) { gameMultiply = new DownCountGame(); gameMultiply.TargetNumber = game.TargetNumber / currentNumber; gameMultiply.Numbers = subset; solutions.AddRange(Solve(gameMultiply, allSolutions) * new Integer(currentNumber)); if (!allSolutions && solutions.Count > 0) return solutions; } DownCountGame gameDivide = new DownCountGame(); gameDivide.TargetNumber = game.TargetNumber * currentNumber; gameDivide.Numbers = subset; solutions.AddRange(Solve(gameDivide, allSolutions) / new Integer(currentNumber)); if (!allSolutions && solutions.Count > 0) return solutions; return solutions; }
/// <summary> /// Solve the given downcount game /// </summary> /// <param name="game"></param> /// <param name="allSolutions"></param> /// <returns></returns> public static Solutions Solve(DownCountGame game, bool allSolutions = true) { Solutions solutions = new Solutions(); if (game.Numbers.Contains(game.TargetNumber)) solutions.Add(new Integer(game.TargetNumber)); if (!allSolutions && solutions.Count > 0) return solutions; if (game.Numbers.Count == 1) return solutions; for (int i = 0; i < game.Numbers.Count; ++i) { solutions.AddRange(SolveSubset(game, i, allSolutions)); if (!allSolutions && solutions.Count > 0) return solutions; } return solutions; }
/// <summary> /// Calculate the solution to the game /// </summary> private static Solutions CalculateSolution(DownCountGame game) { Solutions solutions = DownCountSolver.Solve(game, false); if (solutions.Count == 0) { //Look for a 'close' soltion DownCountGame closeGame = new DownCountGame(game.TargetNumber, game.Numbers.ToArray()); ; for (int i = 1; i <= 10; ++i) { closeGame.TargetNumber = game.TargetNumber - i; solutions = DownCountSolver.Solve(closeGame, false); if (solutions.Count > 0) return solutions; closeGame.TargetNumber = game.TargetNumber + i; solutions = DownCountSolver.Solve(closeGame, false); if (solutions.Count > 0) return solutions; } } return solutions; }
public void DownCountSolver_NoSolution() { DownCountGame game = new DownCountGame(577, 9, 3, 4, 2, 1); Solutions solutions = DownCountSolver.Solve(game); Assert.IsTrue(solutions.Count == 0); }
public void DownCountSolver_Test4() { DownCountGame game = new DownCountGame(952, 25, 50, 75, 100, 3, 6); Solutions solutions = DownCountSolver.Solve(game); Assert.IsTrue(solutions.Count > 0); solutions.ForEach(solution => Assert.AreEqual(952, solution.Value)); solutions = DownCountSolver.Solve(game, false); Assert.IsTrue(solutions.Count == 1); solutions.ForEach(solution => Assert.AreEqual(952, solution.Value)); }
private static void PlayGame() { Console.WriteLine("How many big numbers would you like, please enter a number between 1 and 6"); ConsoleKeyInfo input = Console.ReadKey(); int numBigNumbers; string keyValue = input.KeyChar.ToString(); while (!int.TryParse(keyValue, out numBigNumbers) || numBigNumbers < 1 || numBigNumbers > 6) { Console.WriteLine(); Console.WriteLine("Invalid number entered"); Console.WriteLine("Please enter a number between 1 and 6"); input = Console.ReadKey(); keyValue = input.KeyChar.ToString(); } // Calculate the numbers used in this game List<int> numbers = new List<int>(); for (int i = 0; i < numBigNumbers; ++i) { numbers.Add(RandomNumberHelper.RandomIntegerFromSet(25, 50, 75, 100)); } for (int i = 0; i < 6 - numBigNumbers; ++i) { numbers.Add(RandomNumberHelper.RandomInteger(1, 10)); } IntegerSet sourceNumbers = new IntegerSet(numbers); int targetNumber = RandomNumberHelper.RandomInteger(101, 999); Console.WriteLine(); Console.WriteLine("The game is to find {0} from the set of numbers {1}, you have 30 seconds starting from now", targetNumber, sourceNumbers.ToString()); Console.WriteLine(); // Show Timer Task timer = Task.Factory.StartNew(() => TimerCountDown(30)); // Calculate Answer DownCountGame game = new DownCountGame(targetNumber, sourceNumbers); Task<Solutions> calculationTask = CalculateSoultionASync(game); timer.Wait(); // Display Result if (calculationTask.IsCompleted) { try { Solutions solutions = calculationTask.Result; if (solutions.Count == 0) { Console.WriteLine("Downcount could not find a solution"); } else { IEquation solution = solutions[0]; if (solution.Value == game.TargetNumber) { Console.WriteLine("Downcount found an exact solution"); Console.WriteLine("{0} = {1}", targetNumber, solution.ToString()); } else { decimal closeValue = solution.Value; Console.WriteLine("Downcount found a solution within {0} of the original target number", game.TargetNumber - closeValue); Console.WriteLine("{0} = {1}", solution.Value, solution.ToString()); } } } catch (Exception ex) { Console.WriteLine(string.Format("An error occured calculating the solution: {0}", ex.ToString())); } } else { // We ran out of time Console.WriteLine("Downcount could not find a solution in the time given"); } Console.WriteLine(); }
/// <summary> /// Calculate the solution to the game /// </summary> private static Task<Solutions> CalculateSoultionASync(DownCountGame game) { Task<Solutions> calculationTask = new Task<Solutions>(() => CalculateSolution(game));//, cancellSource.Token); calculationTask.Start(); return calculationTask; }