Cant get required output from loop - java

I am trying to get a certain output pattern from the array but can't seem to get what I'm looking for and now sure why. Link is the desired output. Sorry if formatting is not good. Array size is inputted by the user.
public class A3_Q2 {
int [][] pattern2 = new int[arraySize][arraySize];
number = 1;
int i;
int j;
int newNumber = arraySize-1;
for (i = 0; i < arraySize; i++)
{
if (i == 0)
{
for (j = 0; j < arraySize; j++)
{
pattern2[i][j] = number;
System.out.printf("%3d", pattern2[i][j]);
number++;
}
}
else
{
for(j = 0; j < i; j++)
{
pattern2[i][j] = number + newNumber;
System.out.printf("%3d", pattern2[i][j]);
newNumber++;
}
newNumber = arraySize-1;
while(j < arraySize)
{
pattern2[i][j] = number;
System.out.printf("%3d", pattern2[i][j]);
number++;
j++;
}
}
System.out.println("");
}
Desired Output:
1 2 3 4 5
10 6 7 8 9
14 15 11 12 13
18 19 20 16 17
22 23 24 25 21
This image shows the out-of-sequence cells highlighted:

There is no need to separately handle specific rows. Value should be calculated with formula that can be applied universally using modulo operator.
This should do the trick:
for (i = 0; i < arraySize; i++) {
for (j = 0; j < arraySize; j++) {
int value = i * arraySize + (j - i + arraySize + 1) % arraySize;
if (value % arraySize == 0) {
value += arraySize;
}
pattern2[i][j] = value;
System.out.printf("%3d", pattern2[i][j]);
}
System.out.println("");
}

As I suggested in my comment, you're trying to do too many things at once, and that makes the logic (and logic errors) very hard to see.
Breaking each part into its own method can make things much easier.
All those loops and conditionals hid that there were only three tasks required:
Create grid.
Fill grid.
Print grid.
public static void main(final String[] args) {
final int arraySize = 5;
int[][] pattern = new int[arraySize][arraySize];
fillPattern(pattern);
printPattern(pattern);
return;
}
That weird non-sequential output means that "fill the grid" is actually too big a task for one method.
Filling a grid normally requires filling each row.
This grid also requires rotating each row's values one to the right...
one more than the previous row, that is.
That has nothing to do with filling a grid with rows, so it's some other method's problem.
(I could have foisted rowStartValue off onto the other method too, come to think of it.)
private static void fillPattern(int[][] pattern) {
final int rowCount = pattern.length;
for (int rowOffset = 0; rowOffset < rowCount; rowOffset++) {
final int[] row = pattern[rowOffset];
// Numbers in grid start at 1, not 0.
final int rowStartValue = rowOffset * row.length + 1;
fillRow(row, rowOffset, rowStartValue);
}
return;
}
fillRow has to produce values and stuff them into row.
Producing the values is easy;
the only tricky part is deciding where to put them.
Picking the destination required only two operators, so I did it here.
Since no one wants to figure out what row[some / weird * math % here] means, I gave the calculation a name by saving it as the rowIndex variable.
If it had been any more complex, I would have moved the work to a rowIndex(...) method instead.
private static void fillRow(int[] row, final int offset, final int value) {
for (int addend = 0; addend < row.length; addend++) {
final int rowIndex = (offset + addend) % row.length;
row[rowIndex] = value + addend;
}
return;
}
Now that the grid is full, printing it is easy:
private static void printPattern(final int[][] pattern) {
for (final int[] row : pattern) {
for (final int element : row) {
System.out.printf("%3d", element);
}
System.out.println();
}
return;
}
Replacing variables like i and j with row and offset helped a lot, too.

Related

Calculate factorial of 50 using array only in java

I'm a total beginner of java.
I have a homework to write a complete program that calculates the factorial of 50 using array.
I can't use any method like biginteger.
I can only use array because my professor wants us to understand the logic behind, I guess...
However, he didn't really teach us the detail of array, so I'm really confused here.
Basically, I'm trying to divide the big number and put it into array slot. So if the first array gets 235, I can divide it and extract the number and put it into one array slot. Then, put the remain next array slot. And repeat the process until I get the result (which is factorial of 50, and it's a huge number..)
I tried to understand what's the logic behind, but I really can't figure it out.. So far I have this on my mind.
import java.util.Scanner;
class Factorial
{
public static void main(String[] args)
{
int n;
Scanner kb = new Scanner(System.in);
System.out.println("Enter n");
n = kb.nextInt();
System.out.println(n +"! = " + fact(n));
}
public static int fact(int n)
{
int product = 1;
int[] a = new int[100];
a[0] = 1;
for (int j = 2; j < a.length; j++)
{
for(; n >= 1; n--)
{
product = product * n;
a[j-1] = n;
a[j] = a[j]/10;
a[j+1] = a[j]%10;
}
}
return product;
}
}
But it doesn't show me the factorial of 50.
it shows me 0 as the result, so apparently, it's not working.
I'm trying to use one method (fact()), but I'm not sure that's the right way to do.
My professor mentioned about using operator / and % to assign the number to the next slot of array repeatedly.
So I'm trying to use that for this homework.
Does anyone have an idea for this homework?
Please help me!
And sorry for the confusing instruction... I'm confused also, so please forgive me.
FYI: factorial of 50 is 30414093201713378043612608166064768844377641568960512000000000000
Try this.
static int[] fact(int n) {
int[] r = new int[100];
r[0] = 1;
for (int i = 1; i <= n; ++i) {
int carry = 0;
for (int j = 0; j < r.length; ++j) {
int x = r[j] * i + carry;
r[j] = x % 10;
carry = x / 10;
}
}
return r;
}
and
int[] result = fact(50);
int i = result.length - 1;
while (i > 0 && result[i] == 0)
--i;
while (i >= 0)
System.out.print(result[i--]);
System.out.println();
// -> 30414093201713378043612608166064768844377641568960512000000000000
Her's my result:
50 factorial - 30414093201713378043612608166064768844377641568960512000000000000
And here's the code. I hard coded an array of 100 digits. When printing, I skip the leading zeroes.
public class FactorialArray {
public static void main(String[] args) {
int n = 50;
System.out.print(n + " factorial - ");
int[] result = factorial(n);
boolean firstDigit = false;
for (int digit : result) {
if (digit > 0) {
firstDigit = true;
}
if (firstDigit) {
System.out.print(digit);
}
}
System.out.println();
}
private static int[] factorial(int n) {
int[] r = new int[100];
r[r.length - 1] = 1;
for (int i = 1; i <= n; i++) {
int carry = 0;
for (int j = r.length - 1; j >= 0; j--) {
int x = r[j] * i + carry;
r[j] = x % 10;
carry = x / 10;
}
}
return r;
}
}
How about:
public static BigInteger p(int numOfAllPerson) {
if (numOfAllPerson < 0) {
throw new IllegalArgumentException();
}
if (numOfAllPerson == 0) {
return BigInteger.ONE;
}
BigInteger retBigInt = BigInteger.ONE;
for (; numOfAllPerson > 0; numOfAllPerson--) {
retBigInt = retBigInt.multiply(BigInteger.valueOf(numOfAllPerson));
}
return retBigInt;
}
Please recall basic level of math how multiplication works?
2344
X 34
= (2344*4)*10^0 + (2344*3)*10^1 = ans
2344
X334
= (2344*4)*10^0 + (2344*3)*10^1 + (2344*3)*10^2= ans
So for m digits X n digits you need n list of string array.
Each time you multiply each digits with m. and store it.
After each step you will append 0,1,2,n-1 trailing zero(s) to that string.
Finally, sum all of n listed string. You know how to do that.
So up to this you know m*n
now it is very easy to compute 1*..........*49*50.
how about:
int[] arrayOfFifty = new int[50];
//populate the array with 1 to 50
for(int i = 1; i < 51; i++){
arrayOfFifty[i-1] = i;
}
//perform the factorial
long result = 1;
for(int i = 0; i < arrayOfFifty.length; i++){
result = arrayOfFifty[i] * result;
}
Did not test this. No idea how big the number is and if it would cause error due to the size of the number.
Updated. arrays use ".length" to measure the size.
I now updated result to long data type and it returns the following - which is obviously incorrect. This is a massive number and I'm not sure what your professor is trying to get at.
-3258495067890909184

How do I trim the leading zeros in an array of digits without using an arraylist in java?

I have an array made that represents digits and I am trying to make a method so that if there are zeros in front of the first significant digit I want to trim them, I understand you can't re size arrays so I have created a new array, but my code doesn't seem to run correctly?
Here is my code I can't figure out what is wrong I've tried everything: (I put stars around the error** It gives an arrayoutofbounds error **)
package music;
import java.util.Random;
/**Music Array
*
* #author Ryan Klotz
* #version February 3, 2015
*/
public class Music
{
private int length; // length of the array
private int numOfDigits; // number of actual digits in the array
int[] musicArray;
/**Explicit Constructor
* #param x The length of the array
*/
public Music(int x)
{
length = x;
musicArray = new int[length];
Random rand = new Random();
numOfDigits = rand.nextInt(length);
int posOrNeg; // determines positive or negative sign
int digit;
for (int i = 0; i <= numOfDigits; i++)
{
digit = rand.nextInt(10);
posOrNeg = rand.nextInt(2);
if (posOrNeg == 0)
{
digit *= -1;
musicArray[i] = digit;
}
else
{
musicArray[i] = digit;
}
}
}
public void trimLeadingSilence(Music x)
{
while (x.musicArray[0] == 0)
{
int[] newMusicArray;
int count = 0;
**while (x.musicArray[count] == 0)**
{
count++;
}
if (count == x.numOfDigits)
{
newMusicArray = new int[1];
newMusicArray[0] = 0;
x.numOfDigits = 1;
x.musicArray = newMusicArray;
}
else
{
newMusicArray = new int[x.numOfDigits - count];
for (int i = 0; i <= x.numOfDigits - count; i++)
{
newMusicArray[i] = x.musicArray[i + count];
}
x.numOfDigits -= count;
x.musicArray = newMusicArray;
}
}
}
}
i <= x.numOfDigits - count should use < instead. But Arrays.copyOfRange is probably a better solution.
for (int i = 0; i <= numOfDigits; i++)
Should be
for (int i = 0; i < numOfDigits; i++)
Currently you are generating 1 more digit than numOfDigits is. This will not give you any exceptions in any case since randInt(length) will be in range of 0 and length - 1.
while (x.musicArray[count] == 0)
{
count++;
}
Will throw an exception if all values in array are 0.
while (count < x.musicArray.length && x.musicArray[count] == 0){
count++;
}
Will fix that for you.
for (int i = 0; i <= x.numOfDigits - count; i++)
Will also throw you ArrayIndexOutOfBoundsException so you should fix it to:
for (int i = 0; i < x.numOfDigits - count; i++)
Anyway, this is very inefficient since if you have 10 "0" values at the start you are creating 10 new arrays. Take a look at Arrays.copyOfRange method, you should be able to do the same job in less than 10 lines of code.
Inside your for loop, use i < x.numOfDigits - count (you were using <=).
That will solve the problem.

Java pyramid of numbers - version 2

I'm reading a book and before I go to next chapter, I want to solve every exercise from current one. I have a problem with creating this output (the number of rows must be between 11 and 20)
I almost have it, even when I think my code is pretty bad and I could get it in less lines.
public class piramide {
public static void main(String args[]){
int max, n;
max = 20;
n=1;
for (int min=11; min<=max; min++){
if (n>9) n-=10;
int x=n-1;
int x2=n-1;
int b=min-1;
for (int j=1; j<min; j++){
while (b<max-1) {
System.out.print(" ");
b++;
}
System.out.print(x);
x--;
if (x<0) x=9;
}
System.out.print("A"+n+"A");
for (int j=1; j<min; j++){
System.out.print(x2);
x2--;
if (x2<0) x2=9;
}
System.out.println();
n+=2;
}
}
}
This is my current code and this is the output:
0987654321A1A0987654321
21098765432A3A21098765432
432109876543A5A432109876543
6543210987654A7A6543210987654
87654321098765A9A87654321098765
098765432109876A1A098765432109876
2109876543210987A3A2109876543210987
43210987654321098A5A43210987654321098
654321098765432109A7A654321098765432109
8765432109876543210A9A8765432109876543210
The problem I'm having is that the left part of the pyramid should be reversed. For example in the first row it should start at 0 (from the A1A) and finish in 1 but it starts in 1 and finish in 0, any idea how can I turn it to the other side?
Thanks to all of you who helped me ^^.
Oh, and the caps A are just so I could find the number easier in the output.
Have you worked the problem out?
The code will be much easier to understand with a couple changes...
max, min, and especially the single letter variables like n should have names that help describe what they are. This may also help you think about the problem when you don't have to keep in mind what all those random letters mean.
n I will rename to rowIndex
max I will rename to totalRows
min I will rename to columnIndex
Starting with that we have
public static void main(String args[])
{
int totalRows = 20;
int rowIndex = 1;
int columnIndex = 1;
//we look ready to start at row 1, column 1!
}
Now, this section of your code:
for (int min=11; min<=max; min++){
if (n>9) n-=10;
int x=n-1;
int x2=n-1;
int b=min-1;
for (int j=1; j<min; j++){
while (b<max-1) {
System.out.print(" ");
b++;
}
You are setting min, or, the columnIndex, to start at 11, because that is the "middle" of the pyramid. Then you print out spaces to catch up to the columnIndex.
x = rowIndex - 1;
x2 = rowIndex - 1;
b = columnIndex - 1;
j and b are now like a second and third column index, which is catching up to the actual columnIndex
Look at this example of how your for loop works:
for (int j=1; j <min; j++) { // j = 1;
while (b<max-1) { // 10 < 19
System.out.print(" "); // print space
b++; // b = 11
// 11 < 19
// print space
// b = ...(*skip to the end*) 19
// j = 2
// b is still 19, doesn't print anything
// j = 3, etc.
}
System.out.print(x);
x--;
if (x<0) x=9;
}
In other words, j and b are unnecessary because we already have a columnIndex we can use. Let's do some more renaming of variables.
x I will rename to printValue
x2 will be unnecessary, we only need one printValue, However, I will be adding a totalColumns to the beginning of our main method.
So now our finished code will look like:
public static void main(String args[])
{
int totalRows = 20;
int totalColumns = (totalRows * 2) - 1; //added totalColumns, notice the number of columns increases by two with each row and we start with 1 column.
int rowIndex = 0;//easier for looping to start with zero
int columnIndex = 0;
int printValue = 0;
while (rowIndex < totalRows) // we will want to spin through every row
{
//notice there is no limit to the length of a variable name!
int numberOfValuesInRow = (rowIndex*2) + 1;
int numberOfSpacesToOffsetOnEachSide = (totalColumns - numberOfValuesInRow) / 2;
//Print Spaces before the numbers in this row
for (int i = 0; i < numberOfSpacesToOffsetOnEachSide; i++) //i is commonly used to stand for index in a single for loop
{
System.out.print(" ");
columnIndex++; //keep track of columnIndex so we know when we are at the middle of the columns
}
//Print numbers in this row
for (int i = 0; i < numberOfValuesInRow; i++)
{
if (columnIndex < (totalColumns/2) + 1) { //depending on columnIndex position, increase or decrease printValue
printValue++;
} else {
printValue--;
}
System.out.print(printValue%10); //Print printValue, the % will return the remainder of (printValue/10)
columnIndex++;
}
System.out.println(); //start next line
columnIndex = 0; //reset columnIndex for the next row
rowIndex++;
}
}

Math and Arrays

I'm new to java and still learning. I am having one heck of a time trying to figure out how to create this program. I have tried multiple ways and spent about 4 hours now trying to get this to work and it still wont outprint what I need it to. I need a 10x5 array with the first 25 digits being the index variable squared and the last 25 digits being the index times 3. What it is outprinting is 5 numbers over and over 10 times. But it's like it is not reading the "next index variable". I get: 0.0, 1.0, 4.0, 9.0, 16.0, 0.0, 1.0, 2.0, 4.0, etc.. Here is what I have so far(please don't rate down, I'm trying hard to learn this!):
public class snhu4 {
public static void main(String args[]) {
double alpha[][] = new double [10][5];
for (int col=0; col<=9;col++) {
for (int row=0; row<=4;row++) {
alpha[col][row]= Math.pow(row,2);
System.out.println(alpha[col][row]);
}
}
}
}
I believe you're looking for something like this:
public static void main (String[] args) {
double[][] alpha = new double[10][5];
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 5; j++) {
int index = (5 * i + j);
if (index < 25) {
alpha[i][j] = (index * index);
System.out.println("index(" + index + ")^2 =" + alpha[i][j]);
} else {
alpha[i][j] = (3 * index);
System.out.println("3*index(" + index + ") = " + alpha[i][j]);
}
}
}
}
You need an index variable initialized to zero outside of the loops and incremented (index++) inside the inner loop. Then you can perform the calculations on the index (0-49) rather than the row variable, which keeps looping 0-4. You'll also need a conditional (if statement) that performs one calculation if index is < 25 and a different calculation if index >= 25.
This is just a generalised version, compared to the accepted answer. It will give the same output, though.
public static void main(String args[]) {
double alpha[][] = new double [10][5];
int index = 0;
for (int row = 0; row < alpha.length; row++)
{
for (int col = 0; col < alpha[row].length; col++)
{
if (index < 25)
alpha[row][col] = Math.pow(index, 2);
else
alpha[row][col] = index * 3;
index++;
System.out.println(alpha[row][col]);
}
System.out.println("" + '\n');
}
}
You're always using the row variable to calculate the assignment value, I think you should combine the values of row and col (or maybe use an index as aetheria says), something like this:
double alpha[][] = new double[10][5];
for (int col = 0; col <= 9; col++) {
for (int row = 0; row <= 4; row++) {
if (col < 5) //if column >= 5 that means that you just passed the 25 index
alpha[col][row] = Math.pow(row + (col*row), 2);
else {
alpha[col][row] = Math.pow(row + (col*row), 3);
}
}
}
I couldn't test it (my eclipse is totally crushed) but I think that will give you the idea (probably you will need to play with the "row + (col*row)" part, when one of the variables is 0 it will not fit your needs). Hope this helps, regards.

Sudoku Checker 2d array Java

So im having a bit of problem with my code.. It's suppose to cross check rows and columns for same integers.
this is what i have so far.. but when i run it, it only seems to check the first integer only. (for example the first line of the sudoku board reads. 1 2 2 2 2 2 2 2 2 2) it wont detect the obvious multiple 2's but if i change the input to 1 1 2 2 2 2 2 2 2 the error will come up of multiple 1's in this case. the multiple any suggestions to tweak my loops to make it go through the columns?
public static void validate(final int[][] sudokuBoard) {
int width = sudokuBoard[0].length;
int depth = sudokuBoard.length;
for (int i = 0; i < width; i++) {
int j = i;
int reference = sudokuBoard[i][j];
while (true) {
if ((j >= width) || (j >= depth)) {
break;
}
else if (i == j){
// do nothing
}
else if (j < width) {
int current = sudokuBoard[i][j];
if (current == reference) {
System.out.print("Invalid entry found (width)" + "\n");
System.out.print(current + "\n");
// invalid entry found do something
}
} else if (j < depth) {
// note reversed indexes
int current = sudokuBoard[j][i];
if (current == reference) {
System.out.print("Invalid entry found (depth)" + "\n");
System.out.print(current + "\n");
// invalid entry found do something
}
}
j++;
}
Your code is more complex than it should be. Why put everything in one single function when you could split in several different functions?
public static void Validate(final int[][] sudokuBoard)
{
int width = sudokuBoard[0].length;
int depth = sudokuBoard.length;
for(int i = 0; i < width; i++)
if(!IsValidRow(sudokuBoard, i, width))
{
//Do something - The row has repetitions
}
for(int j = 0; j < height; j++)
if(!IsValidColumn(sudokuBoard, j, width))
{
//Do something - The columns has repetitions
}
}
static bool IsValidRow(int[][] sudokuBoard, int referenceRow, int width)
{
//Compare each value in the row to each other
for(int i = 0; i < width; i++)
{
for(int j = i + 1; j < width; j++)
{
if(sudokuBoard[referenceRow][i] == sudokuBoard[referenceRow][j])
return false
}
}
return true;
}
static bool IsValidColumn(int[][] sudokuBoard, int referenceColumn, int height)
{
//Compare each value in the column to each other
for(int i = 0; i < height; i++)
{
for(int j = i + 1; j < height; j++)
{
if(sudokuBoard[i][referenceColumn] == sudokuBoard[j][referenceColumn])
return false
}
}
return true;
}
That way, your code is much more easily maintainable/readable. This code above hasn't been tested, but it should be about right.
I suggest debugging this code step by step to really understand what's going on, if that's not clear for you.
Given the constraints of sudoku (a row of n cells must contain the numbers 1-n only) you don't need an order n^2 search (per row or column), you can do it order n by keeping a bit array indicating which numbers you've seen. Here's the pseudo-code for checking rows, do the same for columns:
for i in 0 to depth-1 // rows
boolean seen[] = new seen[width];
for j in 0 to width-1 // columns
if seen[board[i][j]-1] == true
duplicate number
else
seen[board[i][j]-1] = true
I would break the functionality into smaller boolean checks. This way, you can validate row by row, column by column, and square by square. For instance
private boolean isValidRow(int[] row) {
// Code here to check for valid row (ie, check for duplicate numbers)
}
private boolean isValidColumn(int[] column) {
// Code here to check for valid column
}
private boolean isValidSquare(int[][] square) {
// Code here to check for valid square
}
Note that rows and columns only need to be passed a 1 dimensional array. Squares are a 2 dimensional array as you need to check a 3x3 area. You can also treat these methods as static as their functionality is independent of the Sudoku board instance.
Edit: A suggestion on row/column/square validation is to use a HashSet. Sets can only have 1 element of a certain value, so you can add elements and look for a failure. For example:
HashSet<Integer> hs = new HashSet<Integer>();
for(int i = 0; i < 9; i++) {
if(!hs.add(integerArray[i])) // HashSet.add returns 'false' if the add fails
// (ie, if the element exists)
return false;
}
return true;

Categories