Dining Philosopher's Solution needed - java

I'm stuck on implementing a solution in Java for Dining Philosopher's problem.
The error I'm getting is
"Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
at Main.main(Main.java:43)"
That line 43 is:
rFork = forks[forI + 1];
and is within the for loop below
for (int i = 0; i < phiNum; i++)
{
list[i] = new Philosopher(forks[i], forks[(i + 1) % phiNum],
i, in.nextFloat());
for (int forI = 0; forI < (phiNum); forI++)
{
lFork = forks[forI];
rFork = forks[forI + 1];
}
}
Below is the rest of my code for the Main.java class:
import java.util.*;
public class Main
{
static Scanner in = new Scanner(System.in);
public static void main(String[] args)
{
int phiNum = 0, maxForks = 2;
float time = 0;
System.out.print("Enter the number of Philosophers: ");
phiNum = in.nextInt();
//float timeSpentThinking = in.nextFloat();
Philosopher[] list = new Philosopher[phiNum];
Fork[] forks = new Fork [phiNum];
Fork lFork = new Fork();
Fork rFork = new Fork();
if (phiNum == 0)
System.out.println("There are no philosophers eating or
thinking.");
else if (phiNum == 1)
System.out.println("There are not enough forks for the
philosopher" + " to eat.");
else
{
for (int index = 0; index < (phiNum); index++)
forks[index] = new Fork();
for (int i = 0; i < phiNum; i++)
{
list[i] = new Philosopher(forks[i], forks[(i + 1) % phiNum],
i, in.nextFloat());
for (int forI = 0; forI < (phiNum); forI++)
{
lFork = forks[forI];
rFork = forks[forI + 1];
}
}
}
for (int i = 1; i < list.length; i++)
list[i].run();
}
}

You declare this variable:
forNum = 0;
And use it to declare the array:
Fork[] forks = new Fork [forNum];
So the array is empty, so trying to access it gives you the error. You would have to either give the variable forNum a value other than zero, or ask the user to enter the number of forks:
System.out.print("Enter the number of forks: ");
forNum = in.nextInt();
Learning to use a debugger would have helped you to see that the array was of size zero.

Related

How can I sum these two arrays into a new one?

How can I sum these two arrays into a new one? Where the first value of the arrayA sums the first value of the arrayB?
public class Exercises {
static BufferedReader in = new BufferedReader(
new InputStreamReader(System.in));
static PrintStream out = System.out;
public static void main(String[] args) throws IOException {
int numbersA[] = new int[5];
int numbersB[] = new int[5];
int numbersC[] = new int[5];
for (int i = 0; i < 5; i++) {
out.print("Please insert a number for the first array: ");
numbersA[i] = Integer.parseInt(in.readLine());
}
for (int i = 0; i < 5; i++) {
out.print("Please insert a number for the second array: ");
numbersB[i] = Integer.parseInt(in.readLine());
}
int j = 0;
for (int i = 0; i < 5; i++) {
numbersC[j] = (numbersA.length[i] + numbersB.length[i]);
}
{
out.print("The sum of the two arrays are: " + numbersC[j] + " ");
}
out.println();
}
}
You were pretty close. numbersA[i] and numbersB[i] (not the length of each array). Also, you don't need j and should print the prelude before the loop. Like,
out.print("The sum of the two arrays are: ");
for (int i = 0; i < 5; i++) {
numbersC[i] = numbersA[i] + numbersB[i];
out.print(numbersC[i] + " ");
}
out.println();
Finally, your code relies on magic numbers (hard coded array lengths). That is bad practice, instead you should use the array.length so your code doesn't require changing when your array sizes change. Like,
int[] numbersA = new int[5];
int[] numbersB = new int[5];
for (int i = 0; i < numbersA.length; i++) {
out.print("Please insert a number for the first array: ");
numbersA[i] = Integer.parseInt(in.readLine());
}
for (int i = 0; i < numbersB.length; i++) {
out.print("Please insert a number for the second array: ");
numbersB[i] = Integer.parseInt(in.readLine());
}
int[] numbersC = new int[Math.min(numbersA.length, numbersB.length)];
out.print("The sum of the two arrays are: ");
for (int i = 0; i < numbersC.length; i++) {
numbersC[i] = numbersA[i] + numbersB[i];
out.print(numbersC[i] + " ");
}
out.println();
try to delete the numbersC[j] = (numbersA.length[i] + numbersB.length[i]);
length from both
use this shape
numbersC[i] = numbersA[i] + numbersB[i];
i think it will be work now

Extract numbers from a array and divide them (positives and negatives) into separate arrays

I want to extract numbers from an array and divide them into positives and negatives into separate arrays. Why does my Java code does not work?
How to make it work?
int pole[] = new int[20];
int pock = 0;
int pocz = 0;
int pocn = 0;
for (int i = 0; i < pole.length; i++) {
pole[i] = (int)(-10+Math.random()*21);
}
for (int i = 0; i < 10; i++) {
if(pole[i]>0)pock++;
else if(pole[i]<0) pocz++;
else pocn++;
}
int pklad[] = new int[pock];
int pzap[] = new int [pocz];
int n[] = new int [pocn];
int j = 0;
for (int i = 0; i < pole.length; i++) {
if(pole[i]>0){
pklad[j] = pole[i];
}if(pole[i]<0){
pzap[j] = pole[i];
}else n[j]=pole[i];
j++;
}
System.out.print("All positives: ");
for (int i = 0; i < pock; i++) {
System.out.print(pklad[i]+",");
}
System.out.println();
System.out.print("All negatives: ");
for (int i = 0; i < pocz; i++) {
System.out.println(pzap[i]);
}
System.out.print("Zeros: ");
for (int i = 0; i < pocn; i++) {
System.out.println(n[i]);
}
Edit: This throws an exception: (thanks, BRjava)
ArrayIndexOutOfBoundsException, line 36
Use the ArrayList it is better than normal arrays.
public static void main(String[] args) {
ArrayList<Double> yourNumbers = new ArrayList<Double>();
yourNumbers.add(54.2); //add some number to our array
yourNumbers.add(-67.7);
ArrayList<Double> positive = new ArrayList<>();
ArrayList<Double> negative = new ArrayList<>();
for(Double currentNumber : yourNumbers) {
if(currentNumber >= 0) {
positive.add(currentNumber);
}else if(currentNumber <0) {
negative.add(currentNumber);
}
}
//print all positive numbers
for(Double currentDouble : positive) {
System.out.println("Positive: "+currentDouble);
}
//print all negative numbers
for(Double currentDouble : negative) {
System.out.println("Negative: "+currentDouble);
}
}
The problem is that you have three arrays, pklad[], pzap[], and n[], but you try using a single index j to write to all three. This is what is causing your ArrayIndexOutOfBoundsException: as soon as j goes past the limit of the shorter of the arrays, an attempted write causes the exception.
You need three separate indexes, say, jpos, jneg, and jn, all initialized to zero before the loop. Each index needs to be incremented individually when you write to its corresponding array:
for (int i = 0; i < pole.length; i++) {
if (pole[i] > 0) {
pklad[jpos++] = pole[i];
} else if (pole[i] < 0) {
pzap[jneg++] = pole[i];
} else {
n[jn++]=pole[i];
}
}

Java: methods using array variables

So I made this code using various snippets on the web so that I could see how it all works, But For some strange reason the 4th "For" loop is skipped entirely, And I'm not sure why. Any help would be appreciated. It is a command line using code.
public class New1
{
public static void main(String[] args) throws InterruptedException
{
Scanner in = new Scanner(System.in);
System.out.print("Enter number of clicks before repeat: ");
int Clicks = in.nextInt();
int rep2 = 0;
int Waits[] = new int[Clicks];
Clicks = Clicks * 2;
int Coords[] = new int[Clicks];
Clicks = Clicks / 2;
int Gung;
int Ho;
int Yo;
int xco = 0;
int yco = 1;
if(Clicks > 0)
{
for (int rep = 0; rep < Coords.length; rep++)
{
System.out.print("Enter x coord: ");
Coords[rep] = in.nextInt();
rep++;
System.out.println(" ");
System.out.print("Enter y coord: ");
Coords[rep] = in.nextInt();
System.out.println(" ");
System.out.print("Enter the pause (In seconds) between this click and the next click: ");
Waits[rep2] = in.nextInt();
rep2++;
System.out.println(" ");
}
rep2 = 0;
for (int rep3 = 0; rep3 < Waits.length; rep3++)
{
Waits[rep3] = Waits[rep3] * 1000;
}
System.out.print("How many times to repeat click sequence? : ");
int Revolutions = in.nextInt();
for (int counter = 0; counter > Revolutions; counter++)
{
for (int Flicks = 0; Flicks > Clicks; Flicks++)
{
Gung = Coords[xco];
Ho = Coords[yco];
Yo = Waits[Flicks];
Click(Gung, Ho);
Thread.sleep(Yo);
xco += 2;
yco += 2;
}
xco = 0;
yco = 1;
}
}
}
public static void Click(int x, int y)
{
Robot bot = null;
try
{
bot = new Robot();
}
catch (Exception failed)
{
System.err.println("Failed instantiating Robot: " + failed);
}
int mask = InputEvent.BUTTON1_DOWN_MASK;
bot.mouseMove(x, y);
bot.mousePress(mask);
bot.mouseRelease(mask);
}
public static void printArray(int arr[])
{
int n = arr.length;
for (int ar = 0; ar < n; ar++)
{
System.out.print(arr[ar] + " ");
}
System.out.println(" ");
}
}
Edit: The 4th "For" loop is
for (int Flicks = 0; Flicks > Clicks; Flicks++)
{
Gung = Coords[xco];
Ho = Coords[yco];
Yo = Waits[Flicks];
Click(Gung, Ho);
Thread.sleep(Yo);
xco += 2;
yco += 2;
}
The fourth for loop is:
public static void printArray(int arr[])
{
int n = arr.length;
for (int ar = 0; ar < n; ar++)
{
System.out.print(arr[ar] + " ");
}
System.out.println(" ");
}
As you can see it is inside a method called printArray(). There is nothing wrong with the array. It is just fine. The problem is that the method is never called thus the for loop never runs.
Here is a java methods tutorial.
//first way
System.out.println(Arrays.toString(arr));
//second way
for(int i : arr) {
System.out.print(i + " ");
}
//third way
for(int i = 0; i < arr.length; ++i) {
System.out.print(arr[i] + " ");
}
There three basic ways to print all elements in array. Advice: you should avoid using static methods, it is wrong in your case.
New1 task = new New1();
task.doSomething();

How can I get the longest increasing subsequence in a string?

I'm pretty rusty on my Java skills but I was trying to write a program that prompts the user to enter a string and displays a maximum length increasing ordered subsequence of characters. For example, if the user entered Welcome the program would output Welo. If the user entered WWWWelllcommmeee, the program would still output Welo. I've gotten this much done but it's not doing what it should be and I'm honestly at a loss as to why.
import java.util.ArrayList;
import java.util.Scanner;
public class Stuff {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Please enter a string. ");
String userString = input.next();
ArrayList charList = new ArrayList();
ArrayList finalList = new ArrayList();
int currentLength = 0;
int max = 0;
for(int i = 0; i < userString.length(); i++){
charList.add(userString.charAt(i));
for(int j = i; j < userString.length(); j++){
int k=j+1;
if(k < userString.length() && userString.charAt(k) > userString.charAt(j)){
charList.add(userString.charAt(j));
currentLength++;
}
}
}
if(max < currentLength){
max = currentLength;
finalList.addAll(charList);
}
for (int i = 0; i < finalList.size(); i++){
char item = (char) finalList.get(i);
System.out.print(item);
}
int size1 = charList.size();
int size2 = finalList.size();
System.out.println("");
System.out.println("Size 1 is: " + size1 + " Size 2 is : " + size2);
}
}
My code, if I input Welcome, outputs WWeceeclcccome.
Does anyone have some tips on what I'm doing wrong?
In these cases it tends to help to step away from the keyboard and think about the algorithm you're trying to implement. Try to explain it first in words.
You are constructing a list of individual characters by appending each of the characters in the input string followed by characters to its right that are in correct alphabetical with their successor. For the input "Welcome" this means the accumulated output will be, showing the outer loop in vertical and inner loop in horizontal:
W W e c
e e c
l c
c c
o
m
e
In total: WWeceeclccome
I can't see the logic of this implementation. Here is a faster solution which runs in O(nlogn) time.
import java.util.Scanner;
public class Stuff
{
//return the index of the first element that's not less than the target element
public static int bsearch(char[] arr, int size, int key)
{
int left = 0;
int right = size - 1;
int mid;
while (left <= right)
{
mid = (left + right) / 2;
if(arr[mid] < key)
left = mid + 1;
else
right = mid - 1;
}
return left;
}
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
System.out.println("Please enter a string: ");
String userString = input.next();
char[] maxArr = new char[userString.length()];
char[] precedent = new char[userString.length()];
maxArr[0] = userString.charAt(0);
precedent[0] = userString.charAt(0);
int len = 1;
for(int i = 1; i < userString.length(); i++)
{
if(userString.charAt(i) > maxArr[len - 1])
{
maxArr[len] = userString.charAt(i);
precedent[len] = userString.charAt(i);
len++;
}
else
maxArr[bsearch(maxArr, len, userString.charAt(i))] = userString.charAt(i);
}
//System.out.println(len);
for(int i = 0; i < len; i++)
System.out.print(precedent[i]);
}
}
Using Dynamic Programming O(N^2) in lexicography order mean if i/p is abcbcbcd then o/p can be abcccd, abbbcd, abbccd but as per lexicography order o/p will be abbbcd.
public static String longestIncreasingSubsequence(String input1) {
int dp[] = new int[input1.length()];
int i,j,max = 0;
StringBuilder str = new StringBuilder();
/* Initialize LIS values for all indexes */
for ( i = 0; i < input1.length(); i++ )
dp[i] = 1;
/* Compute optimized LIS values in bottom up manner */
for ( i = 1; i < input1.length(); i++ )
for ( j = 0; j < i; j++ )
if (input1.charAt(i) >= input1.charAt(j) && dp[i] < dp[j]+1)
dp[i] = dp[j] + 1;
/* Pick maximum of all LIS values */
for ( i = 0; i < input1.length(); i++ ) {
if ( max < dp[i] ) {
max = dp[i];
if (i + 1 < input1.length() && max == dp[i+1] && input1.charAt(i+1) < input1.charAt(i)) {
str.append(input1.charAt(i+1));
i++;
} else {
str.append(input1.charAt(i));
}
}
}
return str.toString();
}

Java Sudoku Generator(easiest solution)

In my last question seen here: Sudoku - Region testing I asked how to check the 3x3 regions and someone was able to give me a satisfactory answer (although it involved a LOT of tinkering to get it working how I wanted to, since they didn't mention what the class table_t was.)
I finished the project and was able to create a sudoku generator, but it feels like it's contrived. And I feel like I've somehow overcomplicated things by taking a very brute-force approach to generating the puzzles.
Essentially my goal is to create a 9x9 grid with 9- 3x3 regions. Each row / col / region must use the numbers 1-9 only once.
The way that I went about solving this was by using a 2-dimensional array to place numbers at random, 3 rows at a time. Once the 3 rows were done it would check the 3 rows, and 3 regions and each vertical col up to the 3rd position. As it iterated through it would do the same until the array was filled, but due to the fact that I was filling with rand, and checking each row / column / region multiple times it felt very inefficient.
Is there an "easier" way to go about doing this with any type of data construct aside from a 2d array? Is there an easier way to check each 3x3 region that might coincide with checking either vert or horizontal better? From a standpoint of computation I can't see too many ways to do it more efficiently without swelling the size of the code dramatically.
I built a sudoku game a while ago and used the dancing links algorithm by Donald Knuth to generate the puzzles. I found these sites very helpful in learning and implementing the algorithm
http://en.wikipedia.org/wiki/Dancing_Links
http://cgi.cse.unsw.edu.au/~xche635/dlx_sodoku/
http://garethrees.org/2007/06/10/zendoku-generation/
import java.util.Random;
import java.util.Scanner;
public class sudoku {
/**
* #antony
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int p = 1;
Random r = new Random();
int i1=r.nextInt(8);
int firstval = i1;
while (p == 1) {
int x = firstval, v = 1;
int a[][] = new int[9][9];
int b[][] = new int[9][9];
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if ((x + j + v) <= 9)
a[i][j] = j + x + v;
else
a[i][j] = j + x + v - 9;
if (a[i][j] == 10)
a[i][j] = 1;
// System.out.print(a[i][j]+" ");
}
x += 3;
if (x >= 9)
x = x - 9;
// System.out.println();
if (i == 2) {
v = 2;
x = firstval;
}
if (i == 5) {
v = 3;
x = firstval;
}
}
int eorh;
Scanner in = new Scanner(System.in);
System.out
.println("hey lets play a game of sudoku:take down the question and replace the 0's with your digits and complete the game by re entering your answer");
System.out.println("enter your option 1.hard 2.easy");
eorh = in.nextInt();
switch (eorh) {
case 1:
b[0][0] = a[0][0];
b[8][8] = a[8][8];
b[0][3] = a[0][3];
b[0][4] = a[0][4];
b[1][2] = a[1][2];
b[1][3] = a[1][3];
b[1][6] = a[1][6];
b[1][7] = a[1][7];
b[2][0] = a[2][0];
b[2][4] = a[2][4];
b[2][8] = a[2][8];
b[3][2] = a[3][2];
b[3][8] = a[3][8];
b[4][2] = a[4][2];
b[4][3] = a[4][3];
b[4][5] = a[4][5];
b[4][6] = a[4][6];
b[5][0] = a[5][0];
b[5][6] = a[5][6];
b[6][0] = a[6][0];
b[6][4] = a[6][4];
b[6][8] = a[6][8];
b[7][1] = a[7][1];
b[7][2] = a[7][2];
b[7][5] = a[7][5];
b[7][6] = a[7][6];
b[8][4] = a[8][4];
b[8][5] = a[8][5];
b[0][0] = a[0][0];
b[8][8] = a[8][8];
break;
case 2:
b[0][3] = a[0][3];
b[0][4] = a[0][4];
b[1][2] = a[1][2];
b[1][3] = a[1][3];
b[1][6] = a[1][6];
b[1][7] = a[1][7];
b[1][8] = a[1][8];
b[2][0] = a[2][0];
b[2][4] = a[2][4];
b[2][8] = a[2][8];
b[3][2] = a[3][2];
b[3][5] = a[3][5];
b[3][8] = a[3][8];
b[4][0] = a[4][0];
b[4][2] = a[4][2];
b[4][3] = a[4][3];
b[4][4] = a[4][4];
b[4][5] = a[4][5];
b[4][6] = a[4][6];
b[5][0] = a[5][0];
b[5][1] = a[5][1];
b[5][4] = a[5][4];
b[5][6] = a[5][6];
b[6][0] = a[6][0];
b[6][4] = a[6][4];
b[6][6] = a[6][6];
b[6][8] = a[6][8];
b[7][0] = a[7][0];
b[7][1] = a[7][1];
b[7][2] = a[7][2];
b[7][5] = a[7][5];
b[7][6] = a[7][6];
b[8][2] = a[8][2];
b[8][4] = a[8][4];
b[8][5] = a[8][5];
break;
default:
System.out.println("entered option is incorrect");
break;
}
for (int y = 0; y < 9; y++) {
for (int z = 0; z < 9; z++) {
System.out.print(b[y][z] + " ");
}
System.out.println("");
}
System.out.println("enter your answer");
int c[][] = new int[9][9];
for (int y = 0; y < 9; y++) {
for (int z = 0; z < 9; z++) {
c[y][z] = in.nextInt();
}
}
for (int y = 0; y < 9; y++) {
for (int z = 0; z < 9; z++)
System.out.print(c[y][z] + " ");
System.out.println();
}
int q = 0;
for (int y = 0; y < 9; y++) {
for (int z = 0; z < 9; z++)
if (a[y][z] == c[y][z])
continue;
else {
q++;
break;
}
}
if (q == 0)
System.out
.println("the answer you have entered is correct well done");
else
System.out.println("oh wrong answer better luck next time");
System.out
.println("do you want to play a different game of sudoku(1/0)");
p = in.nextInt();
firstval=r.nextInt(8);
/*if (firstval > 8)
firstval -= 9;*/
}
}
}
I think you can use a 1D array, in much the same way a 1D array can model a binary tree. For example, to look at the value below a number, add 9 to the index.
I just made this up, but could something like this work?
private boolean makePuzzle(int [] puzzle, int i)
{
for (int x = 0; x< 10 ; x++)
{
if (//x satisfies all three conditions for the current square i)
{
puzzle[i]=x;
if (i==80) return true //terminal condition, x fits in the last square
else
if makePuzzle(puzzle, i++);//find the next x
return true;
}// even though x fit in this square, an x couldn't be
// found for some future square, try again with a new x
}
return false; //no value for x fit in the current square
}
public static void main(String[] args )
{
int[] puzzle = new int[80];
makePuzzle(puzzle,0);
// print out puzzle here
}
Edit: its been a while since I've used arrays in Java, sorry if I screwed up any syntax. Please consider it pseudo code :)
Here is the code as described below in my comment.
public class Sudoku
{
public int[] puzzle = new int[81];
private void makePuzzle(int[] puzzle, int i)
{
for (int x = 1; x< 10 ; x++)
{
puzzle[i]=x;
if(checkConstraints(puzzle))
{
if (i==80)//terminal condition
{
System.out.println(this);//print out the completed puzzle
puzzle[i]=0;
return;
}
else
makePuzzle(puzzle,i+1);//find a number for the next square
}
puzzle[i]=0;//this try didn't work, delete the evidence
}
}
private boolean checkConstraints(int[] puzzle)
{
int test;
//test that rows have unique values
for (int column=0; column<9; column++)
{
for (int row=0; row<9; row++)
{
test=puzzle[row+column*9];
for (int j=0;j<9;j++)
{
if(test!=0&& row!=j&&test==puzzle[j+column*9])
return false;
}
}
}
//test that columns have unique values
for (int column=0; column<9; column++)
{
for(int row=0; row<9; row++)
{
test=puzzle[column+row*9];
for (int j=0;j<9;j++)
{
if(test!=0&&row!=j&&test==puzzle[column+j*9])
return false;
}
}
}
//implement region test here
int[][] regions = new int[9][9];
int[] regionIndex ={0,3,6,27,30,33,54,57,60};
for (int region=0; region<9;region++) //for each region
{
int j =0;
for (int k=regionIndex[region];k<regionIndex[region]+27; k=(k%3==2?k+7:k+1))
{
regions[region][j]=puzzle[k];
j++;
}
}
for (int i=0;i<9;i++)//region counter
{
for (int j=0;j<9;j++)
{
for (int k=0;k<9;k++)
{
if (regions[i][j]!=0&&j!=k&&regions[i][j]==regions[i][k])
return false;
}
}
}
return true;
}
public String toString()
{
String string= "";
for (int i=0; i <9;i++)
{
for (int j = 0; j<9;j++)
{
string = string+puzzle[i*9+j];
}
string =string +"\n";
}
return string;
}
public static void main(String[] args)
{
Sudoku sudoku=new Sudoku();
sudoku.makePuzzle(sudoku.puzzle, 0);
}
}
Try this code:
package com;
public class Suduku{
public static void main(String[] args ){
int k=0;
int fillCount =1;
int subGrid=1;
int N=3;
int[][] a=new int[N*N][N*N];
for (int i=0;i<N*N;i++){
if(k==N){
k=1;
subGrid++;
fillCount=subGrid;
}else{
k++;
if(i!=0)
fillCount=fillCount+N;
}
for(int j=0;j<N*N;j++){
if(fillCount==N*N){
a[i][j]=fillCount;
fillCount=1;
System.out.print(" "+a[i][j]);
}else{
a[i][j]=fillCount++;
System.out.print(" "+a[i][j]);
}
}
System.out.println();
}
}
}

Categories