While Loops and Reverse Fibonacci - java

I've come across a problem. I'm trying to make a class which takes the maximum number that a user puts in and adds the integer before it until it gets to 0, however, when I run it, the numbers get larger and larger until it crashes. What seems to be throwing this into an infinite loop?
public class Summation {
public static void main(String[] args) {
EasyReader console = new EasyReader();
System.out.print("Debug? (Y/N): ");
char debug = console.readChar();
if ((debug!='Y')&&(debug!='N')){
System.out.println("Please enter Y or N");
main(null);
}
else{
System.out.print("Enter max range:");
int max = console.readInt();
int s = sum(max,debug);
System.out.print(s);
}
}
public static int sum(int m, char d){
int sm = 1;
boolean isRunning = true;
while ((isRunning == true)&&(d=='Y')){
if ((--m)==0) {
isRunning = false;
}
else{
sm = m+(--m);
System.out.println("sm is"+sm);
}
while ((isRunning == true)&&(d=='N')){
if ((--m)==0) {
isRunning = false;
}
else{
sm = m+(--m);
}
}
}return sm;
}
}

There's a scenario where your condition for exit
if ((--m)==0)
will never again be reached, because m is already less than 0, and it's never going back.
that scenario is whenever m is an even number.
while ((isRunning == true)&&(d=='Y'))
{
// this condition decriments `m` every time it runs, regardless of whether it evaluates to true
if ((--m)==0)
{
// if `m` was set to 0 on your last iteration, it will be set to -1
isRunning = false;
}
else
{
// if m is 1 before this line it will be 0 after it.
sm = m+(--m);
System.out.println("sm is"+sm);
}
while ((isRunning == true)&&(d=='N'))
{
// this code will never get executed
}
}
return sm;

Answer to your problem is very simple
Just modify the condition
if (m==0) {
isRunning = false;
}
When you are checking --m == 0, it is very much possible that m will be jumping over 0 and will enter negative territory without even setting this condition to be true.

Everything you are doing is wrong :).
First - FORMATTING. You maybe even dont know that, but the second while is INSIDE the first while cycle. If you use netbeans, its ALT+SHIFT+F.
The using of --m is not good for your example, cause it firsts decrease the "m" value and then it compares. So even when you asking at
(--m)==0
you decrease a value. And because you are using it again at
sm = m+(--m)
you can even skip the "0" value and get into negative numbers.
However if you want only "add numbers in reverse order from given number to 0 in while loop" it is not fibonacci and you can use this code (it could be done better, but this is using your code) :
public class Summation {
public static void main(String[] args) {
System.out.println(sum(10, 'Y'));
}
public static int sum(int m, char d) {
int sm = 0;
boolean isRunning = true;
while ((isRunning == true) && (d == 'Y')) {
sm += m;
if (m == 0) {
isRunning = false;
} else {
m--;
System.out.println("sm is" + sm);
}
while ((isRunning == true) && (d == 'N')) {
if ((--m) == 0) {
isRunning = false;
} else {
sm = m + (--m);
}
}
}
return sm;
}
}
Note that second while cycle couldnt be reached - it passes only when "d == Y" and then it starts only when "d == N"

Related

Given an array of numbers, the task is to print only those numbers which have only 1, 2 and 3 as their digits

Im currently working on a program to given integer input from user, print only those ones contain numbers 1 2 or 3. Here is my code so far:
public static void main(String[] args){
Scanner s = new Scanner(System.in);
int[] x=new int[5];
System.out.println("Enter 5 integers: ");
for(int i=0; i<x.length;i++) {
x[i]=s.nextInt();
boolean temp=recursion(x[i]);
if(temp==true) {
System.out.print(x[i]);
}
}
}
public static boolean recursion(int y) {
if(y%10==1 || y%10==2 || y%10==3) {
return true;
}
else if(y%10==0) {
return false;
}
else {
int remain=y/10;
recursion(remain);
}
}
So my approach is quite simple, I used a simple bool recursion to return true or false, true if it does contain 1 2 or 3 and false if not. The problem I am having is that I am not returning anything in my recursion else statement. I know I have to return something but not sure what to return or if its necessary. Anything I can change to make this work?
Your base cases for recursion are a little off, so in the statement
else if(y%10==0), the number 100 would cause this to fail even though it is valid. you want your false base case to actually be else if (y == 0) which means you have gone through the entire number. the solution looks like:
public static boolean recursion(int y) {
int positive = Math.abs(y);
if(positive%10==1 || positive%10==2 || positive%10==3) {
return true;
} else if (positive == 0) {
return false;
}
return recursion(positive / 10);
}
edit: Calling absolute value on the number makes it work for negative numbers as well, but you can call abs on the integer being passed in to the same effect.
I think you just have to do
return recursion(remain);
Use below code, hope this will help.
public static boolean recursion(int y) {
if(y%10==1 || y%10==2 || y%10==3) {
return true;
}
else if(y%10==0) {
return false;
}
else {
int remain=y/10;
return recursion(remain);
}
}

java close scanner & out of bounds exeption

i got two different kind of errors in my code.
one is when someone enters a number that's higher than 8 or lower than 0.
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 22
at boter_kaas_en_eiren.Board.placeAttempt(Board.java:37)
at boter_kaas_en_eiren.Game.play(Game.java:28)
at boter_kaas_en_eiren.MainClass.main(MainClass.java:12)
the other error is when a player wins and i want to close the scanner so nobody can play anymore.
Exception in thread "main" java.lang.IllegalStateException: Scanner closed
at java.util.Scanner.ensureOpen(Unknown Source)
at java.util.Scanner.findWithinHorizon(Unknown Source)
at java.util.Scanner.nextLine(Unknown Source)
at boter_kaas_en_eiren.Game.play(Game.java:23)
at boter_kaas_en_eiren.MainClass.main(MainClass.java:12)
if somebody could help me i would appriciate it.
game class
package boter_kaas_en_eiren;
import java.util.Scanner;
public class Game {
private Board board;
private boolean gameFinished;
public Game() {
board = new Board();
gameFinished = false;
}
public void play() {
Scanner scan = new Scanner(System.in);
int x = 0;
String nextSymbol = "x";
board.ShowBoard();
while (gameFinished == false) {
String input = scan.nextLine();
int position = Integer.parseInt(input);
boolean highorlow = board.tohighorlow(position);
boolean succes = board.placeAttempt(position, nextSymbol);
if (highorlow) {
if (succes) {
if (nextSymbol.equals("x")) {
nextSymbol = "o";
} else {
nextSymbol = "x";
}
}
}
board.ShowBoard();
if (board.checkWinner("x") == true) {
System.out.println("x wins");
scan.close();
}
if (board.checkWinner("o") == true) {
System.out.println("x wins");
scan.close();
}
}
}
}
main class
package boter_kaas_en_eiren;
public class MainClass {
public static void main(String[] args) {
Game game = new Game();
game.play();
}
}
board class
package boter_kaas_en_eiren;
import java.util.Scanner;
public class Board {
private String[] board;
public Board() {
board = new String[9];
for (int i = 0; i < board.length; i++) {
board[i] = " ";
}
}
public void ShowBoard() {
System.out.println(board[0] + "|" + board[1] + "|" + board[2]);
System.out.println(board[3] + "|" + board[4] + "|" + board[5]);
System.out.println(board[6] + "|" + board[7] + "|" + board[8]);
System.out.println("");
}
public boolean tohighorlow(int position) {
if (position <= 8 && position >= 0) {
return true;
} else {
System.out.println("Invalid!!");
return false;
}
}
public boolean placeAttempt(int position, String symbol) {
if (board[position].equals(" ")) {
board[position] = symbol;
return true;
} else {
System.out.println("invalid!");
return false;
}
}
public boolean checkWinner(String symbol) {
if (board[0].equals(symbol) && board[1].equals(symbol) && board[2].equals(symbol)) {
return true;
} else if (board[3].equals(symbol) && board[4].equals(symbol) && board[5].equals(symbol)) {
return true;
} else if (board[6].equals(symbol) && board[7].equals(symbol) && board[8].equals(symbol)) {
return true;
} else if (board[0].equals(symbol) && board[3].equals(symbol) && board[6].equals(symbol)) {
return true;
} else if (board[1].equals(symbol) && board[4].equals(symbol) && board[7].equals(symbol)) {
return true;
} else if (board[2].equals(symbol) && board[5].equals(symbol) && board[8].equals(symbol)) {
return true;
} else if (board[0].equals(symbol) && board[4].equals(symbol) && board[8].equals(symbol)) {
return true;
} else if (board[2].equals(symbol) && board[4].equals(symbol) && board[6].equals(symbol)) {
return true;
} else {
return false;
}
}
}
If you would thoroughly check the source code lines given in the exceptions, you could probably find the issues yourself. But let's go through it together this time:
ArrayIndexOutOfBoundsException
This means you are trying to access an array element that is simply not there.
In your Game class, you have these two lines:
boolean highorlow = board.tohighorlow(position);
boolean succes = board.placeAttempt(position, nextSymbol);
Looking at tohighorlow(), we find this line:
if (position <= 8 && position >= 0) {
return true;
}
However, this will return true if the number is in the range [0..8]. In other words, the method returns true when your number is neither too high nor too low. Easiest fix is to change the condition like this:
if (position > 8 || position < 0)
Now numbers greater than 8 or lower than 0 will yield true, which seems to be what the method is supposed to do. Alternatively, you could swap the bodies of the if and else.
Regardless of that, you are ignoring the result of this method when you call placeAttempt() in your Game class. That's not good, because looking at placeAttempt() we find this line:
if (board[position].equals(" ")) { /* ... */
This is where your exception originates. You are accessing the board array without checking the position value. Or rather, you did check the position value but did not respect the result of that check here. Hence, if position is -2 or 12, for example, you will run into trouble as those elements do not exist (are out of bounds).
IllegalStateException: Scanner closed
Let's simplify the play() method of your Game class for a second:
public void play() {
Scanner scan = new Scanner(System.in);
/* ... */
while (gameFinished == false) {
String input = scan.nextLine();
/* ... */
boolean highorlow = board.tohighorlow(position);
boolean succes = board.placeAttempt(position, nextSymbol);
/* ... */
if (board.checkWinner("x") == true) {
System.out.println("x wins");
scan.close();
}
if (board.checkWinner("o") == true) {
System.out.println("x wins");
scan.close();
}
}
}
The first thing you do is to create the Scanner. Now, under certain circumstances (the two if at the end), you close the scanner. However, you do that within a loop. After you close the scanner, the loops starts over with its first line:
String input = scan.nextLine();
But you can't get the next line of a closed scanner.
Additional notes
I noticed that you are quite inconsistent in your style. For example, see these three method names: ShowBoard, placeAttempt and tohighorlow. You use different capitalization for each. I strongly suggest to stick to the recommended naming convention, which means camelCase with lower first letter: showBoard, placeAttempt and tooHighOrLow (also notice to vs too).
Hope this helps.
Your array board has the size 9. So if someone enters a number not between 0 and 8 you get an Exception.
You pass the input from the user directly to your function:
board.placeAttempt(position, nextSymbol);
There you do:
if (board[position].equals(" ")) {
So you try to access an invalid position of the array

What's wrong with my simple Java program?

It's just supposed to print the prime numbers below 100 but it only gets the number '3' as an output. I'm only just starting to learn Java so it all looks right to me.
public class ClassesAndObjects {
public static void main(String[] args) {
Prime n = new Prime();
for (int i = 3; i < 100; i++){
n.Number = i;
n.factors();
}
}
}
class Prime{
long Number;
long fact;
boolean state = true;
void factors(){
for (fact = 2; fact < Number; fact++){
if (fact != Number){
if (Number % fact == 0){
state = false;
break;
}
}
}
if (state == true){
System.out.println(Number);
}
}
}
You have to reset the boolean state to true at the beginning of each call, otherwise it's always false except for the first call (when i =3 )
void factors(){
state = true;
for (fact = 2; fact < Number; fact++){
if (fact != Number){
if (Number % fact == 0){
state = false;
break;
}
}
}
if (state == true){
System.out.println(Number);
}
}
Add a statement like this:
if (state == true){
System.out.println(Number);
}
state = true; //reset the state variable
Here we are resetting the state variable to true for next iteration.
Well, you dont have state = true as default in your factor() method. So when it runs state = false for the first time (happens when Number = 4), then it is always false. Just add the bolded line in your code and you are good to go.
void factors(){
**boolean state = true;**
for (fact = 2; fact < Number; fact++){
if (fact != Number){
if (Number % fact == 0){
state = false;
break;
}
}
}
if (state == true){
System.out.println(Number);
}
}

Java-Finding whether given numbe is prime or not by using recursive method call

I had done a lot of googling about it but unable to figure out the right answer. While I am running the below code i am always getting output as "not prime even though the input is prime number like 13".
Please help me out.
import java.util.Scanner;
public class PrimeRecurssion {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
int number = sc.nextInt();
System.out.println("Your given number is:" + prime(number,2));
}
public static String prime(int x,int temp )
{
if(x%temp == 0)
{
return("not a prime");
}
if(x != temp-1)
{
return prime(x,temp+1);
}
else
return("prime");
}
}
try
if(x - 1 != temp)
{
return prime(x,temp+1);
}
or
if(x != temp + 1)
{
return prime(x,temp+1);
}
at the moment you compare x with temp - 1
eg. x = 13, temp = 12 what leads to 13 != 12-1
=> so prime(13, 13) is called, which returns with "no prime"
Try to change
if(x != temp-1)
to
if(x != temp+1)
It will not cure all bugs you have, but probably fix it a bit.
public static String prime(int x,int temp )
{
if(x == 1)
{
return "prime";
}
if(x != temp)
{
if(x%temp == 0)
{
return("not a prime");
}
else
{
return prime(x,temp+1);
}
}
else
return("prime");
}
This works because you only want to return prime if you have reached the number itself otherwise you will hit a not prime before that point. Look at the code and see if you can figure out what is going on.

Boolean in a method not returning correctly (array formal paramater)

I am trying to make a cee-lo program in simple, simple java. I'm just learning. However when I get to my instant w. (i have simplified it for the test) it just always returns false. I can't seem to figure out why. It even displays the correct data but when it compares it it fails.
public class ceeLo
{
public static void main (String [] args)
{
Scanner scan= new Scanner (System.in);
int [] die = new int [3];
int answer;
boolean roll = true;
boolean qualifed;
boolean instantW;
boolean instantL;
do
{
System.out.println("Roll the dice?");
answer = scan.nextInt ();
if (answer == 0)
roll= false;
else
{
int i;
for (i = 0; i < die.length; i++)
{
die[i]= rollin();
System.out.println(diceTxt(die[i]));
}
qualifed = (qualify (die));
System.out.println("Qualified = " + qualifed);
instantW = (easyW (die));
System.out.println("Instant win = " + instantW);
}
}
while (roll);
}
// Generate random numbers for the roll
public static int rollin ()
{
Random rand = new Random();
int die= rand.nextInt(6);
return die;
}
//Check if dice qualify with pair
public static boolean qualify (int [] die)
{
boolean qualify;
//Pair Qualifying roll
if (die[0] == die[1] || die[0] == die[2] || die[1] == die[2])
qualify = true;
else
qualify = false;
return qualify;
}
//Check if instant win
public static boolean easyW (int [] die)
{
boolean instantW;
// show contents of die [x] for testing
System.out.println (die[0] + "" + die[1] + "" + die[2]);
if (die[0] > 2 && die [1] > 2 && die[2] > 2)
instantW = true;
else;
instantW = false;
return instantW;
}
}
Remove semi-colon after else; it should be just else
I guess the reason is,
instantW = false; is being treated as separate statement not part of else block. Which is why instantW is always being assigned to false and returning false.
It is always better to use {} to define block even though they are single liners. It is my preference.
As Greg Hewgill suggested, using single statement instantW = die[0] > 2 && die [1] > 2 && die[2] > 2; would do good than if/else.
A better way to write boolean methods is really to do something like
boolean easyW(int[] die)
{
return (die[0] > 2 && die[1] > 2 && die[2] > 2);
}
Or even better (more general)
boolean easyW(int[] die)
{
for(int roll : die)
{
if(roll < 2)
{
return false;
}
}
return true;
}
But in your case, you have a ; after your else. Fixed version:
public static boolean easyW (int [] die)
{
boolean instantW;
// show contents of die [x] for testing
System.out.println (die[0] + "" + die[1] + "" + die[2]);
if (die[0] > 2 && die [1] > 2 && die[2] > 2)
instantW = true;
else
instantW = false;
return instantW;
}

Categories

Resources