How to scan the next line of a file of integers? - java

In my program, I am trying to use a Scanner to scan a file full of integers. This is a homework assignment asking me to write a program that shows all ways of making up a predetermined amount of money with the given coins, and the tester uses files like this.
// Coins available in the USA, given in cents. Change for $1.43?
1 5 10 25 50 100
143
My output needs to have the very last line (the line representing the total amount of money ex: 143)
to appear like this:
change: 143
1 x 100 plus 1 x 25 plus 1 x 10 plus 1 x 5 plus 3 x 1
1 x 100 plus 0 x 25 plus 4 x 10 plus 0 x 5 plus 3 x 1
1 x 100 plus 0 x 25 plus 3 x 10 plus 2 x 5 plus 3 x 1
1 x 100 plus 0 x 25 plus 2 x 10 plus 4 x 5 plus 3 x 1
1 x 100 plus 0 x 25 plus 1 x 10 plus 6 x 5 plus 3 x 1
1 x 100 plus 0 x 25 plus 0 x 10 plus 8 x 5 plus 3 x 1
2 x 50 plus 1 x 25 plus 1 x 10 plus 1 x 5 plus 3 x 1
2 x 50 plus 0 x 25 plus 4 x 10 plus 0 x 5 plus 3 x 1
...
my struggle is that I have an initialized variable,
Integer change;
and I have it set to
change = input.nextLine();
However, I get this error message stating that it is an incompatible type requiring a String. How do I make it to where I can scan the next line and set it to an integer? Thank you for any and all help!

Parse the string to Integer change = Integer.parseInt(input.nextLine());

Is this the Scanner from Java? If so try this. . .
Scanner scantron = new Scanner( 'input file' );
// can be dynamically added to easier than normal arrays
ArrayList<Integer> coins = new ArrayList<Integer>();
int change;
// toggle flag for switching from coins to change
boolean flag = true;
while(scantron.hasNextLine())
{
// if this line has no numbers on it loop back to the start
if(!scantron.hasNextInt()) continue;
// getting the first line of numbers
while(flag && scantron.hasNextInt()) coins.add(scantron.nextInt());
// set the flag that the coins have been added
flag = false;
// if this is the first time the flag has been seen ignore this
// otherwise the next line should have the change
if(!flag) change = scantron.nextInt();
}

Related

Nested for loop output not correct

for(int c = 1; c <= rows; c++) {
for(int i = 0; i < c; i++) {
System.out.print(++number + " ");
}
}
let us assume that rows = 5 and number = 0 initially. what will be the output?
to me, if rows were 5, the output would be as follows:
1
2
3
4
5
however my teacher has it as: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
and i can't seem to wrap my head around it! can anyone explain why ? i have tried with different numbers as well, for 2, i would get just the number 1,2 but my professor gets 1,2,3
You have two nested loops.
The outer loop iterates from 1 to 5.
The inner loop iterates from 0 to c - 1.
When c == 1, the inner loop iterates from 0 to 0 so number is incremented 1 time.
When c == 2, the inner loop iterates from 0 to 1 so number is incremented 2 times.
When c == 3, the inner loop iterates from 0 to 2 so number is incremented 3 times.
When c == 4, the inner loop iterates from 0 to 3 so number is incremented 4 times.
When c == 5, the inner loop iterates from 0 to 4 so number is incremented 5 times.
In total, number is incremented 1 + 2 + 3 + 4 + 5 == 15 times.
Each time number is incremented, it is also printed, followed by a space. So the loops produce the output 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15.
For every row with the inner loop execute System.out.print(++number + " "); this statement total 15(1 + 2 + 3 + 4 + 5) times and every time number value is implemented and print.
Take a look visualization here
The best way to understand this type of problems is dry-run. I am sharing a two step dry-run hoping that will be helpful:
dry-run

For-loop output explanation needed?

I need an explanation of how the output prints 9(S), 7(S), 5(S) and 3(S).
10 > 3 is correct and goes to y 1 <= 2 which is correct so 2 x 10 - 2 = 18 but the output prints 9. I don't understand the logic here. Why does it print 9(s) instead of 18(s)?
public class Q2{
public static void main(String args[]) {
int x,y;
for(x= 10; x > 3; x = x - 2) {
for(y = 1; y <= 2 * x - 2; y = y + 2)
System.out.print("S");
System.out.print("\n");
}
}
}
Its correct Y <= 18 , but you are incrementing Y by 2, so it gets printed 9 times.
To understand, write down on a piece of paper what the values of your variables will be.
First, write down the values of x:
x: 10 8 6 4
Next, write down the calculated upper boundary value for y, i.e. the result of expression 2 * x - 2:
x : 10 8 6 4
yMax: 18 14 10 6
Last, write down the values of y:
x : 10 8 6 4
yMax: 18 14 10 6
y : 1 1 1 1
3 3 3 3
5 5 5 5
7 7 7
9 9 9
11 11
13 13
15
17
Finally, count the number of y values for each x value, i.e. the number of times S is printed:
x : 10 8 6 4
count: 9 7 5 3
Then realize that the code would have been much easier to understand if it had just been written like this:
for (int count = 9; count >= 3; count -= 2) {
for (int i = 0; i < count; i++) {
System.out.println("S");
}
}
Of course, that wouldn't have taught you what they were trying to teach you, which is:
Conclusion: If you don't understand what the code is doing, follow the logic step by step, and write down what it is doing.

How to reverse this equation?

The following line of code is inside a for loop where j is incremented and ansString is a string of ASCII characters, like 000\Qg$M!*P000\gQYA+ h000\M|$skd 000\Qo}plsd000\.
ansString[j] = ((char)(paramString[j] >> j % 8 ^ paramString[j]));
I am having trouble with figuring out how to have XOR and all the other operators reversed to find paramString. Appreciate any help.
The right bitshift (>>) and modulo (%) are irreversible operations:
In the case of the right bitshift, underflowed bits are lost, so reversing a >> b would leave you with 2^b different possible results.
For the modulo operator, in x % 8 = y there are 32 possible values for x asuming it has a maximum length of 8 bits. (That would be every x * 8 + y that fit in 8 bits)
The xor operation is the only one reversible. If you have
a ^ b = c
then
c ^ b = a
So for more than one input you would have the same output. For example, lets take the case where j = 0
j % 8 = 0 % 8 = 0
paramString[j] >> (j % 8) = paramString[0] >> 0 = paramString[0]
paramString[0] ^ paramString[j] = paramString[0] ^ paramString[0] = 0
This means that for your first character and every 8th subsequent character (this is every character where its index j is a multiple of 8, so j % 8 = 0) the result will be 0, whichever the original character was (as you can see in your example output string).
This is why, even if you brute-force every possible input (a total of 256 * n possible input strings, being n the string length), you can never be sure of what was the original input, as many inputs yield the same output.
If j is a running index, you will know the shift amount in each iteration. With that, you can find a prefix and decrypt the string.
e.g. for j = 2 (0..7 are bit positions, double digits are XORed bits, x is 0):
Original: 0 1 2 3 4 5 6 7
Shifted: x x 0 1 2 3 4 5
Encrypted: 0 1 02 13 24 35 46 57
As you can see, the first 2 digits remain untouched. And those 2 digits are used to encrypt the next two, and so forth.
So to decrypt with j = 2, you find a 2 digit prefix unencrypted. This can be used to decrypt the next 2 bits (02 and 13):
Encrypted: 0 1 02 13 24 35 46 57
Shift-Mask: x x 0 1 x x x x
Temp1: 0 1 2 3 24 35 46 57
Now we know the first 4 digits, and also the decryption bits for the next 2:
Temp1: 0 1 2 3 24 35 46 57
Shift-Mask: x x x x 2 3 x x
Temp2: 0 1 2 3 4 5 46 57
And again:
Temp2: 0 1 2 3 4 5 46 57
Shift-Mask3: x x x x x x 4 5
Decrypted3: 0 1 2 3 4 5 6 7 <- Original string
Based on this idea, you can build the decryption algorithm

Calculating Manhattan Distance within a 2d array

I am writing a program to solve an nxn 8 puzzle problem. I'm having difficulty with my Manhattan calculation function being off by two from the puzzle I'm testing my program with. This will eventually be expanded to use the A* pathfinding algorithm, but I'm not there yet.
Here is my function(which is based on the initial state of the board and not taking into account the amount of moves taken so far):
// sum of Manhattan distances between blocks and goal
public int Manhattan() // i don't think this is right yet - check with vince/thomas
{
int distance = 0;
// generate goal board
int[][] goal = GoalBoard(N);
// iterate through the blocks and check to see how far they are from where they should be in the goal array
for(int row=0; row<N; row++){
for(int column=0; column<N; column++){
if(blocks[row][column] == 0)
continue;
else
distance += Math.abs(blocks[row][column]) + Math.abs(goal[row][column]);
}
}
distance = (int) Math.sqrt(distance);
return distance; // temp
}
This is the example I'm working off of:
8 1 3 1 2 3 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8
4 2 4 5 6 ---------------------- ----------------------
7 6 5 7 8 1 1 0 0 1 1 0 1 1 2 0 0 2 2 0 3
initial goal Hamming = 5 + 0 Manhattan = 10 + 0
My Hamming calculation is correct and returns 5, but my Manhattan returns 8 instead of 10. What am I doing wrong?
This is the output of my program:
Size: 3
Initial Puzzle:
8 1 3
4 0 2
7 6 5
Is goal board: false
Goal Array:
1 2 3
4 5 6
7 8 0
Hamming: 5
Manhatten distance: 8
Inversions: 12
Solvable: true
The error lies in the update of the distance.
In writing distance += Math.abs(blocks[row][column]) + Math.abs(goal[row][column]); you add all contents of the cells of initial and goal. Only one excluded in initial and goal is the cell with same coordinates as 0 in initial.
In your example this gives 2 times sum from 0 to 8 minus 5. 2 * 36 -8 = 64. Then you take the square which is 8.
Manhattan - as described by Wiktionary is calculated by distance in rows plus distance in columns.
Your algorithm must lock like (beware, pseudocode ahead!)
for (cell : cells) {
goalCell = findGoalcell(cell.row, cell.col);
distance += abs(cell.row - goalCell.row);
distance += abs(cell.col - goalCell.col);
}
And don't take the square root.

Determining all values that are equal & next to one another in a 2D array

I'm new to stackoverflow as well as programming so pardon me if I ask this question poorly.
So say I have a 2-D array with integer values from 1 through 4. It might look something like this:
3 3 3 1 3 1 3 1 2 1
1 3 1 3 3 1 1 1 1 1
1 4 3 3 1 3 3 4 3 4
1 4 1 1 3 3 1 4 2 4
1 1 1 4 1 3 3 1 1 3
1 2 3 3 3 3 3 3 1 1
4 1 4 3 3 2 1 1 4 1
1 3 3 3 4 1 4 2 2 3
Let me rewrite it so that I can isolate a part of the array I want us to observe:
x x x x x x x x x x
x x x x x x x x x x
x x x x x 3 3 x x x
x x x x 3 3 x x x x
x x x x x 3 3 x x x
x x 3 3 3 3 3 3 x x
x x x 3 3 x x x x x
x 3 3 3 x x x x x x
We see that the 3's shown here are not only all equal in value but also directly "next to" one another and are all "connected".
I have 4 methods that determine whether or not the space to the right, left, top, or bottom of a space in the array is equal to a given start position:
boolean isEqualRight(int row, int column) {
return array[row][column] == array[row][column + 1];
}
boolean isEqualLeft(int row, int column) {
return array[row][column] == array[row][column - 1];
}
boolean isEqualUp(int row, int column) {
return array[row][column] == array[row - 1][column];
}
boolean isEqualDown(int row, int column) {
return array[row][column] == array[row + 1][column];
}
But, even if I know if a position in the array is equal and next to a start position, I can't think of a solution to determine all of the positions in the array that are equal and connected to the start.
I tried developing a loop that would cycle through a space next to a starting 3, determine if it is next and equal to it, and if so then do the same for the 3 that is next to it, and so on, and so on. But I faced an issue when the 3's started branching. Any thoughts?
This is a standard problem in computer graphics. The algorithm is called Flood Fill and is covered in detail in Wikipedia.
There are also many Java implementations out there if you wanted to study one (just google).
Your methods seem correct but you should add come code to catch any possible IndexOutOfBoundErrors. For example if you take the first element in your array and check up or left you will get an IndexOutOfBound Error as it will reference an element that does not exist, this goes for all boundary elements. This will prevent your code from running efficiently.
Just something to always consider when dealing with arrays.

Categories