public int TestSum(int[] intArray) { IntVector vec = new IntVector(intArray); SumVector sum = new SumVector(); return(sum.sum(vec)); }
private sbyte?[] AttemptSolve(sbyte?[] setValues, List <sbyte> valuesLeft, SumVector v, List <SumVector> vectorsLeft, CancellationToken token) { if (token.IsCancellationRequested) { return(null); } if (v == null) { return(setValues); } sbyte?[] result = null; //for state we really only care about the view //of the board for this vector & the remaining ones. var boxesToTrack = vectorsLeft.Concat(new[] { v }).SelectMany(x => x.BoxIndexes).Distinct().ToList(); var trackState = setValues.Where((x, i) => x.HasValue && boxesToTrack.Contains(i)).Select(x => x.Value).ToArray(); if (v.TrackState(trackState, valuesLeft)) { var solutionDictionary = v.GetSolutionDictionary(setValues, valuesLeft, token); if (solutionDictionary.Values != null) { Parallel.ForEach(solutionDictionary.Values.OrderBy(x => x.Value.Solutions), (k, state) => { var temp = AttemptSolveOneSolutionGroup(setValues, valuesLeft, v, k, vectorsLeft, token); if (temp != null || token.IsCancellationRequested) { result = temp; state.Break(); } }); } } else { double skipped = v.FinalSolutionsCount; foreach (var notComputed in vectorsLeft) { skipped *= notComputed.FinalSolutionsCount; } lock (this) { ProgressBar.CompletedCount += skipped; } } return(result); }
private static IEnumerable <sbyte[]> IntersectionPermuatations(sbyte[] values, int[] intersections) { if (intersections.Length == 0) { //Add special case handling if we have no intersections, //just return the single value. yield return(values); yield break; } var valuesInOrder = values.OrderBy(x => x).ToList(); var returnArray = new sbyte[values.Length]; foreach (var combo in SumVector.GetCombination(new List <sbyte>(), valuesInOrder, intersections.Length)) { var valuesForPerm = valuesInOrder.ToList(); foreach (var c in combo) { valuesForPerm.Remove(c); } foreach (var comboPerm in Permutations(combo.ToArray(), 0)) { var intersectionCounter = 0; var nextIntersection = intersections[intersectionCounter]; var valueSelector = 0; for (var i = 0; i < values.Length; i++) { sbyte value; if (i == nextIntersection) { value = comboPerm[intersectionCounter++]; nextIntersection = intersectionCounter < intersections.Length ? intersections[intersectionCounter] : -1; } else { value = valuesForPerm[valueSelector++]; } returnArray[i] = value; } yield return(returnArray.ToArray()); } } }
private sbyte?[] AttemptSolveOneSolutionGroup(sbyte?[] setValues, List <sbyte> valuesLeft, SumVector v, KeyValuePair <sbyte, KeyDictionary> k, List <SumVector> vectorsLeft, CancellationToken token) { bool topLevel = false; if (token.IsCancellationRequested) { return(null); } if (setValues == null) { topLevel = true; setValues = new sbyte?[100]; } var primarySetValues = setValues.ToArray(); var primaryValuesLeft = valuesLeft.ToList(); //Interlocked.Add(ref ProgressBar.TotalSolutions, k.Value.Solutions); bool solutionWorks = EvaluateSolutionGroup(primarySetValues, primaryValuesLeft, v.BoxIndexes[0], k.Key); if (solutionWorks) { var rslt = EvalNextGroups(new EvalContext { SetValues = primarySetValues, ValuesLeft = primaryValuesLeft, KeyGroup = k.Value, Position = 1, }, v, vectorsLeft, token); if (rslt != null) { return(rslt); } double skipped = k.Value.Solutions; foreach (var notComputed in vectorsLeft) { skipped *= notComputed.FinalSolutionsCount; } lock (this) { ProgressBar.CompletedCount += skipped; } Console.WriteLine($"[{v.Sum}]: Eliminated sg {k.Key} - {vectorsLeft.Count} vectors left."); } else { double skipped = k.Value.Solutions; foreach (var notComputed in vectorsLeft) { skipped *= notComputed.FinalSolutionsCount; } lock (this) { ProgressBar.CompletedCount += skipped; } } //else //{ // Console.WriteLine("ITT Prevented!!"); //} return(null); }
private sbyte?[] EvalNextGroups(EvalContext context, SumVector v, List <SumVector> vectorsLeft, CancellationToken token) { if (token.IsCancellationRequested) { return(null); } var stack = new Stack <EvalContext>(); stack.Push(context); while (stack.Any()) { if (token.IsCancellationRequested) { return(null); } var ctx = stack.Pop(); if (ctx.Position >= v.Boxes.Count) { //if (v.TrackState(ctx.SetValues, ctx.ValuesLeft)) //{ var rslt = AttemptSolve(ctx.SetValues, ctx.ValuesLeft, vectorsLeft.FirstOrDefault(), vectorsLeft.Skip(1).ToList(), token); if (rslt != null) { return(rslt); } //} //else //{ // Console.WriteLine("ITT prevented due to state tracking."); //} continue; } var boxIdx = v.BoxIndexes[ctx.Position]; var setVal = ctx.SetValues[boxIdx]; //Short-cut if we have values set. if (setVal.HasValue) { if (ctx.KeyGroup.Values.TryGetValue(setVal.Value, out var next)) { stack.Push(new EvalContext { //Can we get away with not duplicating these here?? SetValues = ctx.SetValues.ToArray(), ValuesLeft = ctx.ValuesLeft.ToList(), KeyGroup = next, Position = ctx.Position + 1 }); } continue; } else { foreach (var k in ctx.KeyGroup.Values.OrderByDescending(c => c.Value.Solutions)) { var tempSetValues = ctx.SetValues.ToArray(); var tempValuesLeft = ctx.ValuesLeft.ToList(); var works = EvaluateSolutionGroup(tempSetValues, tempValuesLeft, v.BoxIndexes[ctx.Position], k.Key); if (works) { stack.Push(new EvalContext { SetValues = tempSetValues, ValuesLeft = tempValuesLeft, KeyGroup = k.Value, Position = ctx.Position + 1 }); } } } } return(null); }
private List <SumVector> GetVectors() { var vectors = new List <SumVector>(); var rowBoxes = new SumVector(); var colBoxes = new SumVector(); //search rows... for (var y = 0; y < 10; y++) { for (var x = 0; x < 10; x++) { var tbRow = textBoxes[y, x]; if (!string.IsNullOrWhiteSpace(tbRow.Text)) { if (tbRow.BackColor != Color.LightGreen) { rowBoxes.Boxes.Add(tbRow); } else { var text = tbRow.Text.ToUpper().Trim(); if (!text.Contains("U") && !text.Contains("D")) { text = text.Replace("L", string.Empty).Replace("R", string.Empty); rowBoxes.Sum = sbyte.Parse(text); } else { //this one isn't for us. rowBoxes = new SumVector(); } } } else { if (rowBoxes.Sum.HasValue && rowBoxes.Boxes.Any()) { foreach (var b in rowBoxes.Boxes) { rowBoxes.BoxIndexes.Add(flatBoxes.IndexOf(b)); } vectors.Add(rowBoxes); } rowBoxes = new SumVector(); } var tbCol = textBoxes[x, y]; if (!string.IsNullOrWhiteSpace(tbCol.Text)) { if (tbCol.BackColor != Color.LightGreen) { colBoxes.Boxes.Add(tbCol); } else { var text = tbCol.Text.ToUpper().Trim(); if (!text.Contains("L") && !text.Contains("R")) { text = text.Replace("U", string.Empty).Replace("D", string.Empty); colBoxes.Sum = sbyte.Parse(text); } else { //this one isn't for us. colBoxes = new SumVector(); } } } else { if (colBoxes.Sum.HasValue && colBoxes.Boxes.Any()) { foreach (var b in colBoxes.Boxes) { colBoxes.BoxIndexes.Add(flatBoxes.IndexOf(b)); } vectors.Add(colBoxes); } colBoxes = new SumVector(); } } //Handle wrap to next row/column if (rowBoxes.Sum.HasValue && rowBoxes.Boxes.Any()) { foreach (var b in rowBoxes.Boxes) { rowBoxes.BoxIndexes.Add(flatBoxes.IndexOf(b)); } vectors.Add(rowBoxes); rowBoxes = new SumVector(); } if (colBoxes.Sum.HasValue && colBoxes.Boxes.Any()) { foreach (var b in colBoxes.Boxes) { colBoxes.BoxIndexes.Add(flatBoxes.IndexOf(b)); } vectors.Add(colBoxes); colBoxes = new SumVector(); } } return(vectors); }