implemented basic challenge structure.
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,285 @@
|
||||
package spring24.week9;
|
||||
|
||||
/**
|
||||
* A Cell represents a single cell in the Sudoku grid.
|
||||
* This helper class is used to store the row, column, value, and possible values for a cell.
|
||||
* The possible values are stored in an ArrayList of Integers, and are sorted in ascending order.
|
||||
*
|
||||
* The Cell class also contains a method to add a possible value to the cell, and a method to get the possible values.
|
||||
*/
|
||||
public class Cell {
|
||||
private int row;
|
||||
private int col;
|
||||
private int box;
|
||||
private int value;
|
||||
private List possibleValues;
|
||||
|
||||
/**
|
||||
* Create a new Cell with the given row and column.
|
||||
*
|
||||
* The value of the cell is initially -2, and the possible values are initially empty.
|
||||
*
|
||||
* @param row
|
||||
* @param col
|
||||
*/
|
||||
public Cell(int row, int col) {
|
||||
this.row = row;
|
||||
this.col = col;
|
||||
setBox();
|
||||
possibleValues = new List();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new Cell with the given row, column, and value.
|
||||
*
|
||||
* The possible values are initially empty.
|
||||
*
|
||||
* @param row
|
||||
* @param col
|
||||
* @param value
|
||||
*/
|
||||
public Cell(int row, int col, int value) {
|
||||
this.row = row;
|
||||
this.col = col;
|
||||
this.value = value;
|
||||
setBox();
|
||||
possibleValues = new List();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new Cell with the given row, column, and possible values.
|
||||
*
|
||||
* The value of the cell is initially -2.
|
||||
*
|
||||
* @param row
|
||||
* @param col
|
||||
* @param possibleValues
|
||||
*/
|
||||
public Cell(int row, int col, int[] possibleValues) {
|
||||
this.row = row;
|
||||
this.col = col;
|
||||
setBox();
|
||||
this.possibleValues = new List(possibleValues);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of a cell.
|
||||
*
|
||||
* The value must be between 1 and 9, inclusive.
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
public void setValue(int value) {
|
||||
if(value < 1 || value > 9) {
|
||||
System.out.println("Value " + value + " is not a valid value for this cell.");
|
||||
return;
|
||||
}
|
||||
|
||||
possibleValues.clear();
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of a cell.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the box a cell is in.
|
||||
*
|
||||
* @return box number
|
||||
*/
|
||||
public int getBox() {
|
||||
return box;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a value to the list of possible values.
|
||||
*
|
||||
* If the value is already possible for the cell, or if the value is not a valid value for the cell, then the value is not added.
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
public void addPossibleValue(int value) {
|
||||
if(possibleValues.contains(value)) {
|
||||
System.out.println("Value " + value + " is already possible for this cell.");
|
||||
return;
|
||||
} else if(value < -1 || value > 9) {
|
||||
System.out.println("Value " + value + " is not a valid value for this cell.");
|
||||
return;
|
||||
}
|
||||
|
||||
possibleValues.add(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of possible values for the cell.
|
||||
*
|
||||
* This list is a copy of the cell's possible values, and is sorted in ascending order.
|
||||
*
|
||||
* @return list of possible values for the cell
|
||||
*/
|
||||
public int[] getPossibleValues() {
|
||||
return possibleValues.toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Given the cell's row and column, set the box number for the cell.
|
||||
*/
|
||||
private void setBox() {
|
||||
int boxRow = row % 3;
|
||||
int boxCol = col % 3;
|
||||
box = boxRow * 3 + boxCol;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class is used to store the possible values for a cell in a sorted list.
|
||||
* The list is sorted in ascending order, and the values are stored in a linked list.
|
||||
*
|
||||
* The List class also contains a method to add a value to the list, and a method to get the list of values as an array.
|
||||
*/
|
||||
private class List {
|
||||
|
||||
private Value head;
|
||||
private Value tail;
|
||||
private int size;
|
||||
private int max;
|
||||
private int min;
|
||||
|
||||
/**
|
||||
* Create a new empty List.
|
||||
*
|
||||
* By default, the head and tail are null, the size is 0, and the max and min are 0.
|
||||
*/
|
||||
public List() {
|
||||
head = null;
|
||||
tail = null;
|
||||
size = 0;
|
||||
max = 0;
|
||||
min = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new List with the given initial value.
|
||||
*
|
||||
* By default, the head and tail are the same, the size is 1, and the max and min are the initial value.
|
||||
* @param initValue
|
||||
*/
|
||||
public List(int initValue) {
|
||||
head = new Value(initValue);
|
||||
tail = head;
|
||||
size = 1;
|
||||
max = initValue;
|
||||
min = initValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new List with the given initial values.
|
||||
*
|
||||
* @param initValues
|
||||
*/
|
||||
public List(int[] initValues) {
|
||||
for(int i = 0; i < initValues.length; i++) add(initValues[i]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new value to the list.
|
||||
*
|
||||
* By default, the value will be inserted at it's sorted place in the list.
|
||||
*
|
||||
* @param newValue
|
||||
*/
|
||||
public void add(int newValue) {
|
||||
if(size == 0) {
|
||||
head = new Value(newValue);
|
||||
tail = head;
|
||||
size = 1;
|
||||
max = newValue;
|
||||
min = newValue;
|
||||
} else {
|
||||
if(newValue > max) {
|
||||
max = newValue;
|
||||
tail.next = new Value(newValue);
|
||||
tail = tail.next;
|
||||
} else if(newValue < min) {
|
||||
min = newValue;
|
||||
Value tmp = new Value(newValue);
|
||||
tmp.setNext(head);
|
||||
head = tmp;
|
||||
} else {
|
||||
Value current = head;
|
||||
while(current.next != null && current.next.value < newValue) {
|
||||
current = current.next;
|
||||
}
|
||||
Value tmp = new Value(newValue);
|
||||
tmp.setNext(current.next);
|
||||
current.setNext(tmp);
|
||||
}
|
||||
size++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of values as an array.
|
||||
*
|
||||
* @return array of values in the list
|
||||
*/
|
||||
public int[] toArray() {
|
||||
int[] array = new int[size];
|
||||
Value current = head;
|
||||
for(int i = 0; i < size; i++) {
|
||||
array[i] = current.value;
|
||||
current = current.next;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the list contains the given value.
|
||||
*
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public boolean contains(int value) {
|
||||
Value current = head;
|
||||
while(current != null) {
|
||||
if(current.value == value) return true;
|
||||
current = current.next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the list of all values.
|
||||
*/
|
||||
public void clear() {
|
||||
head = null;
|
||||
tail = null;
|
||||
size = 0;
|
||||
max = 0;
|
||||
min = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Value class is a Node for the List class.
|
||||
*/
|
||||
private class Value {
|
||||
|
||||
private int value;
|
||||
private Value next;
|
||||
|
||||
public Value(int value) {
|
||||
this.value = value;
|
||||
next = null;
|
||||
}
|
||||
|
||||
public void setNext(Value next) {
|
||||
this.next = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,225 @@
|
||||
package spring24.week9;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Scanner;
|
||||
|
||||
/**
|
||||
* A Sudoku puzzle is a 9x9 grid of numbers, where each row, column, and 3x3 subgrid contains the numbers 1-9 exactly once.
|
||||
*
|
||||
* The goal of this challenge is to write a program that can solve Sudoku puzzles.
|
||||
*
|
||||
* Given an input .sdku file (a plain-text file containing the initial state of a Sudoku puzzle), find the solution to the puzzle and write the solution to a new .sdku file.
|
||||
*
|
||||
* The input file will contain 9 lines, each containing 9 characters. Each character will be a digit (1-9) or a period (.), representing an empty cell.
|
||||
*
|
||||
* The output file should contain the same 9x9 grid, with the empty cells filled in with the correct numbers.
|
||||
*
|
||||
* For example, given the following input file:
|
||||
*
|
||||
* 53..7....
|
||||
* 6..195...
|
||||
* .98....6.
|
||||
* 8...6...3
|
||||
* 4..8.3..1
|
||||
* 7...2...6
|
||||
* .6....28.
|
||||
* ...419..5
|
||||
* ....8..79
|
||||
*
|
||||
* The output file should be:
|
||||
*
|
||||
* 534678912
|
||||
* 672195348
|
||||
* 198342567
|
||||
* 859761423
|
||||
* 426853791
|
||||
* 713924856
|
||||
* 961537284
|
||||
* 287419635
|
||||
* 345286179
|
||||
*
|
||||
* This challenge is broken up into parts. In Programming Club, we will split into teams of 3-4 people to work on each method.
|
||||
*/
|
||||
public class Sudoku {
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println("Welcome to the Sudoku Solver!");
|
||||
System.out.println("Let's solve a Sudoku puzzle.");
|
||||
|
||||
Scanner in = new Scanner(System.in);
|
||||
System.out.print("Enter the name of the input file (do not include the file extension): ");
|
||||
String inputFilename = in.nextLine();
|
||||
System.out.print("Enter the name of the output file (do not include the file extension): ");
|
||||
String outputFilename = in.nextLine();
|
||||
|
||||
Sudoku app = new Sudoku();
|
||||
Cell[][] grid = app.readPuzzle(inputFilename);
|
||||
app.solve(grid);
|
||||
app.saveSolution(outputFilename, grid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an input filename, read the Sudoku puzzle from the file and return it as a 9x9 grid numbers, with no value for spaces in the file.
|
||||
*
|
||||
* @param filename
|
||||
* @return
|
||||
*/
|
||||
public Cell[][] readPuzzle(String filename) {
|
||||
System.out.println("TODO: Read sudoku puzzle solution from " + filename);
|
||||
// TODO: Account for possible invalid input file and handle an error.
|
||||
// TODO: Spaces in the file should be represented as '.' in the grid.
|
||||
// TOOD: Read the file's puzzle.
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an output filename and a 9x9 grid of numbers, write the Sudoku puzzle to the file.
|
||||
*
|
||||
* @param grid
|
||||
* @return
|
||||
*/
|
||||
public void saveSolution(String filename, Cell[][] grid) {
|
||||
System.out.println("TODO: Write sudoku puzzle solution to " + filename);
|
||||
// TODO: Account for possible invalid solution from isSolved and handle an error.
|
||||
// TODO: Write the solution to the file.
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine what numbers are available to be placed in the given cell of the grid.
|
||||
*
|
||||
* @param grid
|
||||
* @param row
|
||||
* @param col
|
||||
* @return an array of numbers that are available to be placed in the given cell
|
||||
*/
|
||||
private void getAvailableNumbers(Cell[][] grid, int row, int col) {
|
||||
// TODO: Account for possible invalid inputs and handle an error.
|
||||
// TODO: Given the rules of Sudoku, determine what numbers are available to be placed in the given cell of the grid.
|
||||
// HINT: Use the getRowRemainingNumbers, getColRemainingNumbers, and getBoxRemainingNumbers methods and save to the Cell.
|
||||
System.out.println("TODO: Get available numbers for cell at row " + row + " and column " + col);
|
||||
}
|
||||
|
||||
/**
|
||||
* Solve the Sudoku puzzle.
|
||||
*
|
||||
* @param grid
|
||||
*/
|
||||
public void solve(Cell[][] grid) {
|
||||
// TODO: Account for possible invalid inputs and handle an error.
|
||||
// TODO: Given the rules of Sudoku, solve the puzzle.
|
||||
|
||||
// HINT: Use the getAvailableNumbers method to find the available numbers for each cell.
|
||||
// HINT: Use the isSolved method to check if the puzzle is solved.
|
||||
// HINT: Assume the puzzle is solvable and has only one solution.
|
||||
System.out.println("TODO: Solve the Sudoku puzzle");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get any number between 1 and 9 that is not in the row.
|
||||
*
|
||||
* @param grid
|
||||
* @param row
|
||||
* @return
|
||||
*/
|
||||
private ArrayList<Integer> getRowRemainingNumbers(Cell[][] grid, int row) {
|
||||
ArrayList<Integer> remainingNumbers = new ArrayList<Integer>();
|
||||
for(int i = 1; i <= 9; i++) {
|
||||
boolean found = false;
|
||||
for(int j = 0; j < 9; j++) {
|
||||
if(grid[row][j].getValue() == i) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found) {
|
||||
remainingNumbers.add(i);
|
||||
}
|
||||
}
|
||||
|
||||
return remainingNumbers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get any number between 1 and 9 that is not in the column.
|
||||
*
|
||||
* @param grid
|
||||
* @param col
|
||||
* @return
|
||||
*/
|
||||
private ArrayList<Integer> getColRemainingNumbers(Cell[][] grid, int col) {
|
||||
ArrayList<Integer> remainingNumbers = new ArrayList<Integer>();
|
||||
for(int i = 1; i <= 9; i++) {
|
||||
boolean found = false;
|
||||
for(int j = 0; j < 9; j++) {
|
||||
if(grid[j][col].getValue() == i) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found) {
|
||||
remainingNumbers.add(i);
|
||||
}
|
||||
}
|
||||
|
||||
return remainingNumbers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get any number between 1 and 9 that is not in the box.
|
||||
*
|
||||
* A box is a 3x3 subgrid of the 9x9 grid.
|
||||
*
|
||||
* @param grid
|
||||
* @param box
|
||||
* @return
|
||||
*/
|
||||
private ArrayList<Integer> getBoxRemainingNumbers(Cell[][] grid, int row, int col) {
|
||||
ArrayList<Integer> remainingNumbers = new ArrayList<Integer>();
|
||||
int boxRow = row % 3;
|
||||
int boxCol = col % 3;
|
||||
for(int i = 1; i <= 9; i++) {
|
||||
boolean found = false;
|
||||
for(int j = 0; j < 3; j++) {
|
||||
for(int k = 0; k < 3; k++) {
|
||||
if(grid[boxRow * 3 + j][boxCol * 3 + k].getValue() == i) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!found) {
|
||||
remainingNumbers.add(i);
|
||||
}
|
||||
}
|
||||
|
||||
return remainingNumbers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a list of numbers, return an array of the numbers.
|
||||
*
|
||||
* A helper method to keep the code using arrays instead of lists whenever possible.
|
||||
*
|
||||
* @param list
|
||||
* @return
|
||||
*/
|
||||
private int[] arrayListToArray(ArrayList<Integer> list) {
|
||||
int[] array = new int[list.size()];
|
||||
for(int i = 0; i < list.size(); i++) {
|
||||
array[i] = list.get(i);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a 9x9 grid of numbers, return true if the grid is a valid Sudoku puzzle solution, and false otherwise.
|
||||
*
|
||||
* A valid Sudoku puzzle is one where each row, column, and 3x3 subgrid contains the numbers 1-9 exactly once.
|
||||
*
|
||||
* @param grid a 9x9 grid of numbers
|
||||
* @return true if the grid is a valid Sudoku puzzle, and false otherwise
|
||||
*/
|
||||
private boolean isSolved(Cell[][] grid) {
|
||||
return false; // TODO: I need to do this before club.
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user