-3

I am trying to implement an iterative Sudoku solver. To avoid recursion I used a stack, but I'm having problems with its management. The starting board is represented by a String array (variable 'input' in the following code) in which each element is composed of 3 numbers: the [row, col] and its value (i.e, "006" means that the element in the 1st line and 1st col is 6) and is translated into an array of int by the constructor. When I run it, I cannot get a solution, so there are probably mistakes in the nested for cycles. Any help is appreciated.

import java.util.ArrayList;

public class SudokuSolver {

    private int[][] matrix = new int[9][9];
    private String[] input = { "006", "073", "102", "131", "149", "217",
        "235", "303", "345", "361", "378", "422", "465", "514", "521",
        "548", "582", "658", "679", "743", "752", "784", "818", "883" };

    private ArrayList<int[][]> stack = new ArrayList<>();

    public SudokuSolver() {
        // Building the board based on input array
        for (int n = 0; n < input.length; ++n) {
            int i = Integer.parseInt(input[n].substring(0, 1));
            int j = Integer.parseInt(input[n].substring(1, 2));
            int val = Integer.parseInt(input[n].substring(2, 3));
            matrix[i][j] = val;
        }
        stack.add(matrix);
    }

    private boolean isSolution(int[][] cells) {
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                if(cells[i][j] == 0)
                    return false;
            }
        }
        return true;
    }

    private boolean isValid(int i, int j, int val, int[][] cells) {
        for (int k = 0; k < 9; k++)
            if (val == cells[k][j])
                return false;
        for (int k = 0; k < 9; k++)
            if (val == cells[i][k])
                return false;
        return true;
    }

    private boolean iterativeSudokuSolver() {
        int[][] current = null;

        while(stack.size() > 0 && !isSolution(stack.get(0))) {
            current = stack.remove(0);

            for (int row = 0; row < 9; row++) {
                for (int col = 0; col < 9; col++) {
                    if (current[row][col] == 0) {
                        for (int val = 1; val <= 9; val++) {
                            if (isValid(row, col, val, current)) {
                                current[row][col] = val;
                                stack.add(0, current);
                                break;
                            }
                        }
                    }
                }
            }
        }
        if (current != null && isSolution(current))
            return true;
        else
            return false;
    }

    public static void main(String [] args) {
        SudokuSolver sudokuSolver = new SudokuSolver();
        boolean result = sudokuSolver.iterativeSudokuSolver();

        if (result)
            System.out.println("Sudoku solved");
        else
            System.out.println("Sudoku not solved");
    }
}
tobias_k
  • 81,265
  • 12
  • 120
  • 179
Emonale
  • 513
  • 2
  • 7
  • 22
  • From your rep., it appears you are fairly new to StackOverflow (SO). A good suggestion for your future questions: generally, the SO community prefers more pointed or directed questions - less so very general "how to" questions, like that above. Often times it is best if you isolate a portion of the code you feel is most problematic, identify the specific problem, and request help in better understanding the problem. – Thomas Apr 29 '15 at 11:55
  • Why do you want to avoid recursion? The brute force algorithm would recuse at most 81 times: not a real issue at all. – chqrlie May 08 '15 at 14:42
  • Because I am implementing a test for a middleware which uses serialization to migrate execution state among network peers. Unfortunately recursion does not allow me to do that. – Emonale May 08 '15 at 20:50

1 Answers1

0
  1. A stack implementation by adding and removing the 0-th element of an ArrayList is a very bad idea: it forces the whole content of the array to be shifted back an forth every time. Use LinkedList or modify the end of the list.
  2. When you add and remove the same instance of the matrix back and forth to the stack, it is still the same matrix object, even though you may call it "current" or any other name. This means that when you change something in the matrix and then remove it from your stack, the change stays there (and in every other element of your stack, which are identical links to the same object). The logic of your solution looks like it needs to store the previous state of the solution on the stack, if so - allocate a new array every time and copy the data (also not very efficient, but try starting there).
  3. A good question has to be specific. "Why this doesn't work?" is a bad question. Fix the obvious problems first, debug, and if puzzled provide more information about the state of your program (data in, data on step #1...N, for example)
Alex Nevidomsky
  • 668
  • 7
  • 14
  • Thanks, rewriting the stack implementation solved the problem. Actually I did not take into account the reference passing. – Emonale Apr 29 '15 at 12:01