private static int?GetMinimumMovesToTargetState(LockState target, LockState current, IEnumerable <LockState> deadEnds, int currentMin, int currentMoves, LockState previousState) { if (deadEnds.Any(s => s == current)) { return(null); } if (current == target) { return(Math.Min(currentMin, currentMoves)); } var nextMoves = new List <LockState> { current.MoveFirstClockwise(), current.MoveSecondClockwise(), current.MoveThirdClockwise(), current.MoveFirstCounterClockwise(), current.MoveSecondCounterClockwise(), current.MoveThirdCounterClockwise(), }; foreach (var nextMove in nextMoves) { if (nextMove == previousState) { continue; } currentMin = Math.Min(currentMin, GetMinimumMovesToTargetState(target, nextMove, deadEnds, currentMin, currentMoves + 1, current) ?? int.MaxValue); } return(currentMin); }