Java infinite method run - java

I make a class to make Arithmetic operations on rational numbers the problem is when I run the program it keeps running and never stops or show results after many tries I discovered that the problem is the reduce method it is just stuck and never completed . any ideas ?
private void normalize() {
if ( (this.num > 0 && this.den < 0) || (this.num < 0 && this.den < 0)){
this.num = -this.num;
this.den = -this.den;
}
}
private void reduce(int n , int d) {
int r , L = 0;
while ( (n!=0) && (d!=0) ) {
if (this.den > this.num)
r = den % num ;
else
r = num % den ;
while (r != 0 ){
for ( int i= r ; i>0 ; i-- ){
if (den % i == 0 && num % i == 0 )
L = i ;
}
num = num / L ;
den = den / L ;
}
}
}
public Rational (int num , int den) {
this.num = num ;
this.den = den ;
normalize();
reduce (this.num , this.den) ;
}

I think I see the source of your confusion. You're passing num and den to reduce(int n, int d), but n and d get assigned the same value as num and den, not the same reference. As such, even though the values of num and den are changing in the while loop, those changes aren't reflected in the values of n and d.
Note also that you're doing division on integers and assigning the result to integers, which may be mathematically undesirable.
One other thing: Even after you fix the problem with n and d, you have an inner while loop that will never exit, because the value of r never changes. You need to update the value of r in the loop so that it eventually becomes 0.

The problem with your loop is that you're never changing the value of r, which contains the terminal value
while (r != 0 )
{
for ( int i= r ; i>0 ; i-- )
{
if (den % i == 0 && num % i == 0 )
L = i ;
}
num = num / L ;
den = den / L ;
}
Somewhere within your while loop, you need to decrement r, or create a condition to help it reach 0.

Related

Limit number of input lines in Java?

I have a problem where I want to take input from the user, the user can insert 1 and up to 8 lines, and each line represents a case.
What I want is to stop the scanner when the user inserts 8 lines, Or if the user wants less than 8 he can press enter or a specific key to end the loop.
What I have done so far:
public static void doSomthing(){
Scanner input = new Scanner(System.in);
while (input.hasNextLine()) { // here I want to check so that it don't exeed 8 lines
int e;
int m;
i = input.nextInt();
j = input.nextInt();
int num = 0;
while (i != 0 || j != 0) {
num += 1;
e = (e + 1) % 100;
m = (m + 1) % 400;
}
System.out.println(num);
}
}
The input should be two numbers in each line, one for i and one for j.
Input:
0 0
100 300
99 399
0 200
Output should be:
C1: 0
C2: 100
C3: 1
C4: 200
Hope this explains my problem.
Thanks in advance!
As #Abhishek suggested, you can use a counter variable:
public static void doSomthing(){
Scanner input = new Scanner(System.in);
int linesParsed = 0;
while (linesParsed < 8 && input.hasNextLine()) {
// What are you using these variables for? You compute their
// values, but then you do not use them
int e;
int m;
// Where are these variables declared? It seems weird to have
// instance variables be named i and j
i = input.nextInt();
j = input.nextInt();
int num = 0;
// Unless i and j are being modified concurrently somewhere
// else in the code, this will result in an infinite loop
while (i != 0 || j != 0) {
num += 1;
e = (e + 1) % 100;
m = (m + 1) % 400;
}
System.out.println(num);
linesParsed++;
}
}

Advice on speeding up prime number counter

How can I improve the logic of the following code? The purpose is to compute the number of primes from 1 to the user input (limitNo). The program works fine except it takes a while, more than the usual 1-3 secs, to generate a result for huge numbers like 99999.
public static int countPrime(int limitNo) {
int noOfTimes = 0, noOfRounds = 0; int o = 1;
while (o <= limitNo) {
for (int i = 1; i <= o; i++) {
if (o%i == 0) {
noOfRounds++;
}
}
if (noOfRounds == 2) {
noOfTimes++;
}
noOfRounds = 0;
o++;
}
return noOfTimes;
}
The code can be improved by
Separating some of the lines to make an isPrime() method.
Changing limits of the for loop so that if the condition is met that means the number is not prime.
public static boolean isPrime(int num) {
for ( int i = 2 ; i < num ; i++ ) {
if ( num % i == 0 ) {
return false;
}
}
return true;
}
Replacing the code in the method with isPrime() and change the start int o = 2 ;.
public static int countPrime(int limitNo) {
int noOfTimes = 0;
int o = 2;
while ( o <= limitNo ) {
if ( isPrime(o) ) {
noOfTimes++;
}
o++;
}
return noOfTimes;
}
Of course, there are better and more improvements like:
for ( int i = 2 ; i <= num/2 ; i++ )
for ( int i = 2 ; i <= Math.sqrt(num) ; i++ )

Why is my Java Tortoise and Hare Race not displaying properly?

I have seen several questions about the Tortoise and Hare Race but they are all pertaining to applets and I am not programming an applet. The program is meant to I am having some trouble with the display output of my program. I would like to have the program display an output that looks something like this:
______T__________H________________________________
__________T_______________________H_______________
_____________T________H___________________________
etc. until either the tortoise or the hare reaches the end and wins the race. As of right now, my output looks like this:
______________________________HT__________________________________________________HT__________________________________________________HT_
over and over in what seems to be an infinite loop. Here is my code:
public class TortoiseAndHair {
public static void main ( String [] args )
{
int t = 0; // Keeps track of tortoise progress
int h = 0; // Keeps track of hare progress
System.out.println( "AND THEY'RE OFF!!" );
while (t < 50 || h < 50)
{
hareMove( h );
tortoiseMove( t );
if (t>1 && h> 1 && t == h) // Display when tortoise and hare occupy same space beyond start
{
System.out.print( "OUCH!!");
}
if ( t < 1 )
{ // Prevents tortoise from slipping behind start
t = 1;
}
if ( h < 1 )
{ // Prevents hare from slipping behind start
h = 1;
}
if ( t > 50 )
{ // Prevents tortoise from going passed finish line
t = 50;
}
if ( h > 50 )
{ // Prevents hare from going passed finish line
h = 50;
}
for ( int count = 1; count <= 50; count++)
{
System.out.print( "_" );
if ( count == h )
{
System.out.print( "H" );
}
if ( count == t )
{
System.out.print( "T" );
}
}
if (h < 50 && t == 50)
{ //Output if tortoise wins
System.out.print( "TORTOISE WINS!!" );
}
if ( t < 50 && h == 50)
{ // Output if hare wins
System.out.print( "HARE WINS!!" );
}
if ( h == 50 && t == 50)
{
System.out.print( "IT'S A TIE!!" );
}
}
}
/**
* This method will calculate the random integer that will dictate the tortoise's movements on the board,
* use that random integer to determine the tortoise's movements (tMove), and add that to the counter keeping track
* of the tortoise's position
* #param t is an int variable that is keeping track of the tortoises position on the board
* #return the tortoise's current position on the board after that turn
* Pre-Conditions: n is an int between 1 and 10, t is a positive int greater than 0 and less than 50
*/
public static int tortoiseMove (int t)
{
int n;
int tMove = 0;
n = (int) ( 10 * Math.random() ) + 1; // Generates random number between 1 and 10
if ( n > 10 )
{ // ensures n doesn't go higher than 10
n = 10;
}
// Series of if/else statements to control tMove
if ( n >= 1 && n <= 5)
{ // Fast plod if n is between 1 and 5
tMove = 3;
}
else
{
if ( n >= 6 && n <= 8)
{ // Slow Plod if n is between 6 and 8
tMove = 1;
}
else
{
if ( n == 9 || n == 10 )
{ // Slip if n is 9 or 10
tMove = -6;
}
}
}
// Add determined movement to tortoise counter and return that value
t += tMove;
return t;
}
/**
* This method will calculate the random integer that will dictate the hare's movements on the board,
* use that random integer to determine the hare's movements (hMove), and add that to the counter keeping track
* of the hare's position on the board
* #param h is an int variable keeping track of the hare's current position on the board
* #return the hare's position on the board after current turn
* Pre-Condition: n is an int between 1 and 10, h is a positive int greater than 0 and less than 50
*/
public static int hareMove (int h)
{
int n;
int hMove = 0;
n = (int) ( 10 * Math.random() ) + 1; // Generates random number between 1 and 10
if ( n > 10 )
{ // ensures n doesn't go higher than 10
n = 10;
}
//Series of if/else statements to control hMove
if ( n == 1 || n == 2 )
{ // Big hop if n is 1 or 2
hMove = 9;
}
else
{
if ( n >= 3 && n <= 5)
{ // Small hop is n is between 3 and 5
hMove = 1;
}
else
{
if ( n == 6 )
{ // Big slip is n is 6
hMove = -12;
}
else
{
if ( n == 7 || n == 8 )
{ // Small slip if n is 7 or 8
hMove = -2;
}
else
{
if ( n == 9 || n == 10 )
{ // Hare falls asleep if n is 9 or 10
hMove = 0;
}
}
}
}
}
// Add determined movement to hare counter and return value of h
h += hMove;
return h;
}
}
You never reassign h and t after moving
h = hareMove( h );
t = tortoiseMove( t );
Primitives are passed by value, so whatever change you made to h and t in the move method are not reflected in the original values.

For loop confused as to which value to consider

I have this loop here:
while(n != 0)
{
ld = n % 10;
System.out.println(ld);
for ( i=1; i <= ld; i++)
{
f = f * i;
}
System.out.println(f);
n /= 10;
}
Let us consider a number, say 123. Now, this loop calculates the factorial of 3 accurately, but when it restarts to calculate the factorial of 2, the for loop gets confused as to which value to take for the variable ld. Is there any solution to this?
The problem is not ld. You forgot to resetf in each iteration.
while(n != 0)
{
ld = n % 10;
System.out.println(ld);
f = 1; // reset f
for ( i=1; i <= ld; i++)
{
f = f * i;
}
System.out.println(f);
n /= 10;
}
Output :
3
6 // factorial of 3
2
2 // factorial of 2
1
1 // factorial of 1
You need to reset f once you are done with one number.
Add f = 1; when you enter in while loop.
Solution
while(n != 0)
{
ld = n % 10;
f = 1;// add this
System.out.println(ld);
for (int i=1; i <= ld; i++)
{
f = f * i;
}
System.out.println(f);
n /= 10;
}
You may look in to this code,code is ok just need to set the value for f inside the loop for each digit for given number.
import java.util.*;
import java.lang.*;
import java.io.*;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
int ld;
int n=123;
while(n != 0)
{
int f=1;
ld = n % 10;
System.out.println(ld);
for ( int i=1; i <= ld; i++)
{
f = f * i;
}
System.out.println(f);
n /= 10;
}
}
}
output are as
3
6
2
2
1
1
Most important:
Now our loop resets f to 1 every "repeat".
Additional:
Added int i = 1 to for loop.
You can use f *= 1; instead of f = f * 1;
Changed n != 0 to n > 0 for more safety .
while(n > 0)
{
ld = n % 10;
System.out.println(ld);
f = 1;
for(int i = 1; i <= ld; i++)
{
f *= i;
}
System.out.println(f);
n /= 10;
}

Find the max sum path from bottom left side to top right cell

I have to find the maximum sum path in a 2d Array(n,m) given which has a value from 0 to 99999. 0 means wall. We have t start from the left bottom side of the array and must reach the right top cell(0,m-1). You can go up/down/right and can visit each cell once. Below is the code without any blocks .My problem is that i cant move from left bottom to right top cell . I also created left array(lest side of the main array) so that i can start from the best value possible .Sorry am not good programmer :).
Code
public static int maxvalue(int [][]field,int[] left)
{
for(int i=field.length-1;i>0 && left[i]!=-1;i--)
{
System.out.println( "Startpos "+i+" 0");
int distance =max(i,0,field,0,field.length-1);
if(distance>maxvalue)
maxvalue=distance;
}
return maxvalue;
}
public static int max(int r, int c,int [][]field ,int destR, int destC)
{
if(r>destR|| c>destC)
return 0;
if(r==0 && c==field[0].length)
return field[r][c];
int sum1=max(r-1,c,field,destR,destC); // up
System.out.println(sum1);
int sum2= max(r+1,c,field,destR,destC); //down
int sum3= max(r,c+1,field,destR,destC); //right
return field[r][c]+Math.max(sum1, Math.max(sum2, sum3));
}
Sample
Input
0 1 2 3
2 0 2 4
3 3 0 3
4 2 1 2
Output
25
How to do solve this question? if all the path is blocked then print No Solution.
Have you first tried to solve it by yourself?
It looks like a bit of work but it is not impossible.
What I would use is 3 int variables : xPosition, yPosition and Sum;
Go on and test the values of xPosition+1, yPosition-1 in priority and then the rest (because you want to reach xPosition == array.length - 1 && yPosition == 0.) and if you find a 0, test the other possibilities and exclude the ones you already passed by.
Each time you find a good path, add the value of the cell to your sum.
Reset it to 0 once you're blocked.
For every element in the array, you have to find the maximum of the adjacent elements and also check the boundary conditions. I hope this code will help you.
public class StackOverFlow {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int m = in.nextInt();
Integer [][] array = new Integer[n][m];
boolean [][] visited = new boolean[n][m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
array[i][j] = in.nextInt();
}
}
int i = n-1, j =0;
visited[i][j] = true;
int sum = array[i][j];
while(true)
{
int max = -1;
int maxi = 0, maxj = 0;
if(i-1 >= 0 && i-1<= n-1 && j>=0 && j<= m-1 && array[i-1][j] != null && array[i-1][j]>max && !visited[i-1][j])
{
max = array[i-1][j];
maxi = i-1;
maxj=j;
}
if(i+1 >= 0 && i+1<= n-1 && j>=0 && j<= m-1 &&array[i+1][j] != null && array[i+1][j]>max && !visited[i+1][j])
{
max = array[i+1][j];
maxi = i+1;
maxj=j;
}
if(i >= 0 && i<= n-1 && j-1>=0 && j-1<= m-1 && array[i][j-1] != null && array[i][j-1]>max && !visited[i][j-1])
{
max = array[i][j-1];
maxi = i;
maxj=j-1;
}
if(i >= 0 && i<= n-1 && j+1>=0 && j+1<= m-1 && array[i][j+1] != null && array[i][j+1]>max && !visited[i][j+1])
{
max = array[i][j+1];
maxi = i;
maxj=j+1;
}
i = maxi;
j = maxj;
visited[i][j] = true;
sum += max;
if(i == 0 && j == m-1)
break;
}
System.out.println(sum);
}
}

Categories