I'm trying to generate a Sudoku board via a 2D array: board[5][5]. The Sudoku board should only contain unique vowels. However, I have only made unique vowels appear in a row. For the columns, they still seem to have duplicates. How am I suppose to generate a column with no duplicates using the code I have so far?
Here's the code I have for generating unique letters in a row:
String [] vowels = {"A","E","I","O","U"};
String [][] board = new String [vowels.length][5];
public Actions(){
int rows = 5;
for(int row = 0;row<rows;row++){
ArrayList<String> tempVowels = new ArrayList<String>(Arrays.asList(vowels));
int numVowPerLine = (int)Math.floor(Math.random()*4);
for(int j = 0;j<numVowPerLine;j++){
do{
int pos = (int)Math.floor(Math.random()*5);
if(board[row][pos] == null){
int temp = (int)Math.floor(Math.random()*tempVowels.size());
board[row][pos] = tempVowels.get(temp);
tempVowels.remove(temp);
break;
}
}while(true);
}
}
Credits to: L7ColWinters
This is related to a rather well known problem, called the Rooks Problem.
Might I suggest a simpler loop?
EDIT: After reading comments, I see that the problem needs to be applied to each vowel. In my opinion, this is more readable:
java.util.Random random = new Random();
boolean[] r_occupied;
boolean[] c_occupied;
for (i = 0; i < vowels.length; i++)
{
// Clear the 'occupied' information
r_occupied = new boolean[5];
c_occupied = new boolean[5];
// we will put vowel[i] 'count' times into the 'board'
count = random.nextInt(5);
for (j = 0; j < count; j++)
{
// generate a random row
row = random.nextInt(5);
// if it is already occupied, select the next one
while (r_occupied[row])
row = (row + 1) % 5;
// generate a random column
col = random.nextInt(5);
// if it is already occupied, select the next one
while (c_occupied[col])
col = (col + 1) % 5;
/* put the vowel at board[row][col] */
r_occupied[row] = true;
c_occupied[col] = true;
board[row][col] = vowel[i];
}
}
Note: It will overwrite some vowels, but this should be OK.
If the content of first column / first row is A and you are on the first column / second row, you could use a truncated array, i.e. String [] availableVowels = {"E","I","O","U"};, to select from. If you pick O, then when you are on first column / thrid row, you would choose from String [] availableVowels = {"E","I","U"};. etc.
Before adding an additional vowel character in a row check if it
already contains this vowel and with continue you can pass to the
other vowel
You can also do the same thing for the columns with just switching
it
before this:
board[row][pos] = tempVowels.get(temp);
Write this:
boolean b = false;
for(int j = 0;j<columnLength; j++){
if(board[row][j] == tempVowels.get(temp))
b= true;
if(b == true)
{
b = false;
continue;
}
board[row][pos] = tempVowels.get(temp);
}
Related
I am trying to get this code to read in a text file and then populate a 15x15 grid with the numbers from the file. What it is doing is only populating the grid with 0's. I am not sure how to fix it, but I think the issue is with how I am trying to use list.indexOf() in the loop.
I have tried switching to use list.get(i) or using j, which has not worked the way I need it to.
public Grid(String fileName) throws FileNotFoundException {
//reading file using scanner
Scanner sc = new Scanner(new File(fileName));
//first number is the dimension for rows
this.rows = sc.nextInt();
//since it is square matrix second dimension is same as first
this.cols = this.rows;
grid = new boolean[rows][cols];
String longNumber = sc.next();
List<Integer> list = new ArrayList<>();
for(char ch : longNumber.toCharArray()) {
list.add( Integer.valueOf(String.valueOf(ch)));
}
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++) {
//reading from file 1 and 0 if 1 then store true else store false in grid
if (list.indexOf(i) == 1)
grid[i][j] = true;
else
grid[i][j] = false;
}
}
I am getting an output showing a 15x15 block of 0's, instead of the 1's and 0's that are being read in from the text file. The text file should be read in and displayed (along with a count of blobs or clumps of 1's), but this is not happening. If you need the rest of the code, please let me know. I am required to read in a file, which contains an int (15) which is used to make the grid, and then 15 lines of 1's and 0's, which should be displayed in the same way when the program works properly.
Why are you converting it into a List<Integer>? You can simply work with String that you got from the file.
For each row, you'll have to get a String and then for each of such a String you can do charAt() to check what is the character there and store true or false in grid accordingly.
The code will look something like this:
this.rows = sc.nextInt();
//since it is square matrix second dimension is same as first
this.cols = this.rows;
grid = new boolean[rows][cols];
for (int i = 0; i < rows; i++) {
String longNumber = sc.next();
for (int j = 0; j < cols; j++) {
//reading from file 1 and 0 if 1 then store true else store false in grid
grid[i][j] = (longNumber.charAt(j) == 1);
}
}
Notice that I've placed String longNumber = sc.next() in the outer loop.
HTH
My program freezes when I enter one million as a number for input. How do I fix this?
I tried separating second for loop as a second function, it didn't work.
import java.io.*;
public class Array {
public static void main(String[] args) {
String line = System.console().readLine("How many digits of Pi do you want? ");
int n = Integer.parseInt(line);
int columns = (int)(10.0*n/3.0);
int[][] makedigitsofpi = new int[columns][2];
makedigitsofpi[0][0] = 30;
makedigitsofpi[0][1] = 10;
for(int i = 1; i < columns; i++) {
makedigitsofpi[i][0] = i;
makedigitsofpi[i][1] = i*2+1;
}
int[] make2s = new int[columns];
for(int i = 0; i < columns; i++) {
make2s[i] = 2;
}
int[] timesby10 = new int[columns];
int[] thirdrow = new int[columns];
int[] fourrow = new int[columns];
int[] fifthrow = new int[columns];
for(int four_rows = 0; four_rows < n; four_rows++) {
for(int i = 0; i < columns; i++) {
timesby10[i] = make2s[i]*10;
}
for(int column = (columns - 1); column >= 0; column--) {
if(columns == (column + 1)) { //last column
thirdrow[column] = 0; // add last
}
else { // Third Row
int[] cell0 = makedigitsofpi[(column+1)];
int cellfour = fourrow[(column+1)];
int cellfive = fifthrow[(column+1)];
int d = cellfour - cellfive;
thirdrow[column] = (d*cell0[0])/cell0[1];
}
}
}
}
}
I need my program to be able to handle large numbers. This program is only the start of my project. The project is to create a program that generates Pi to a unlimited amount of digits.
How do I fix this?
Do the work in background thread.
Your code is working, the processor is used, doing math.
The "freeze" it is because it is not handling your inputs and is not finished his job.
To finish earlier the job, give smaller number of course.
To handle your imputs you need to do those for loops in a separated Thread
The code will not ececute faster, but you will not have the "freeze" feeling. If you would have a button to start in this case the button would be pressed and stay pressed, no other input.
In multi threaded context the button would release and you could switch from "start" state to "stop" state and if you press the button again, you set a Boolean variable value toggle: ex shouldCalculate = false; In your for loop if check that value, if is false, than exit from the thread, that's all.
Please take a look here to work with threads.
I managed to make a random sequence based on a seed, but now i am trying something else. basically, it generates a number(Based on a seed), then checks if that number is already in the array, then if it isn't in the array, it adds it to the array, and if it is, it goes on to the next one. However, my program works fine until it hits a 0, then it just keeps repeating 0. here is my code:
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.println("Enter a seed(One letter)");
String input = s.nextLine();
char a = input.charAt(0);
int b = ((int) a) - 96;
Random rnd1 = new Random(b);
int[] letters = new int[25];
boolean isSame = false;
for(int i = 0; i < 26; i++)
{
int c = rnd1.nextInt(26);
for(int x = 0; x < i; x++)
{
if(letters[x] == c)
{
isSame = true;
}
}
if(isSame == false)
{
letters[i] = c;
}
System.out.println(letters[i]);
}
}
Break the problem up in to parts, first a method to test for a value in letters between indices 0 and p like
private static boolean match(int[] letters, int p, int val) {
for (int i = 0; i < p; i++) {
if (letters[i] == val) {
return true;
}
}
return false;
}
Then a method to fill an int[] with a provided Random to a given length. Since you want the int[] to be unique, you can use an inner do while loop while the next symbol is already present. Like,
private static int[] fill(Random rnd1, int length) {
int[] letters = new int[length];
for (int i = 0; i < length; i++) {
int c;
do {
c = rnd1.nextInt(length);
} while (match(letters, i, c));
letters[i] = c;
}
return letters;
}
Then you can call that (and you might use Arrays.toString(int[])) to output the array like
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.println("Enter a seed(One letter)");
String input = s.nextLine();
char a = input.charAt(0);
int b = ((int) a) - 96;
Random rnd1 = new Random(b);
int[] letters = fill(rnd1, 26);
System.out.println(Arrays.toString(letters));
}
Two quick fixes:
1) The for loop is going up to index 25 which is ArrayIndexOutOfBoundsException as your array is of length 25.
for(int i = 0; i < 25; i++)
//Your code
}
2) Replace this code with something that can satisfy the condition as well generate a new random number and then assign it to array.
if (letters[x] == c) {
isSame = true;
}
It looks like you want to shuffle the numbers 0-25, that is, storing each number exactly once, but in a random position in the array. This is also known as generating a random permutation. Assuming this is the case, then there are two problems with your code:
isSame needs to be set to false when you pick a new random number, otherwise once a number is repeated, isSame is true for all subsequent numbers and nothing new is written to the array.
When a random number is picked that was already in the array (when isSame is found to be true), a new number needs to be found for that index. In your code, that index is skipped instead, and the value at that index will default to 0.
It is perhaps also worth mentioning that there are more efficient algorithms for this problem. This method will keep picking a lot of random numbers that are then just discarded, which is wasteful. The Fisher-Yates shuffle solves this (pseudocode from wikipedia):
for i from 0 to nā2 do
j ā random integer such that i ā¤ j < n
exchange a[i] and a[j]
I've a problem with my sudoku solving method. The program works like this; the board is empty when started, the users adds a couple of numbers to the board and then by hitting a Solve-button the program tries to solve it. Everything works fine besides if I put the same number in the same row. So if the user adds 1,1,0,0 ... 0. In the puzzle it can't solve it because its two 1's next to each other and will just go on forever trying to find a sulotion even though its an unsolvable puzzle. However if they were all 0's(empty) it would solve it right away, same as if Id put 1 and 2 in the top left corner. If I'd just put some random numbers in it will detect it as unsolvable (or will solve it if it's a valid puzzle)
I'm thinking around the lines of saying, when theNumber == (row, col) equals thenNumber == (row+1, col), it should return false because it's a duplicated number.
This is the code I tried to add in the solve method, obviously without success.
if ((puzzle.getNum(row, col) == a) == (puzzle.getNum(row + 1, col) == a)) {
return false;
}
Help is greatly appreciated
Validate the puzzle like this:
Create a boolean array of 9 elements.
Loop through every row, column and 9x9 box.
If you read a number, set the corresponding value in the array to true.
If it is already true throw an error (impossible puzzle).
After reading a row, column or 9x9 box reset the boolean array.
Then, if the validation succeeded call the solving method.
EDIT: Source code
public boolean checkPuzzle() {
boolean[] nums = new boolean[9];
for (int row = 0; row < panel.puzzleSize; row++) {
for (int cell = 0; cell < panel.puzzleSize; cell++) {
if (nums[puzzle[row][cell]]) return false;
nums[puzzle[row][cell]] = true;
}
nums = new boolean[9];
}
for (int col = 0; col < panel.puzzleSize; col++) {
for (int cell = 0; cell < panel.puzzleSize; cell++) {
if (nums[puzzle[cell][col]]) return false;
nums[puzzle[cell][col]] = true;
}
nums = new boolean[9];
}
for (int square = 0; square < panel.puzzleSize; square++) {
int squareCol = panel.squareSize * (square % panel.squareSize);
int squareRow = panel.squareSize * Math.floor(square / panel.squareSize);
for (int cell = 0; cell < panel.puzzleSize; cell++) {
int col = cell % panel.squareSize;
int row = Math.floor(cell / panel.squareSize);
if (nums[puzzle[squareCol + col][squareRow + row]]) return false;
nums[puzzle[squareCol + col][squareRow + row]] = true;
}
nums = new boolean[9];
}
return true;
}
Didn't have too much time to test out, but it might work (?). The row/col variable namings might be incorrect, because I didn't have time to find that in your code, but it shouldn't matter for it to work or not.
I had a class assignment (it's already past) where I had to write a Sudoku solver. I was able to create a method that can solve for each missing number. But I'm having trouble creating a method to find which cells I need to solve. I'm supposed to take a 2D array and fill in the missing number (represented by 0's).
I've put some of my code below, but not all of it (even though the assignment has passed, I respect the profs wishes).
public class SolveSudoku {
private static int[][] grid = new int[9][9];
public static int[][] getSolution(int[][] grid) {
for (int i = 0; i < 9; i++) {
System.arraycopy(grid[i], 0, SolveSudoku.grid[i], 0, 9);
}
int n = getZero();
return getSolution(n);
}
private static int[][] getSolution(int n) {
if (n == 0) {
return grid;
}
Cell cell = getZero();
int row = cell.row;
int column = cell.column;
for (int number = 1; number <= 9; number++) {
//checks cell using another method
//I have booleans that return true if the number works
}
return null;
}
private static int getZero() {
return 0;
}
private static class Cell {
int cell = 0;
int row = 0;
int column = 0;
int number;
}
}
I have the getZero method which has to find each zero in the grid (0's represent a missing number) so I can solve it. What should I do in getZero to find the cells I need to replace?
You don't check if the number is repeated in the same 3x3 square (only rows and columns).
I don't get what do you mean by "finding zeroes". In fact it is meaningless, solving the sudoku from the first row or the last one has no effect in the solution. I'll explain what did I do for the same trouble.
A cell is not an int, is an object. In the object I store a value (the number if it is found, 0 if not) and a boolean[9]. False means (index + 1) is discarded because it is in the same row/column/square, true means it is not decided yet. Also, 3 Lists (Vectors, Sets, whatever).
A list of 81 cells (you can make it a bidimensional array if you wish).
9 Lists/Vectors/Sets representing rows, 9 representing columns, 9 representing square. Each of the 81 cells is assigned to its row/column/square. Inside each cell you store the references to the list to which it belongs to.
Now comes the execution part. In a first iteration, every time you find a non-zero (a number fixed in the sudoku), you loop through the lists to which the cell belongs. For each cell in those lists, you mark the boolean assigned to that number to false.
You loop through cells, each time you find a 0 you check how many of the booleans in the cell are true. If it is 1 (all other 8 possible values have been discarded), it is the value of the cell. You set it, and as in 4) you get the list to which it belongs and mark that number to false in every cells. Loop until you get a solution, or an iteration in which you cannot set any number (no solution available directly, must start with backtracking or similar).
Remember before getting at the keyboard, to have a clear idea about what the question is and how would you resolve it without a computer. If you do not know what you want to do, the computer won't help (unless you post in stackoverflow)-
From what I can tell you want to find the first 0-valued cell in grid. I'll define first as the first zero containing column in the lowest zero-containing row.
This can be done using a naive search:
private Cell getZeroCell(){
int rz = -1;
int cz = -1;
outer: for(int row = 0; row < grid.length; row++){
for(int col = 0; col < grid[row].length; col++){
if(grid[row][col] == 0){
rz = row;
cz = col;
break outer;
}
}
}
if(rz == -1 || cz == -1){
// no zeros found
return null;
}else{
// first zero found at row `rz` and column `cz`
Cell cell = new Cell();
cell.row = rz;
cell.column = cz;
return cell;
}
}
Get the "number" of the first cell containing a zero (counting left to right, then top to bottom, 0-indexed):
private int getZeroInt(){
int rz = -1;
int cz = -1;
outer: for(int row = 0; row < grid.length; row++){
for(int col = 0; col < grid[row].length; col++){
if(grid[row][col] == 0){
rz = row;
cz = col;
break outer;
}
}
}
if(rz == -1 || cz == -1){
// no zeros found
return -1;
}else{
return rz * grid[0].length + cz;
}
}
Get the number of cells containing a zero:
private int getNumZeros(){
int count = 0;
for(int row = 0; row < grid.length; row++){
for(int col = 0; col < grid[row].length; col++){
if(grid[row][col] == 0){
count++;
}
}
}
return count;
}