首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用种子数独的数独发生器

使用种子数独的数独发生器
EN

Code Review用户
提问于 2019-05-18 11:48:42
回答 2查看 327关注 0票数 3

我用Java创建了一个Sudoku生成器。在这里,我使用一个基本的已解决的sudoku作为种子,通过转换它和移动它的行和列,我得到了一个新的解决sudoku。

代码语言:javascript
复制
 //import java.util.Arrays;

import java.util.Random;

public class SudokuGenerator {
    private char[][] board = new char[9][9];
    private int[] randomizeSudoku = new int[9];
    private char[][] transposedSeed = new char[][]{{'8', '2', '7', '1', '5', '4', '3', '9', '6'},
            {'9', '6', '5', '3', '2', '7', '1', '4', '8'},
            {'3', '4', '1', '6', '8', '9', '7', '5', '2'},
            {'5', '9', '3', '4', '6', '8', '2', '7', '1'},
            {'4', '7', '2', '5', '1', '3', '6', '8', '9'},
            {'6', '1', '8', '9', '7', '2', '4', '3', '5'},
            {'7', '8', '6', '2', '3', '5', '9', '1', '4'},
            {'1', '5', '4', '7', '9', '6', '8', '2', '3'},
            {'2', '3', '9', '8', '4', '1', '5', '6', '7'},};
    private char[][] seed = new char[9][9];
    private Random random = new Random();

    public static void main(String[] args) {
        SudokuGenerator s = new SudokuGenerator();
        int n = 2;
        s.transpose();
        s.shuffle();
        s.seedChanger();
        while (n > 0) {
            System.out.println("\n\n------ New Board --------\n");
            s.transpose();
            s.shuffle();
            s.display();
            s.seedChanger();
            n--;
        }
    }

    private void transpose() {
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                seed[j][i] = transposedSeed[i][j];
            }
        }
    }

    private void seedChanger() {
        for (int i = 0; i < 9; i++) {
            System.arraycopy(board[i], 0, transposedSeed[i], 0, board.length);
        }
    }

    private void randomSudokuGenerator() {
        for (int i = 0; i < randomizeSudoku.length; i++) {
            randomizeSudoku[i] = 9;
        }
        int i = 0;
        for (; i < randomizeSudoku.length; ++i) {
            int r = random.nextInt(2);
            for (int i1 = 0; i1 < i; ++i1) {
                int x = randomizeSudoku[i1];
                if (x == r) {
                    if (i < 3) {
                        r = random.nextInt(3);
                    } else if (i < 6) {
                        r = random.nextInt(3) + 3;
                    } else if (i < 9) {
                        r = random.nextInt(3) + 6;
                    }
                    i1 = -1;
                }
            }
            randomizeSudoku[i] = r;
        }
    }

    private void shuffle() {
        randomSudokuGenerator();
//        System.out.println(Arrays.toString(randomizeSudoku));
        for (int x = 0; x < 9; x++) {
            board[0][x] = seed[randomizeSudoku[0]][x];
            board[1][x] = seed[randomizeSudoku[1]][x];
            board[2][x] = seed[randomizeSudoku[2]][x];
            board[3][x] = seed[randomizeSudoku[3]][x];
            board[4][x] = seed[randomizeSudoku[4]][x];
            board[5][x] = seed[randomizeSudoku[5]][x];
            board[6][x] = seed[randomizeSudoku[6]][x];
            board[7][x] = seed[randomizeSudoku[7]][x];
            board[8][x] = seed[randomizeSudoku[8]][x];
        }
        for (int x = 0; x < 9; x++) {

            if (randomizeSudoku[0] == 0) swapping(board, x, 1, 0);
            if (randomizeSudoku[0] == 1) swapping(board, x, 2, 0);
            if (randomizeSudoku[0] == 0) swapping(board, x, 5, 4);
            if (randomizeSudoku[0] == 1) swapping(board, x, 5, 3);
            if (randomizeSudoku[0] == 2) swapping(board, x, 8, 6);
        }
    }

    private void swapping(char[][] a, int commonIndex, int first, int second) {
        char swap = a[commonIndex][first];
        a[commonIndex][first] = a[commonIndex][second];
        board[commonIndex][second] = swap;
    }

    private void display() {
        int i, j;
        for (i = 0; i <= 8; ++i) {
            if (i == 0) {
                System.out.print("\t\t\t_______________________________________\n\t row " + (i + 1) + "\t");
            } else {
                System.out.print("\t\t\t|---|---|---||---|---|---||---|---|---|\n\t row " + (i + 1) + "\t");
            }
            for (j = 0; j <= 8; ++j) {
                if (j == 3) {
                    System.out.print("|");
                }
                if (j == 6) {
                    System.out.print("|");
                }
                if (j == 8) {
                    System.out.println("| " + board[i][j] + " |");
                } else {
                    System.out.print("| " + board[i][j] + " ");
                }
            }
            if (i == 2) {
                System.out.println("\t\t\t|---|---|---||---|---|---||---|---|---|");
            }
            if (i == 5) {
                System.out.println("\t\t\t|---|---|---||---|---|---||---|---|---|");
            }
            if (i == 8) {
                System.out.println("\t\t\t---------------------------------------");
                System.out.println("\tcolumns   1   2   3    4   5   6    7   8   9  \n\n\n");
            }
        }
    }
}
EN

回答 2

Code Review用户

回答已采纳

发布于 2019-05-18 19:49:42

对于这篇评论,我的操作假设是:这是一个类分配/编程挑战,并且/或有部分复制粘贴/由多个人完成。造成这种情况的主要原因是b/c过度不一致的w/格式。这是一个很好的分段:

格式

由于您使用的是Java,我将简要介绍OOD (面向对象的设计)。尽管这是一个被控制的程序/脚本,但是将您的main函数拆分成一个单独的类是一个很好的实践。这将允许您将Sedoku求解器设计为一个单独的对象。这一点非常重要,因为您在SudokuGenerator函数中使用了main

在样式化方面,您的for循环的格式设置不一致。你跳起来了。使用++ii++ (我更喜欢前缀b/c )来提高性能,尽管现在可能无关紧要),在循环内外声明变量,并使用i < 9i <= 8。这里的原则只是一种逻辑形式。因此,让我们开始使用这些原则轻微地改变程序。

Main.java

代码语言:javascript
复制
    public static void main(String[] args) {
        SudokuGenerator gen = new SudokuGenerator();
        // initial transpose, shuffle & seedChange happens in a constructor
        for (int i = 2; i > 0; --i) {
            System.out.println("\n\n------ New Board --------\n");
            gen.transpose();
            gen.shuffle();
            gen.display();
            gen.seedChanger();
        }
        /*
        int n = 2;
        s.transpose();
        s.shuffle();
        s.seedChanger();
        while (n > 0) {
            System.out.println("\n\n------ New Board --------\n");
            s.transpose();
            s.shuffle();
            s.display();
            s.seedChanger();
            n--;
        }
        */
    }

正如这里的注释所述,您为准备生成器所做的最初工作现在已在其默认构造函数中处理。您从不在这些调用中编辑n,所以在for循环中声明和修改while是最好的方法。

改性后的

(

)

Main.java

代码语言:javascript
复制
package T145.sudokugen;

public class Main {

    static char[][] transposedSeed = new char[][] {
        {'8', '2', '7', '1', '5', '4', '3', '9', '6'},
        {'9', '6', '5', '3', '2', '7', '1', '4', '8'},
        {'3', '4', '1', '6', '8', '9', '7', '5', '2'},
        {'5', '9', '3', '4', '6', '8', '2', '7', '1'},
        {'4', '7', '2', '5', '1', '3', '6', '8', '9'},
        {'6', '1', '8', '9', '7', '2', '4', '3', '5'},
        {'7', '8', '6', '2', '3', '5', '9', '1', '4'},
        {'1', '5', '4', '7', '9', '6', '8', '2', '3'},
        {'2', '3', '9', '8', '4', '1', '5', '6', '7'}
    };

    public static void main(String[] args) {
        Sudoku game = new Sudoku(transposedSeed);
        // initial transpose, shuffle & seedChange happens in a constructor
        for (int i = 2; i >= 0; --i) {
            System.out.println("\n\n------ New Board --------\n");
            game.transpose();
            game.shuffle();
            game.printBoard();
            game.seedChanger();
        }
    }
}

Sudoku.java

代码语言:javascript
复制
package T145.sudokugen;

import java.util.Random;

public class Sudoku {

    private final char[][] transposedSeed;

    private char[][] board = new char[9][9];
    private int[] randomizeSudoku = new int[9];
    private char[][] seed = new char[9][9];
    private Random random = new Random();

    public Sudoku(char[][] transposedSeed) {
        this.transposedSeed = transposedSeed;

        transpose();
        shuffle();
        seedChanger();
    }

    public void transpose() {
        for (short i = 0; i < 9; ++i) {
            for (short j = 0; j < 9; ++j) {
                seed[j][i] = transposedSeed[i][j];
            }
        }
    }

    public void seedChanger() {
        for (short i = 0; i < 9; ++i) {
            System.arraycopy(board[i], 0, transposedSeed[i], 0, board.length);
        }
    }

    public void randomSudokuGenerator() {
        short i = 0;

        for (i = 0; i < randomizeSudoku.length; ++i) {
            randomizeSudoku[i] = 9;
        }

        for (i = 0; i < randomizeSudoku.length; ++i) {
            int r = random.nextInt(2);

            for (int i1 = 0; i1 < i; ++i1) {
                int x = randomizeSudoku[i1];

                if (x == r) {
                    if (i < 3) {
                        r = random.nextInt(3);
                    } else if (i < 6) {
                        r = random.nextInt(3) + 3;
                    } else if (i < 9) {
                        r = random.nextInt(3) + 6;
                    }

                    i1 = -1;
                }
            }

            randomizeSudoku[i] = r;
        }
    }

    private void swap(char[][] a, int commonIndex, int first, int second) {
        char swap = a[commonIndex][first];
        a[commonIndex][first] = a[commonIndex][second];
        board[commonIndex][second] = swap;
    }

    public void shuffle() {
        randomSudokuGenerator();

        for (short x = 0; x < 9; ++x) {
            board[0][x] = seed[randomizeSudoku[0]][x];
            board[1][x] = seed[randomizeSudoku[1]][x];
            board[2][x] = seed[randomizeSudoku[2]][x];
            board[3][x] = seed[randomizeSudoku[3]][x];
            board[4][x] = seed[randomizeSudoku[4]][x];
            board[5][x] = seed[randomizeSudoku[5]][x];
            board[6][x] = seed[randomizeSudoku[6]][x];
            board[7][x] = seed[randomizeSudoku[7]][x];
            board[8][x] = seed[randomizeSudoku[8]][x];
        }

        for (short x = 0; x < 9; ++x) {
            if (randomizeSudoku[0] == 0) {
                swap(board, x, 1, 0);
            }

            if (randomizeSudoku[0] == 1) {
                swap(board, x, 2, 0);
            }

            if (randomizeSudoku[0] == 0) {
                swap(board, x, 5, 4);
            }

            if (randomizeSudoku[0] == 1) {
                swap(board, x, 5, 3);
            }

            if (randomizeSudoku[0] == 2) {
                swap(board, x, 8, 6);
            }
        }
    }

    public void printBoard() {
        for (short i = 0; i < 9; ++i) {

            if (i == 0) {
                System.out.print("\t\t\t_______________________________________\n\t row " + (i + 1) + "\t");
            } else {
                System.out.print("\t\t\t|---|---|---||---|---|---||---|---|---|\n\t row " + (i + 1) + "\t");
            }

            for (short j = 0; j < 9; ++j) {
                if (j == 3) {
                    System.out.print("|");
                }

                if (j == 6) {
                    System.out.print("|");
                }

                if (j == 8) {
                    System.out.println("| " + board[i][j] + " |");
                } else {
                    System.out.print("| " + board[i][j] + " ");
                }
            }

            if (i == 2) {
                System.out.println("\t\t\t|---|---|---||---|---|---||---|---|---|");
            }

            if (i == 5) {
                System.out.println("\t\t\t|---|---|---||---|---|---||---|---|---|");
            }

            if (i == 8) {
                System.out.println("\t\t\t---------------------------------------");
                System.out.println("\tcolumns   1   2   3    4   5   6    7   8   9  \n\n\n");
            }
        }
    }
}

这其中的大部分只是简单的重新格式化。您会注意到,在某些情况下,我使用short over int,这只是简单的b/c结构,shorts的内存印记较少。关于现代计算机有多少内存并不是真正重要的b/c,但我喜欢编写注重细节的代码。

我没有修改你最初推理的任何核心逻辑b/c。但是要指出正确的方向,想想:

1)模块操作符(%)可以用于清理某些操作。

2)可以使用其他帮助优化性能的数据结构的地方。

3)可以使用Java 8+功能来优化性能,或者至少精简代码w/等效性能。

票数 2
EN

Code Review用户

发布于 2019-05-19 06:27:39

按照答案中的建议,我稍微更新了我的代码,并进一步优化了它,并试图管理方法的任务。下面是我所做的一些改变;

在这里,我把初始的转换和移动放到构造函数中,

代码语言:javascript
复制
private SudokuGenerator() {
    this.transpose();
    this.shuffle();
    this.seedChanger();
}

接下来,我创建了一个生成新sudoku的方法generate(),

代码语言:javascript
复制
private void generate() {
        System.out.println("\n\n------ New Board --------\n");
        for (int i = 0; i < random.nextInt(5); i++) {
            this.transpose();
            this.shuffle();
            this.seedChanger();
        }
        this.display();
    }

我优化了我的方法之一,通过使用for循环对数组的所有索引更改了类似的任务,

旧代码:

代码语言:javascript
复制
 for (short x = 0; x < 9; ++x) {
            board[0][x] = seed[randomizeSudoku[0]][x];
            board[1][x] = seed[randomizeSudoku[1]][x];
            board[2][x] = seed[randomizeSudoku[2]][x];
            board[3][x] = seed[randomizeSudoku[3]][x];
            board[4][x] = seed[randomizeSudoku[4]][x];
            board[5][x] = seed[randomizeSudoku[5]][x];
            board[6][x] = seed[randomizeSudoku[6]][x];
            board[7][x] = seed[randomizeSudoku[7]][x];
            board[8][x] = seed[randomizeSudoku[8]][x];
        }

优化代码:

代码语言:javascript
复制
for (int x = 0; x < 9; x++) {
            for (int i = 0; i < 9; i++) {
                board[i][x] = seed[randomizeSudoku[i]][x];
            }
        }

并将所有<=8转换为< 9

现在取消main:

代码语言:javascript
复制
 public static void main(String[] args) {
        SudokuGenerator s = new SudokuGenerator();
        s.generate();
    }

现在好多了吗?@T 145

票数 0
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/220461

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档