/* * int[,] referenceMask = new int[12, 9] * { * { 0, 0, 0, 1, 1, 1, 0, 0, 0 }, * { 0, 0, 0, 1, 1, 1, 0, 0, 0 }, * { 0, 0, 0, 1, 1, 1, 0, 0, 0 }, * { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, * { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, * { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, * { 0, 0, 0, 1, 1, 1, 0, 0, 0 }, * { 0, 0, 0, 1, 1, 1, 0, 0, 0 }, * { 0, 0, 0, 1, 1, 1, 0, 0, 0 }, * { 0, 0, 0, 1, 1, 1, 0, 0, 0 }, * { 0, 0, 0, 1, 1, 1, 0, 0, 0 }, * { 0, 0, 0, 1, 1, 1, 0, 0, 0 } * }; */ public static Func <Cube3, bool> RotateColorsOfCenterNeighborsEqFunc(Cube3 refCube) { int[,] colorsNotEqualsMask = new int[12, 9] { { 8, 8, 8, 0, 0, 0, 8, 8, 8 }, { 8, 8, 8, 0, 0, 0, 8, 8, 8 }, { 8, 8, 8, 0, 0, 0, 8, 8, 8 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 1, 1, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 1, 0, 0, 0, 0 }, { 8, 8, 8, 0, 1, 0, 8, 8, 8 }, { 8, 8, 8, 0, 0, 0, 8, 8, 8 }, { 8, 8, 8, 0, 0, 0, 8, 8, 8 }, { 8, 8, 8, 0, 0, 0, 8, 8, 8 }, { 8, 8, 8, 0, 0, 0, 8, 8, 8 }, { 8, 8, 8, 0, 0, 0, 8, 8, 8 } }; int[,] piecesEqualsMask = new int[12, 9] { { 8, 8, 8, 0, 1, 0, 8, 8, 8 }, { 8, 8, 8, 1, 1, 1, 8, 8, 8 }, { 8, 8, 8, 0, 1, 0, 8, 8, 8 }, { 0, 1, 0, 0, 1, 0, 0, 1, 0 }, { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, { 0, 1, 0, 0, 1, 0, 0, 1, 0 }, { 8, 8, 8, 0, 1, 0, 8, 8, 8 }, { 8, 8, 8, 1, 1, 1, 8, 8, 8 }, { 8, 8, 8, 0, 1, 0, 8, 8, 8 }, { 8, 8, 8, 0, 1, 0, 8, 8, 8 }, { 8, 8, 8, 1, 1, 1, 8, 8, 8 }, { 8, 8, 8, 0, 1, 0, 8, 8, 8 } }; int[,] colorsMaskCenterNeighbor = new int[12, 9] { { 0, 0, 0, 0, 1, 0, 0, 0, 0 }, { 0, 0, 0, 1, 1, 1, 0, 0, 0 }, { 0, 0, 0, 0, 1, 0, 0, 0, 0 }, { 0, 1, 0, 0, 1, 0, 0, 1, 0 }, { 1, 1, 0, 0, 1, 1, 1, 1, 1 }, { 0, 1, 0, 0, 0, 0, 0, 1, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 1, 1, 1, 0, 0, 0 }, { 0, 0, 0, 0, 1, 0, 0, 0, 0 }, { 0, 0, 0, 0, 1, 0, 0, 0, 0 }, { 0, 0, 0, 1, 1, 1, 0, 0, 0 }, { 0, 0, 0, 0, 1, 0, 0, 0, 0 } }; return((cube) => { return cube.EqualsPieces(refCube, piecesEqualsMask) && !cube.EqualsColors(refCube, colorsNotEqualsMask) && cube.EqualsColors(refCube, colorsMaskCenterNeighbor); }); }
public static Func <Cube3, Cube3, bool> SwapEdgeNeighborsEqFunc() { var piecesEqualPoints = Cube3.MaskToPoints(new int[12, 9] { { 8, 8, 8, 1, 1, 1, 8, 8, 8 }, { 8, 8, 8, 1, 1, 1, 8, 8, 8 }, { 8, 8, 8, 1, 1, 1, 8, 8, 8 }, { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, { 0, 1, 0, 0, 1, 1, 1, 1, 1 }, { 8, 8, 8, 0, 1, 1, 8, 8, 8 }, { 8, 8, 8, 1, 1, 1, 8, 8, 8 }, { 8, 8, 8, 0, 1, 1, 8, 8, 8 }, { 8, 8, 8, 0, 1, 1, 8, 8, 8 }, { 8, 8, 8, 1, 1, 1, 8, 8, 8 }, { 8, 8, 8, 1, 1, 1, 8, 8, 8 } }); var piecesNotEqualPoints = Cube3.MaskToPoints(new int[12, 9] { { 8, 8, 8, 0, 0, 0, 8, 8, 8 }, { 8, 8, 8, 0, 0, 0, 8, 8, 8 }, { 8, 8, 8, 0, 0, 0, 8, 8, 8 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 1, 0, 1, 1, 0, 0, 0, 0, 0 }, { 8, 8, 8, 1, 0, 0, 8, 8, 8 }, { 8, 8, 8, 0, 0, 0, 8, 8, 8 }, { 8, 8, 8, 1, 0, 0, 8, 8, 8 }, { 8, 8, 8, 1, 0, 0, 8, 8, 8 }, { 8, 8, 8, 0, 0, 0, 8, 8, 8 }, { 8, 8, 8, 0, 0, 0, 8, 8, 8 } }); int[,] colorsEqualsMask = new int[12, 9] { { 8, 8, 8, 1, 1, 1, 8, 8, 8 }, { 8, 8, 8, 1, 1, 1, 8, 8, 8 }, { 8, 8, 8, 1, 1, 1, 8, 8, 8 }, { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, { 1, 1, 0, 0, 1, 0, 0, 1, 1 }, { 8, 8, 8, 0, 1, 0, 8, 8, 8 }, { 8, 8, 8, 1, 1, 1, 8, 8, 8 }, { 8, 8, 8, 1, 1, 1, 8, 8, 8 }, { 8, 8, 8, 1, 1, 1, 8, 8, 8 }, { 8, 8, 8, 1, 1, 1, 8, 8, 8 }, { 8, 8, 8, 1, 1, 1, 8, 8, 8 } }; return((cube, refCube) => { return cube.EqualsPieces(refCube, piecesEqualPoints) && !cube.EqualsPieces(refCube, piecesNotEqualPoints); }); }
Cube3 PrepareCube() { var cube = new Cube3(); cube.Rotate("a2", 1); cube.Rotate("b2", 1); cube.Rotate("c2", 1); cube.Rotate("a1", 1); cube.Rotate("b1", 1); cube.Rotate("c1", 1); return(cube); }
void PrintSolution(Cube3 cube, List <List <string> > result) { lock (printLock) { if (result != null && result.Count > 0) { Console.WriteLine($"Paths found: {result.Count}"); result.Sort((x, y) => x.Count.CompareTo(y.Count)); PrintSolution(cube, result[0]); } else { Console.WriteLine("No moves found :("); } } }
public Cube3(Cube3 other) { for (int x = 0; x < COLORS_X; x++) { for (int y = 0; y < COLORS_Y; y++) { colors[y, x] = other.colors[y, x]; } } for (int x = 0; x < COLORS_X; x++) { for (int y = 0; y < COLORS_Y; y++) { pieces[y, x] = other.pieces[y, x]; } } Validate(); InitDescriptors(); }
public static Func <Cube3, bool> SwapEdgeNeighborsEqFunc_HalfHourNoResult(Cube3 refCube) { int[,] piecesNotEqualsMask = new int[12, 9] { { 8, 8, 8, 0, 0, 0, 8, 8, 8 }, { 8, 8, 8, 0, 0, 0, 8, 8, 8 }, { 8, 8, 8, 0, 0, 0, 8, 8, 8 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 1, 1, 0, 1, 1, 0, 0 }, { 8, 8, 8, 1, 0, 1, 8, 8, 8 }, { 8, 8, 8, 0, 0, 0, 8, 8, 8 }, { 8, 8, 8, 0, 0, 0, 8, 8, 8 }, { 8, 8, 8, 0, 0, 0, 8, 8, 8 }, { 8, 8, 8, 0, 0, 0, 8, 8, 8 }, { 8, 8, 8, 0, 0, 0, 8, 8, 8 } }; int[,] colorsEqualsMask = new int[12, 9] { { 8, 8, 8, 1, 1, 1, 8, 8, 8 }, { 8, 8, 8, 1, 1, 1, 8, 8, 8 }, { 8, 8, 8, 1, 1, 1, 8, 8, 8 }, { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, { 1, 1, 0, 0, 1, 0, 0, 1, 1 }, { 8, 8, 8, 0, 1, 0, 8, 8, 8 }, { 8, 8, 8, 1, 1, 1, 8, 8, 8 }, { 8, 8, 8, 1, 1, 1, 8, 8, 8 }, { 8, 8, 8, 1, 1, 1, 8, 8, 8 }, { 8, 8, 8, 1, 1, 1, 8, 8, 8 }, { 8, 8, 8, 1, 1, 1, 8, 8, 8 } }; return((cube) => { return //!cube.EqualsPieces(refCube, piecesNotEqualsMask) && (cube.Pieces[5, 3] != refCube.Pieces[5, 3] || cube.Pieces[5, 5] != refCube.Pieces[5, 5]) && cube.EqualsColors(refCube, colorsEqualsMask); }); }
public static IEnumerable <XY> MaskToPoints(int[,] mask) { var agg = new Dictionary <int, XY>(); var cube = new Cube3(); for (var y = 0; y < mask.GetLength(0); y++) { for (var x = 0; x < mask.GetLength(1); x++) { if (mask[y, x] == 1) { if (!agg.ContainsKey(cube.Pieces[y, x])) { agg.Add(cube.Pieces[y, x], new XY(x, y)); } } } } return(agg.Values.ToArray()); }
public RecursiveSolutionFinder3(Cube3 cube, Action <Cube3, List <string> > print, Func <Cube3, Cube3, bool> eqFunc, int maxDepth, int maxThreads) { this.print = print; this.eqFunc = eqFunc; this.maxThreads = maxThreads; this.refCube = new Cube3(cube); this.maxDepth = maxDepth; for (char moveLetter = 'a'; moveLetter <= 'c'; moveLetter++) { for (char moveIdx = '1'; moveIdx <= '2'; moveIdx++) { letterIndexStrings[moveLetter - 'a', moveIdx - '1'] = $"{moveLetter}{moveIdx}"; for (int count = 1; count <= 3; count++) { letterIndexCountStrings[moveLetter - 'a', moveIdx - '1', count - 1] = $"{moveLetter}{moveIdx}/{count}"; } } } }
void PrintSolution(Cube3 cube, List <string> result) { lock (printLock) { if (result != null && result.Count > 0) { Console.WriteLine(); for (int i = 0; i < result.Count; i++) { Console.Write((i > 0 ? ", " : "") + (i + 1) + ". " + result[i]); } Console.WriteLine(); Console.WriteLine(); cube = new Cube3(cube); cube.Rotate(result[0]); Console.WriteLine(cube.ToStringWithPieces()); } else { Console.WriteLine("No moves found :("); } } }
public bool EqualsPieces(Cube3 other, IEnumerable <XY> points) { return(ArrayEqualsUsingPoints(pieces, other.pieces, points)); }
public bool EqualsColors(Cube3 other, IEnumerable <XY> points) { return(ArrayEqualsUsingPoints(colors, other.colors, points)); }
public bool EqualsColors(Cube3 other, int[,] mask = null) { return(ArrayEqualsUsingMask(colors, other.colors, mask)); }
public bool EqualsPieces(Cube3 other, int[,] mask = null) { return(ArrayEqualsUsingMask(pieces, other.pieces, mask)); }
public override bool Equals(object obj) { Cube3 other = (Cube3)obj; return(EqualsColors(other)); }
List <List <string> > RecursivelyRotateAndCompare(Cube3 cube, char prevMoveLetter, char prevMoveIdx, char beforePrevMoveLetter, int depth, string[] moves, bool executedInSeparateThread) { Interlocked.Increment(ref combinationCounter); List <List <string> > result = null; if (eqFunc(cube, refCube)) { result = new List <List <string> >(); result.Add(moves.ToList()); print(refCube, result[0]); return(result); } if (depth >= moves.Length) { return(result); } List <Task <List <List <string> > > > tasks = null; for (char moveLetter = 'a'; moveLetter <= 'c'; moveLetter++) { if (moveLetter == beforePrevMoveLetter) { continue; } for (char moveIdx = '1'; moveIdx <= '2'; moveIdx++) { if (moveLetter == prevMoveLetter && moveIdx == prevMoveIdx) { continue; } for (int count = 1; count <= 3; count++) { cube.Rotate(moveLetter, moveIdx, count); moves[depth] = ToString(moveLetter, moveIdx, count); if (Thread.VolatileRead(ref activeThreadCount) < maxThreads) { int newThreadNumber = Interlocked.Increment(ref activeThreadCount); if (tasks == null) { tasks = new List <Task <List <List <string> > > >(); } var cubeClone = new Cube3(cube); var moveLetterClone = moveLetter; var moveIdxClone = moveIdx; var prevMoveLetterClone = prevMoveLetter; var movesClone = (string[])moves.Clone(); tasks.Add(Task.Run(() => { return(RecursivelyRotateAndCompare(cubeClone, moveLetterClone, moveIdxClone, prevMoveLetterClone, depth + 1, movesClone, true)); })); } else { var resultToAdd = RecursivelyRotateAndCompare(cube, moveLetter, moveIdx, prevMoveLetter, depth + 1, moves, false); AccumulateResult(result, resultToAdd); } moves[depth] = null; cube.Rotate(moveLetter, moveIdx, -count); } } } if (executedInSeparateThread) { Interlocked.Decrement(ref activeThreadCount); } if (tasks != null) { tasks.ForEach(x => AccumulateResult(result, x.Result)); } return(result); }