Java ArrayIndexOutOfBoundsException (Minesweeper) - java

I am trying to make a simple minesweeper that plants n*n/3 mines in a n*n board. The mines are marked by *, and blank spaces are marked by 0. (It does not function as a game yet: I'm trying to make the 'answer sheet' of the minesweeper) And please note that I haven't used any methods on purpose.
I am constantly getting an error at the 23rd line:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 15
I have tried for hours to fix this issue, but none seems to work. Can anyone point out what is wrong and how I should fix my code? Thanks.
import java.util.Scanner;
public class Minesweeper {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
char board[][] = new char [n][n]; // makes board of n*n
int a, b;
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[i].length; j++) {
board[i][j] = '0';
}
}
for (int i = 0; i < n * n / 3; i++) { // '*' is a mine
a = (int)(Math.random() * (n - 1) + 1.0);
b = (int)(Math.random() * (n - 1) + 1.0);
board[a][b] = '*';
}
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[i].length; j++) {
for (int k = i - 1; k <= i + 1 && k >= 0 && k <= n; k++) {
for (int l = j - 1; l <= j + 1 && l >= 0 && l <= n; l++) {
if (board[k][l] == '*' && !(k == i && l == j)) {
board[i][j] = (char)(Character.getNumericValue(board[i][j]) + 1);
}
}
}
}
}
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[i].length; j++) {
System.out.println(board[i][j]);
}
}
}
}

for (int k = i - 1; k <= i + 1 && k >= 0 && k <= n; k++) {
for (int l = j - 1; l <= j + 1 && l >= 0 && l <= n; l++) {
It should be k < n and l < n. n is already outside the boundaries.
Also
for (int i = 0; i < n * n / 3; i++) { // '*' is a mine
a = (int)(Math.random() * (n - 1) + 1.0);
b = (int)(Math.random() * (n - 1) + 1.0);
board[a][b] = '*';
}
seems wrong, I think it should be
for (int i = 0; i < n * n / 3; i++) { // '*' is a mine
a = (int)(Math.random() * n);
b = (int)(Math.random() * n);
board[a][b] = '*';
}

Related

How to make diamond pattern using java?

How to make this pattern
if input N = 5
Output :
Mine is like this, it become 2N
if input N = 5
Output
Here's my code
int i,j;
for(i = 0; i <= n; i++)
{
for(j = 1; j <= n - i; j++)
System.out.print(" ");
for(j = 1; j <= 2 * i - 1; j++)
System.out.print("*");
System.out.print("\n");
}
for(i = n - 1; i >= 1; i--)
{
for(j = 1; j <= n - i; j++)
System.out.print(" ");
for(j = 1; j <= 2 * i - 1; j++)
System.out.print("*");
System.out.print("\n");
}
What should i fix??
You can check odd numbers in your loop. Please see the following example:
public static void main(String[] args) {
printPattern(5);
}
private static void printPattern(int n) {
int i, j;
for (i = 0; i <= n; i++) {
if (i % 2 != 0) {
for (j = 1; j <= (n - i)/2; j++) {
System.out.print(" ");
}
for (j = 0; j < i; j++) {
System.out.print("*");
}
System.out.println();
}
}
for (i = n - 1; i >= 1; i--) {
if (i % 2 != 0) {
for (j = 1; j <= (n - i)/2; j++) {
System.out.print(" ");
}
for (j = 0; j <i; j++) {
System.out.print("*");
}
System.out.println();
}
}
}
Instead of running these two loops from 0 to N twice. Just run half N/2 in each loop.
Example:
public static void main(String[] args) {
int n = 10;
for (int i = 0; i <= (n / 2 + 1); i++) {
for (int j = 1; j <= n - i; j++) System.out.print(" ");
for (int j = 1; j <= 2 * i - 1; j++) System.out.print("*");
System.out.print("\n");
}
// N/2
for (int i = n / 2 - 1; i >= 1; i--) {
for (int j = 1; j <= n - i; j++) System.out.print(" ");
for (int j = 1; j <= 2 * i - 1; j++) System.out.print("*");
System.out.print("\n");
}
}

how to print the below pattern

for the given input I need to print the pattern. For example for input = 6 I have to print:
MMMMMMSDDDDDD
MMMMMSSSDDDDD
MMMMSSSSSDDDD
MMMSSSSSSSDDD
MMSSSSSSSSSDD
MSSSSSSSSSSSD
CSSSSSSSSSSSK
CCSSSSSSSSSKK
CCCSSSSSSSKKK
CCCCSSSSSKKKK
CCCCCSSSKKKKK
CCCCCCSKKKKKK
I have tried but couldn't go further than this could anyone help
public class tgk {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int size = sc.nextInt();
int half = ((2*size)+1)/2;
for (int i = 0; i < size ; i++)
{
for (int j = size; j > i; j--)
{
System.out.print("M");
}
for (int k = half+1 ; k > half - i; k--)
{
System.out.print("S");
}
System.out.println();
}
for(int i = size; i > 0; i--)
{
for (int j = size; j >= i; j--) {
System.out.print("C");
}
for (int k = 0; k < (i * 2 - 1); k++) {
System.out.print("S");
}
System.out.println();
}
}
}
if input = 3 it should be
MMMSDDD
MMSSSDD
MSSSSSD
CSSSSSK
CCSSSKK
CCCSKKK
You can use two sets of for loops to print each half of the pattern. Assuming input variable holds the size of the problem
int input = 3;
for (int i = 0; i < input; i++) {
for (int j = 0; j < input - i; j++) {
System.out.print('M');
}
for (int j = 0; j < 2 * i + 1; j++) {
System.out.print('S');
}
for (int j = 0; j < input - i; j++) {
System.out.print('D');
}
System.out.println();
}
for (int i = input - 1; i >= 0; i--) {
for (int j = 0; j < input - i; j++) {
System.out.print('C');
}
for (int j = 0; j < 2 * i + 1; j++) {
System.out.print('S');
}
for (int j = 0; j < input - i; j++) {
System.out.print('K');
}
System.out.println();
}
will print for input = 3:
MMMSDDD
MMSSSDD
MSSSSSD
CSSSSSK
CCSSSKK
CCCSKKK
and for input = 6:
MMMMMMSDDDDDD
MMMMMSSSDDDDD
MMMMSSSSSDDDD
MMMSSSSSSSDDD
MMSSSSSSSSSDD
MSSSSSSSSSSSD
CSSSSSSSSSSSK
CCSSSSSSSSSKK
CCCSSSSSSSKKK
CCCCSSSSSKKKK
CCCCCSSSKKKKK
CCCCCCSKKKKKK
I don't know why, but I really wanted it to work with only one set of for-loops:
int number = 8;
for (int i = 0; i < number * 2; i++) {
for (int j = 0; j < (number * 2) + 1; j++) {
System.out.print(
i < number && j+i < number ? 'M' :
i < number && j-i > number ? 'D' :
i < number ? 'S' :
i >= number && i-j >= number ? 'C' :
i >= number && j+i >= number*3 ? 'K' :
'S'
);
}
System.out.println();
}
So for 8 (like in the code) it prints:
MMMMMMMMSDDDDDDDD
MMMMMMMSSSDDDDDDD
MMMMMMSSSSSDDDDDD
MMMMMSSSSSSSDDDDD
MMMMSSSSSSSSSDDDD
MMMSSSSSSSSSSSDDD
MMSSSSSSSSSSSSSDD
MSSSSSSSSSSSSSSSD
CSSSSSSSSSSSSSSSK
CCSSSSSSSSSSSSSKK
CCCSSSSSSSSSSSKKK
CCCCSSSSSSSSSKKKK
CCCCCSSSSSSSKKKKK
CCCCCCSSSSSKKKKKK
CCCCCCCSSSKKKKKKK
CCCCCCCCSKKKKKKKK
...or for 3:
MMMSDDD
MMSSSDD
MSSSSSD
CSSSSSK
CCSSSKK
CCCSKKK

SPOJ Prime Generator, getting TLE, but approached with the best I could. (JAVA)

The problem is to generate prime in between two interval, detail problem is given in this link. SPOJ Prime Generator.
Let me explain the magic numbers and the algorithm I followed.
I have used modified Sieve Eratosthenes algorithm (modified in sense because I used the basic idea.) for implementation.
Starting number of interval, m and End number of the interval n are <= 10^9 and the difference is <=10^5 (1 <= m <= n <= 1000000000, n-m<=100000)
There is no even prime number except 2, so I considered max m and n (10^9)/2
and sqrt(max number) is around 32000 (considering both odd and even), finally 32000/2= 16,000 is the size of odd numbers list input_aray.
Finally total number range is divided into 3 regiions.
m and n both >= 32000 in this case the size of the input_aray is (n-m+1)/2 from 16001 index of array, numbers between m and n is stored (only odd numbers).
m and n <32000 in this case size of input_aray is upto n/2.
m <32000 and n>32000 in this case size of input_aray is (n-32000+1)/2.
Boolean array bol of same size as input_aray is kept to track which number is visited so that two number can't be considered twice.
for (int j = 1; j < 16001; j++) {
int flag = input_aray[j];
This loop choose n index from input_aray and check if there is any number in this array that is divisible, if so then same index of bol is initialized into false.
for (int k = j + flag; k <= 16000; k = k + flag)
This loop check for prime numbers upto 32000.
for (int k = 16001; k < input_aray.length; k++)
This one checks in between ** m and n** (when m&n >=32000)
*This is the fastest approach I could implement, but still get Time Limit Exceed. What could be the probable cause?
public static void main(String args[]){
Scanner take= new Scanner(System.in);
ArrayList<String> arrayList= new ArrayList<>();
int m,n;
int temp= take.nextInt();
take.nextLine();
if(temp>=0 && temp<=10){
for(int i=0;i<temp;i++) {
String temp1 = take.nextLine();
arrayList.add(temp1);
}
}
for(int i=0;i<arrayList.size();i++){
String[] temp_aray= arrayList.get(i).split(" ");
m= Integer.parseInt(temp_aray[0]);
n= Integer.parseInt(temp_aray[1]);
if(m>0 && n>0 && m<=10E8 && n<=10E8 && n-m<= 10E4 ) {
if (m >= 32000 && n >= 32000) {
//m & n > 32000
int start;
int[] input_aray = new int[16001 + ((n - m + 1) / 2) + 1];
boolean[] bol = new boolean[16001 + ((n - m + 1) / 2) + 1];
Arrays.fill(bol, true);
input_aray[0] = 2;
input_aray[1] = 3;
for (int j = 2; j < 16001; j++) {
input_aray[j] = input_aray[j - 1] + 2;
}
if (m % 2 == 0) {
start = m + 1;
} else {
start = m;
}
for (int j = 16001; j < input_aray.length; j++) {
input_aray[j] = start;
start += 2;
}
for (int j = 1; j < 16001; j++) {
int flag = input_aray[j];
for (int k = j + flag; k <= 16000; k = k + flag) {
if (input_aray[k] % flag == 0 && bol[k] == true) {
bol[k] = false;
}
}
for (int k = 16001; k < input_aray.length; k++) {
if (input_aray[k] % flag == 0) {
bol[k] = false;
}
}
}
int num = 1;
for (int j = 16001; j < bol.length; j++) {
if (bol[j] == true) {
System.out.println(input_aray[j]);
num++;
}
}
System.out.println();
}
if(m<32000 && n< 32000){
int[] input_aray = new int[(n/2)+1];
boolean[] bol = new boolean[(n/2)+1];
Arrays.fill(bol, true);
input_aray[0] = 2;
input_aray[1] = 3;
for (int j = 2; j < input_aray.length; j++) {
input_aray[j] = input_aray[j - 1] + 2;
}
for (int j = 1; j < Math.sqrt(n); j++) {
int flag = input_aray[j];
for (int k = j + flag; k<input_aray.length; k = k + flag) {
if (input_aray[k] % flag == 0 && bol[k] == true) {
bol[k] = false;
}
}
}
int num = 1;
for (int j = 0; j < bol.length; j++) {
if (bol[j] == true && input_aray[j] >=m && input_aray[j]<=n) {
System.out.println(input_aray[j]);
num++;
}
}
System.out.println();
}
if(m<32000 && n>32000){
int start;
int[] input_aray = new int[16001 + ((n - 32000 + 1) / 2) + 1];
boolean[] bol = new boolean[16001 + ((n - 32000 + 1) / 2) + 1];
Arrays.fill(bol, true);
input_aray[0] = 2;
input_aray[1] = 3;
for (int j = 2; j < 16001; j++) {
input_aray[j] = input_aray[j - 1] + 2;
}
start=32001;
for (int j = 16001; j < input_aray.length; j++) {
input_aray[j] = start;
start += 2;
}
for (int j = 1; j < 16001; j++) {
int flag = input_aray[j];
for (int k = j + flag; k <= 16000; k = k + flag) {
if (input_aray[k] % flag == 0 && bol[k] == true) {
bol[k] = false;
}
}
for (int k = 16001; k < input_aray.length; k++) {
if (input_aray[k] % flag == 0) {
bol[k] = false;
}
}
}
int num = 1;
for (int j = 0; j < bol.length; j++) {
if (bol[j] == true && input_aray[j]>=m && input_aray[j]<=n) {
System.out.println(input_aray[j]);
num++;
}
}
System.out.println();
}
}
}
}

How to remove trailing white spaces from System.out.println(); Java

This is my code:
import java.util.*;
public class Main {
public static void fill(char mat[][], int x, int y, char prevV, char currV) {
if (x < 0 || x >= mat.length || y < 0 || y >= mat.length)
return;
if (mat[x][y] != prevV)
return;
mat[x][y] = currV;
fill(mat, x + 1, y, prevV, currV);
fill(mat, x - 1, y, prevV, currV);
fill(mat, x, y + 1, prevV, currV);
fill(mat, x, y - 1, prevV, currV);
}
public static void replace(char mat[][]) {
for (int i = 0; i < mat.length; i++)
for (int j = 0; j < mat.length; j++)
if (mat[i][j] == 'O')
mat[i][j] = 'v';
for (int i = 0; i < mat.length; i++)
if (mat[i][0] == 'v')
fill(mat, i, 0, 'v', 'O');
for (int i = 0; i < mat.length; i++)
if (mat[i][mat.length - 1] == 'v')
fill(mat, i, mat.length - 1, 'v', 'O');
for (int i = 0; i < mat.length; i++)
if (mat[0][i] == 'v')
fill(mat, 0, i, 'v', 'O');
for (int i = 0; i <mat.length; i++)
if (mat[mat.length - 1][i] == 'v')
fill(mat, mat.length - 1, i, 'v', 'O');
for (int i = 0; i < mat.length; i++)
for (int j = 0; j < mat.length; j++)
if (mat[i][j] == 'v')
mat[i][j] = 'X';
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
char[][] mat = new char[n][m];
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
mat[i][j] = sc.next().charAt(0);
}
}
replace(mat);
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
System.out.print(mat[i][j] + " ");
}
System.out.println();
}
}
}
The part I am having issues with is the main method, specifically this part:
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
System.out.print(mat[i][j] + " ");
}
System.out.println();
}
My problem is at the end of each line there will be a white space because of the + " ".
How can I remove the white space at the end of each line
P.S. if this thread already exists, please link me to it because most of the whitespace solutions are with Strings and just using .trim();
Don't give the space character when its the end of the row.
You could write like this:
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (j < m - 1)
System.out.print(mat[i][j] + " ");
else
System.out.println(mat[i][j]);
}
}
Add a condition for output white space:
for (int j = 0; j < m; j++) {
System.out.print(mat[i][j]);
if (j < m - 1) {
System.out.print(" ");
}
}
besides the answer given, you can do this
for(int i = 0; i < n; i++) {
int j =0; //we move j outside so that it can be accessed later
for( ; j < m -1; j++) { //notice we skip the last entry of the row
System.out.print(mat[i][j] + " ");
}
System.out.println(mat[i][j]); //we add the last entry of the row here.
}
the advantage is that you don't need to do an if check every iteration and there's minimal changes to your current codes.

Sudoku count subfield

I am currently working on a SudokuChecker I want to check the subfields [3x3] of the sudoku. The following code does this:
int[][] field = new field[9][9];
int wrongNumbers = 0;
for (int i = 0; i < 9; i += 3) {
for (int j = 0; j < 9; j += 3) {
// Check subfield by using an array
int arr[] = new int[10];
for (int k = 0; k < 3; k++) {
for (int l = 0; l < 3; l++) {
arr[field[i + k][j + l]]++;
}
}
for (int k = 1; k < arr.length; k++) {
wrongNumbers += arr[k] > 1 ? arr[k] - 1 : 0;
}
}
}
I want to know are there any improvements for the given code?
(I am not talking about making the 3, 9, etc. constant)
I found a very good answer in Codefights from thucnguyen:
boolean sudoku(int[][] grid) {
for (int i = 0; i <9; i++) {
int row = 0, col = 0, group = 0;
for (int j = 0; j <9; j++) {
// check for row i
row += grid[i][j];
// check for col i
col += grid[j][i];
// check for sub-grid i
group += grid[i / 3 * 3 + j / 3][i % 3 * 3 + j % 3];
}
if (row != 45 || col != 45 || group != 45) return false;
}
return true;
}

Categories

Resources