public object Clone() { var rows = RowDescriptors.Select(desc => new RowDescriptor() { BlockSizes = desc.BlockSizes.ToList() }).ToList(); var columns = ColumnDescriptors.Select(desc => new RowDescriptor() { BlockSizes = desc.BlockSizes.ToList() }).ToList(); var c = new Nonogram(Width, Height) { RowDescriptors = rows, ColumnDescriptors = columns }; for (int i = 0; i < Height; i++) { for (int j = 0; j < Width; j++) { c.Cells[i][j].State = c.Cells[i][j].State; } } return(c); }
private List <List <CellState> > FindSolution(WorkingCopy assignments, Nonogram n, List <List <List <CellState> > > cellStates) { int nullIndex = assignments.AssignedRows.FindIndex(x => x == null); if (nullIndex < 0) { if (!containsErrors(assignments, n)) { return(assignments.AssignedRows); } else { return(null); } } var rowVariants = cellStates[nullIndex]; var workingCopy = assignments.Clone() as WorkingCopy; foreach (var value in rowVariants) { workingCopy.AssignedRows[nullIndex] = value; if (containsErrors(assignments, n)) { continue; } var resultsSearch = FindSolution(workingCopy, n, cellStates); if (resultsSearch != null) { return(resultsSearch); } } return(null); }
public void Solve(Nonogram n) { var rowsPossibleStates = Utils.PossibleStatesForRows(n.Width, n.RowDescriptors); var colsPossibleStates = Utils.PossibleStatesForRows(n.Height, n.ColumnDescriptors); var rowSolvingCandidates = rowsPossibleStates.Select(rowStates => FindCommonCells(rowStates).ToList()).ToList(); var colSolvingCandidates = colsPossibleStates.Select(rowStates => FindCommonCells(rowStates).ToList()).ToList(); bool changeFound = true; while (changeFound) { changeFound = false; for (int i = 0; i < rowSolvingCandidates.Count; i++) { var rowCandidate = rowSolvingCandidates[i]; int rowsCandidatesRemoved = RemoveConflictingStates(rowCandidate, i, colsPossibleStates); if (rowsCandidatesRemoved > 0) { changeFound = true; } } colSolvingCandidates = colsPossibleStates.Select(rowStates => FindCommonCells(rowStates).ToList()).ToList(); for (int i = 0; i < colSolvingCandidates.Count; i++) { var rowCandidate = colSolvingCandidates[i]; int rowsCandidatesRemoved = RemoveConflictingStates(rowCandidate, i, rowsPossibleStates); if (rowsCandidatesRemoved > 0) { changeFound = true; } } rowSolvingCandidates = rowsPossibleStates.Select(rowStates => FindCommonCells(rowStates).ToList()).ToList(); } for (int i = 0; i < n.Height; i++) { var row = n.getRow(i); var commonCells = rowSolvingCandidates[i]; for (int j = 0; j < commonCells.Count; j++) { row[j].State = commonCells[j]; } } for (int i = 0; i < n.Width; i++) { var col = n.getColumn(i); var commonCells = colSolvingCandidates[i]; for (int j = 0; j < commonCells.Count; j++) { col[j].State = commonCells[j]; } } }
private bool containsErrors(WorkingCopy assignments, Nonogram n) { for (int i = 0; i < n.Width; i++) { var createdColumn = assignments.AssignedRows.Select(x => x == null ? CellState.Undefined : x[i]).ToList(); if (Utils.GetRowStatus(createdColumn, n.ColumnDescriptors[i]) == RowStatus.ContainsErrors) { return(true); } } return(false); }
public static Nonogram MakeNonogram(int rows, int columns) { var nonogram = new Nonogram(columns, rows); var rand = new Random(); var a = (Array)(new int[] { 5 }); foreach (var r in nonogram.Cells) { foreach (var cell in r) { cell.State = rand.NextDouble() > 0.5 ? CellState.Filled : CellState.Empty; } } var rowsList = new List <RowDescriptor>(rows); for (int i = 0; i < rows; i++) { var row = nonogram.getRow(i); RowDescriptor rowDescriptor = MakeRowDescriptorFor(row); rowsList.Add(rowDescriptor); } nonogram.RowDescriptors = rowsList; var columnList = new List <RowDescriptor>(rows); for (int i = 0; i < columns; i++) { var column = nonogram.getColumn(i); RowDescriptor rowDescriptor = MakeRowDescriptorFor(column); columnList.Add(rowDescriptor); } nonogram.ColumnDescriptors = columnList; return(nonogram); }
public void Solve(Nonogram n) { var rowsPossibleStates = Utils.PossibleStatesForRows(n.Width, n.RowDescriptors); var colsPossibleStates = Utils.PossibleStatesForRows(n.Height, n.ColumnDescriptors); var initWorkingCopy = new WorkingCopy() { AssignedRows = Enumerable.Repeat <List <CellState> >(null, n.Height).ToList() }; var solution = FindSolution(initWorkingCopy, n, rowsPossibleStates); if (solution == null) { throw new Exception("wtf??????????/"); } for (int i = 0; i < n.Height; i++) { for (int j = 0; j < n.Width; j++) { n.Cells[i][j].State = solution[i][j]; } } }
public void Solve(Nonogram n) { var rowVars = n.RowDescriptors.Select((desc, i) => new Variable() { PossibleStates = Utils.MakePossibleStates(n.Width, desc).Select(x => x.ToList()).ToList(), Index = i, ColType = ColumnType.Row } ).ToList(); var colVars = n.ColumnDescriptors.Select((desc, i) => new Variable() { PossibleStates = Utils.MakePossibleStates(n.Height, desc).Select(x => x.ToList()).ToList(), Index = i, ColType = ColumnType.Column }).ToList(); var allVars = rowVars.Concat(colVars).ToList(); var rand = new Random(); int oneRun = 0; while (allVars.Any(v => v.PossibleStates.Count > 1) && oneRun < 4) { oneRun++; TrySolve(allVars); var sortedByStatesCount = allVars .OrderBy(x => x.PossibleStates.Count) .Where(x => x.PossibleStates.Count > 1) .ToList(); if (!sortedByStatesCount.Any()) { break; } var unsolvedVar = sortedByStatesCount.FirstOrDefault(); var states = new List <List <CellState> >(unsolvedVar.PossibleStates); var allVarsClone = allVars.Select(v => v.Clone() as Variable).ToList(); var unsolvedVarClone = allVarsClone.Find(x => x.ColType == unsolvedVar.ColType && x.Index == unsolvedVar.Index); var possibleStatesLeft = new List <List <CellState> >(); foreach (var st in states) { unsolvedVarClone.PossibleStates = new List <List <CellState> > { st }; TrySolve(allVarsClone); if (allVarsClone.All(v => v.PossibleStates.Count == 1)) { allVars = allVarsClone; break; } else if (allVarsClone.Any(v => !v.PossibleStates.Any())) { continue; } else { possibleStatesLeft.Add(st); } } if (unsolvedVar.PossibleStates.Count != possibleStatesLeft.Count && allVars.Any(v => v.PossibleStates.Count != 1)) { unsolvedVarClone.PossibleStates = possibleStatesLeft; break; } } foreach (var v in allVars) { if (v.ColType == ColumnType.Row) { if (v.PossibleStates.Count == 1) { var state = v.PossibleStates.First(); for (int i = 0; i < state.Count; i++) { n.Cells[v.Index][i].State = state[i]; } } else { var solver = new ContradictionSolver(); var state = solver.FindCommonCells(v.PossibleStates).ToList(); for (int i = 0; i < state.Count; i++) { n.Cells[v.Index][i].State = state[i]; } Trace.WriteLine($"at: {v.ColType} {v.Index}, possible states: {v.PossibleStates.Count}"); } } } }
public void SolveWithOneGuess(Nonogram n) { var rowsPossibleStates = Utils.PossibleStatesForRows(n.Width, n.RowDescriptors); var colsPossibleStates = Utils.PossibleStatesForRows(n.Height, n.ColumnDescriptors); List <List <CellState> > rowSolvingCandidates = null; List <List <CellState> > colSolvingCandidates = null; bool fullySolved = false; while (rowsPossibleStates.All(rowStates => rowStates.Count > 0) && colsPossibleStates.All(columnStates => columnStates.Count > 0) && !fullySolved) { rowSolvingCandidates = rowsPossibleStates.Select(rowStates => FindCommonCells(rowStates).ToList()).ToList(); colSolvingCandidates = colsPossibleStates.Select(rowStates => FindCommonCells(rowStates).ToList()).ToList(); bool changeFound = true; while (changeFound) { changeFound = false; for (int i = 0; i < rowSolvingCandidates.Count; i++) { var rowCandidate = rowSolvingCandidates[i]; int rowsCandidatesRemoved = RemoveConflictingStates(rowCandidate, i, colsPossibleStates); if (rowsCandidatesRemoved > 0) { changeFound = true; } } if (colsPossibleStates.Any(columnStates => columnStates.Count == 0)) { break; } colSolvingCandidates = colsPossibleStates.Select(rowStates => FindCommonCells(rowStates).ToList()).ToList(); for (int i = 0; i < colSolvingCandidates.Count; i++) { var rowCandidate = colSolvingCandidates[i]; int rowsCandidatesRemoved = RemoveConflictingStates(rowCandidate, i, rowsPossibleStates); if (rowsCandidatesRemoved > 0) { changeFound = true; } } if (rowsPossibleStates.Any(rowStates => rowStates.Count == 0)) { break; } rowSolvingCandidates = rowsPossibleStates.Select(rowStates => FindCommonCells(rowStates).ToList()).ToList(); } fullySolved = rowSolvingCandidates.All(rowState => rowState.All(cell => cell != CellState.Undefined)) && colSolvingCandidates.All(rowState => rowState.All(cell => cell != CellState.Undefined)); if (!fullySolved) { //find row with several candidates left and remove all others foreach (var colStates in colsPossibleStates) { if (colStates.Count > 1) { colStates.RemoveRange(1, colStates.Count - 1); break; } } } } for (int i = 0; i < n.Height; i++) { var row = n.getRow(i); var commonCells = rowSolvingCandidates[i]; for (int j = 0; j < commonCells.Count; j++) { row[j].State = commonCells[j]; } } for (int i = 0; i < n.Width; i++) { var col = n.getColumn(i); var commonCells = colSolvingCandidates[i]; for (int j = 0; j < commonCells.Count; j++) { col[j].State = commonCells[j]; } } }