For loop stopping prematurely - java

I'm trying to solve problem #299 - Train Swapping in website UVa Online judge. The code I have works fine for independent test cases. However, when I use the sample input they provide, my program omits one of the test cases, the last one to be more specific:
Here is my code:
import java.util.Scanner;
public class Tester {
void problem(){
Scanner imput = new Scanner(System.in);
int numT =imput.nextInt();
int numL, aux, swaps=0;
int [] train = new int [50];
for (int i =0; i<numT; i++) {
numL = imput.nextInt();
for (int m =0; m< numL; m++) {
train[m]=imput.nextInt();
}
for (int j=0; j<numL; j++) {
if (train[j]>train[j+1]) {
for (int k =j; k<numL-1;k++) {
aux = train[k];
train[k]=train[k+1];
train[k+1]=aux;
swaps++;
}
}
}
System.out.println("Optimal train swapping takes "+swaps+" swaps.");
swaps = 0;
}
}
}
Example Input:
3
3
1 3 2
4
4 3 2 1
2
2 1
Example Output:
Optimal train swapping takes 1 swaps.
Optimal train swapping takes 6 swaps.
Optimal train swapping takes 1 swaps.
My code prints until the second solution, then for some reason stops. I've tried to debug it and check what's going on step by step but it has driven me to a migraine point. Any insight is highly appreciated.
...
To be more precise it stops at the second for loop the third time around without taking anything into the array...and I don't know why!
Another thing I found out is that to solve this problem the number of swaps for the case of the middle is 6, therefore the bubble sort wont be useful here, since it makes over 10 swaps thus yielding a wrong output, this is a separate issue to the original one I presented however. I still haven't figure out why it stops the third time around the loop where I assign values to the array for the third time.
The input consists of:
first line is number of cases.
this line enters the length of a train ex: 4
this line enters the number of the wagons ex: 2 4 3 1
the next following lines correspond to the following test cases whose structure is the same as the example.
They ask you to arrange the train and tell the number of swaps made to make the train in order.

Related

Java: Sudoku Array not Filling

I've been trying to build a sudoku, starting with a 9x9 array that ensures no numbers in a given column nor row are the same (ie sudoku without the 3x3 boxes). I've set my code as seen below, but I keep running into a runtime error that I think stems from the do-while statement where the array won't finish filling. However, if I add 10 to the new randomized number (within the do-while statement) the array will finish filling. I've also created a lengthy "check" method that checks whether the current cell is the same as any of the others in that column or row and returns true only if the number is original. I have not included that method for simplicity. Is there something I'm missing?
import java.util.Random;
public class S9x9 {
public static void main (String[] args){
int [][] nines = new int [9][9];
Random rand = new Random();
for (int i = 0; i < nines.length; i++) {
for (int j = 0; j < nines.length; j++) {
nines[i][j] = rand.nextInt(9) + 1;
if (!(check(nines,i,j))) {
do
nines[i][j] = rand.nextInt(9) + 1;
while (!(check(nines, i, j)));
}
System.out.print(nines[i][j] + " ");
}
System.out.print("\n");
}
}
}
Your algorithm will end up in a deadlock quite soon. Suppose you have this:
5 2 3 1 8 6 9 7 4
4 3 1 6 9 2 5 8 7
2 1 6 7 3 5 8 9
There is no valid number to put in the last place. I suggest you change your algorithm to weed out all invalid numbers before using random generation. If there are zero candidates, you have to backtrack.
The problem is that you can deadlock yourself when you don't use any backtrack algorithm in finding a sudoku solution. Assume your two for() loops have already found the following grid:
xxx xxx x1x
xxx xxx x2x
xxx xxx x3x
xxx xxx x4x
567 891 2?.
... ... ...
... ... ...
... ... ...
... ... ...
The place with the ? marker, where your current i and j values are, cannot have any valid number since all the digits are already "used". Check other questions like How to solve Sudoku by backtracking and recursion? on how backtrack works for sudokus.

Jagged Array & Nested For Loop in Java

I have what I thought was a very basic code example, but I can't figure out why the code never completes. It seems to stay stuck in a loop. This very simple code is supposed to declare and initialize a jagged array with the first row having 4 columns and the second row having 3 columns. The code asks the user for 7 integers and prints out the result to the screen. All of that works, but it doesn't break out of the loop unless I manually break out of it. If the manual break is used, the correct output is not achieved.
public class TestCode {
public static void main(String[] args) {
//Create new scanner object
Scanner userInput = new Scanner(System.in);
//Declare two dimentional array
int[][] num2d = new int[4][3];
//Declare variables
int i;
int j;
//Print to screen asking for user input
System.out.print("Enter seven numbers: ");
//Loop through array and print the result
for (i = 0; i < num2d.length; i++) {
for (j = 0; j < num2d[i].length; j++) {
num2d[i][j] = userInput.nextInt();
System.out.println(num2d[i][j]);
//break;
}
}
}
}
When I run this code with the break commented out, I get this result, but I have to manually stop it from running.
run:
Enter seven numbers: 1 2 3 4 1 2 3
1
2
3
4
1
2
3
When I put the break in, this is what I get.
run:
Enter seven numbers: 1 2 3 4 1 2 3
1
2
3
4
BUILD SUCCESSFUL (total time: 4 seconds)
What's going on? Why can I get the correct result with the "build successful" message without using the break?
Your code doesn't loop forever: it loops 12 times, because you have declared a 4x3 array - i.e. an array sized 4 where each of the elements is an array of 3 ints.
Instead, I think you want something like this:
int[][] num2d = {new int[4], new int[3]};
your loop runs on the "columns" of the 2d array which is 4 times and for each "column" it runs on its length which is 3. 4 times 3 is 12, and you only enter 7 numbers. the console is always waiting your input.

Replicating the sleight of hand Trick Oil and Water

Note: I haven't found an answer to this particular question.
Backstory:
I recently learned the Oil and Water routine that magician's use in sleight of hand (this doesn't mean I can actually do it, but I have the mechanics done). For those that are unfamiliar with this routine, it takes three red cards and three black cards. These cards are initially put together red, black, red, black, red, black. By the end of the trick, all the reds are back together and all the blacks are back together.
I have successfully coded this in Java, but I am at a loss as to explain why it is doing it correctly. I think there is a problem with my logic I am sure, but I need some verification.
Here is the code I currently have:
int[] mixed = {1,2,1,2,1,2};
System.out.println("Before Sort: ");
for (int element : mixed){
System.out.println("Element: " + element);
}
for (int element : mixed){//this for loop moves all but the first and last element.
// for (int element=0;element < mixed.length-1;element++){// this for loop reverses order
int temp = mixed[element];
mixed[element]=mixed[element+1];
mixed[element+1]=temp;
}
if ((mixed[0]==1) && (mixed[5]==2)){//this swaps the first and last elements after using an enhanced for loop
int temp = mixed[0];
mixed[0] = mixed[5];
mixed[5] = temp;
}
System.out.println("After sort: ");
for (int element : mixed){
System.out.println("Element: " + element);
}
Make sure to read the comments I have in the code, as this is where my wtf moment is. My goal is to be able to have my high school students do this when it comes time to hit arrays. I would like to be able to introduce this as I introduce arrays. Any help would be greatly appreciated.
You are iterating over the array using elements of the array as an index for the switches that you make.
You are only ever doing two of the same switches.
When the current element is 1, it switches values at index 1 and index 2 of the array.
When the current element is 2, it switches values at index 2 and index 3 of the array.
This doesn't work; you have to do a manual switch at the end. And this manual switch will not work in other cases.
The right way to do this is to:
array 1 2 1 2 1 2
index 0 1 2 3 4 5
Switch:
0 with 1
1 with 3
2 with 5
The are only 3 switches so the loop should start at 0 and end at array length / 2.

Simple program but can't get it right

Problem
Turtles live long (and prosper). Turtles on the island Zanzibar are
even immortal. Furthermore, they are asexual, and every year they give
birth to at most one child. Apart from that, they do nothing. They
never leave their tropical paradise.
Zanzi Bar, the first turtle on Zanzibar, has one further activity: it
keeps track of the number of turtles on the island. Every New Year’s
Day it counts the turtles, and writes the total number in a small
booklet. After many years this booklet contains a non-decreasing
sequence of integers, starting with one or more ones. (After emerging
from its egg on Zanzibar’s beautiful beach, it took Zanzi some time to
start a family on its own.)
One day Zanzi realizes that it could also be the case that turtles
from abroad come to Zanzibar, by boat or plane. Now it wonders how
many of the inhabitants were not born on Zanzibar. Unfortunately, it
can only derive a lower bound from the sequence in the booklet.
Indeed, if the number of turtles in a year is more than twice as big
as the year before, the difference must be fully explained by import.
As soon as Zanzibar has 1000000 turtles, the island is totally covered
with turtles, and both reproduction and import come to a halt. Please
help Zanzi! Write a program that computes the lower bound of import
turtles, given a sequence, as described above.
Input
The input starts with a line containing an integer T(1≤T≤13), the
number of test cases. Then for each test case:
One line containing a sequence of space-separated, positive integers
(≤1000000), non-decreasing, starting with one or more ones. For
convenience, a single space and a 0 are appended to the end of the
sequence.
Output
For each test case, output a line containing a single integer: the
lower bound for the number of turtles not born on Zanzibar.
See question and sample input and output here
My approach
public Zanzibar() {
Scanner scan = new Scanner(System.in);
int iterations = scan.nextInt();
for (int i = 0; i < iterations; i++) {
int previous = -1;
int current = -1;
int lower = 0;
while (true) {
if (current != -1)
previous = current;
current = scan.nextInt();
if (current == 0)
break;
if (current > 2 * previous && previous != -1)
lower += current - previous;
}
System.out.println(lower);
}
}
I think I am understanding the problem wrong. Am I supposed to keep adding to the lower bound or should I find the biggest difference between two years? Also I don't understand how input 1 100 0 produces output 98 (from the link). Shouldn't it be 99?
This is what the problem setter wants us to understand:
The initial 1 for every test case means that the initial population on the island is always 1
So for an input like 1 1 1 0, it means that:
The initial population is 1. Then at the start of the 2nd year, the population is still 1. At the start of the 3rd year, the population is still 1.
As for your doubt about the input: 1 28 0, it means that:
At the start of the 2nd year, the population is 28, whereas the maximum that could have been is 2, as the only turtle could have given birth to one more turtle at max. So, it means that clearly, at least (28-2) = 26 turtles migrated!!!
Hope it helps...
Edit: This is the algorithm:
For every line of test case do the following:
Set initial to 1, migrated to 0
Start reading from the second number in the line, until we encounter a 0:
If the current number is greater than 2*initial: migrated = migrated + (current - 2*initial)
Else: do nothing
Set initial to current
Print migrated
Edit-2:
Here is the JAVA implementation:
import java.util.*;
class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int iterations = scan.nextInt();
int i = 0;
int len,x;
int j,initial;
long migrated;
int arr[] = new int[1000005];
while(i<iterations)
{
len = 0;
while(true)
{
x = scan.nextInt();
if(x==0)
break;
arr[len++] = x;
}
initial = arr[0];
migrated = 0;
j = 1;
while(j<len)
{
if(arr[j]-(2*initial)>0)
{
migrated += arr[j]-(2*initial);
}
initial = arr[j];
j++;
}
System.out.println(migrated);
i++;
}
}
}
Input:
3
1 100 0
1 1 1 2 2 4 8 8 9 0
1 28 72 0
Output:
98
0
42

What is wrong with my code/ what can I do to solve this assignment?

In this lab, you will be creating a program that merges two arrays of positive (greater than 0) integers. Your program will accept each array as input from the keyboard. You do not know ahead of time how many values will be entered, but you can assume each array will have a maximum length of 10,000 elements. To stop entering values enter zero or a negative number. You should disregard any non-positive numbers input and not store these in the array.
The elements of the two input arrays should be in increasing order. In other words, each array element must have a value that is greater than or equal to the previous element value. An array may contain repeated elements.
After the two arrays have been input, your program must check to make sure the elements of each array have been entered in order. If an out of order element is found, print the message “ERROR: Array not in correct order”.
Your task is to merge the two input arrays into a new array, with all elements in order, lowest to highest. Print out each of the original arrays entered, followed by the merged array.
Please note that your program must output the arrays with exactly one space between each of the numbers.
Sample Run 1:
Enter the values for the first array, up to 10000 values, enter zero or a negative number to quit
3
3
5
6
8
9
-1
Enter the values for the second array, up to 10000 values, enter zero or a negative number to quit
3
4
5
6
-5
First Array:
3 3 5 6 8 9
Second Array:
3 4 5 6
Merged Array:
3 3 3 4 5 5 6 6 8 9
My code was:
import java.util.Scanner;
class Main{
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
int one1=0;
int two1=0;
int a = 0;
int b = 0;
int flag = 0;
int[]one=new int[10000];
int[]two=new int[10000];
System.out.println("Enter the values for the first array, up to 10000 values, enter a negative number to quit");
while (a==0){
int first = scan.nextInt();
if (first<=0) a++;
else{
one[one1]=first;
one1++;
}
}
System.out.println("Enter the values for the second array, up to 10000 values, enter a negative number to quit");
while (b==0){
int second = scan.nextInt();
if (second<=0) b++;
else{
two[two1]=second;
two1++;
}
}
System.out.println("First Array:");
for (int i = 0 ; i < one1 ; i++){
System.out.print(one[i]+" ");
}
for (int i = 0 ; i < one.length-1 ; i++){
if (one[i]>one[i+1]) flag++;
}
System.out.println("Second Array:");
for (int i = 0 ; i < two1 ; i++){
System.out.print(two[i]+" ");
}
for (int i = 0 ; i < two.length-1 ; i++){
if (two[i]>two[i+1]) flag++;
}
int[]combo = new int[one.length+two.length];
for (int i = 0 ; i < combo.length-1 ; i+=2){
combo[i]=one[i];
combo[i+1]=two[i];
}
if (flag>0) System.out.println("ERROR: Array not in correct order");
else{
for (int i = 0 ; i < combo.length; i++){
System.out.print(combo[i]+" ");
}
}
}
}
This code keeps giving me runtime error- what am I doing wrong?
I am sorry, your merge algortithm is all wrong. You create an array combo of length one.length + two.length, that is, 20000 (I think one1 + two1 should suffice). Then you try to fill the new array by looping through it two elements at a time:
for (int i = 0; i < combo.length - 1; i += 2) {
So i is 0, 2, 4 etc. through 19998 (the last even number before 20000). Except when it gets 10000, you try to pick out one[i], that is one[10000], which is outside the one array. This gives the ArrayIndexOutOfBoundsException.
How I found out? The stack trace gives a line number. The line it mentions is
combo[i] = one[i];
It also mentioned the number 10000, so I knew this was the value of i at this point.
I think that what you were trying to do, was fill elements 0 from one and two into elements 0 and 1 of combo, I think it works so far. Then you wanted to fill element 1 from each array into elements 2 and 3; but since you have added 2 to i, you fill in element 2 from each source array and never use element 1 from them. Or any element from odd indices.
Before you mend that problem, allow me to mention one more thing. I think with your logic, input arrays 2 5 and 11 30 will come out as 2 11 5 30. This doesn’t fulfil “with all elements in order, lowest to highest”. So I think you should think your algorithm over.
the code exist many logic error,
as for Runtime Error Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10000 at..
the problem is here:
for (int i = 0 ; i < combo.length-1 ; i+=2){
combo[i]=one[i];
combo[i+1]=two[i];
}
the i from 0 to 19999 and the index of a,b is from 0 to 9999, and the code exist other simple logic problem. Please check it again.
Homework questions are very frowned upon, but still, Java is a relatively easy language. If your program is throwing a RuntimeException, you just have to read what the problem is.
In this case, it seems a loop iterates more times than it should, and you are accessing other memory space. Give it a few reads with the info provided by the error trace in mind.

Categories