I'm trying to make a program that finds the largest palindrome that is a product of two 3-digit numbers. This is what I have right now (I am new to programming):
int num1 = 0;
int num2 = 0;
int product = 0;
int tempProd1 = 0;
int tempProd2 = 0;
int tempProd3 = 0;
int tempProd4 = 0;
int tempProd5 = 0;
int tempProd6 = 0;
String prodCheck1 = "";
String prodCheck2 = "";
while (num1 < 1000){
while (num2 < 1000){
product = num1 * num2;
prodCheck1 = Integer.toString(product);
tempProd1 = product % 10;
product = product / 10;
tempProd2 = product % 10;
product = product / 10;
tempProd3 = product % 10;
product = product / 10;
tempProd4 = product % 10;
product = product / 10;
tempProd5 = product % 10;
product = product / 10;
tempProd6 = product % 10;
product = product / 10;
prodCheck2 = "tempProd1" + "tempProd2" + "tempProd3" + "tempProd4" + "tempProd5" + "tempProd6";
if (prodCheck1 == prodCheck2){
System.out.println(prodCheck1);
}
num2++;
}
num1++;
}
Thing is, every time I try to run it, it terminates without an error. Could someone explain what I'm doing wrong?
Edit: Thanks everyone, finally fixed it. The answer is 853358, if anyone was wondering.
Edit: Actually, the number was 906609.
One thing I noticed immediately is that after the first iteration of the inner loop, num2 is 1000 and so the inner loop will just do nothing in the remaining 999 iterations of the outer loop. You have to reset num2 to 0.
Also consider using "for" loops instead; they're designed to prevent this kind of mistake:
for (int num1=0; num1<1000; num1++) {
...
}
Another problem is that the palindrome check is wrong. You cannot compare Strings with == (it tests for object identity, not string equality -- you'd have to use equals() instead). But even that is wrong because prodCheck2 is "tempProd1tempProd2..." and doesn't contain the actual numbers. The easiest way to check for a palindrome would be:
if (tempProd1 == tempProd6 && tempProd2 == tempProd5 && tempProd3 == tempProd$) {
...
}
Equals method for strings
There are several issues here. First == should not be used to compare strings. You should use string.equals(otherString);
Contatinating words
Second you appear to be combining words when you want to combine values
prodCheck2 = "tempProd1" + "tempProd2" + "tempProd3" + "tempProd4" + "tempProd5" + "tempProd6;
will give
prodCheck2 = "tempProd1tempProd2tempProd3tempProd4tempProd5tempProd6";
always. The fact that those words happen to have the same name as some of your variables makes no difference to java.
There are many better ways to concatenate integers. But the easiest is probably as follows
prodCheck2 = tempProd1 + "" + tempProd2 + "" +tempProd3 + "" +tempProd4 + "" +tempProd5 + "" +tempProd6";
Using while when for would be better
while (num1 < 1000){
while (num2 < 1000){
......
num2++;
}
num1++;
}
This code never decreases num2, which means num2 goes 1->1000 for num1=0 and then stays at 1000 from then on. I'm guessing this isn't what you want. We could fix the while loop but really this is what a for loop is for
for(int num1=0;num1<1000;num1++){
for(int num2=0;num2<1000;num2++){
//code as before, no need to inciment or reset num1 or num2 inside the loop
}
}
Issues that don't break your code
You're declaring all your variables with very large scope. For example tempProd1 is declared outside all the loops depite only being needed inside the inner loop. Declare variables in the smallest scope possible. This will catch bugs like those we've found here. Critically num2 couldn't have accidently been made non resetting if you'd delared it within the first loop
if (prodCheck1 == prodCheck2){
System.out.println(prodCheck1);
}
is a comparison that is based solely on the identity equality of prodCheck1 and prodCheck2. Rewrite that code as:
if (prodCheck1.equals()){
System.out.println(prodCheck1);
}
to use value equality that will return true for identical strings.
Related
I'm really new to coding and just got assigned my first coding homework involving methods and returns. I managed to struggle through and end up with this, which I'm pretty proud of, but I'm not quite sure it's right. Along with that, my return statements are all on the same lines instead of formatted how my teacher says they should be ("n is a perfect number", then the line below says "factors: x y z", repeated for each perfect number. Below are the exact instructions plus what it outputs. Anything will help!
Write a method (also known as functions in C++) named isPerfect that takes in one parameter named number, and return a String containing the factors for the number that totals up to the number if the number is a perfect number. If the number is not a perfect number, have the method return a null string (do this with a simple: return null; statement).
Utilize this isPerfect method in a program that prompts the user for a maximum integer, so the program can display all perfect numbers from 2 to the maximum integer
286 is perfect.Factors: 1 2 3 1 2 4 7 14
It should be
6 is perfect
Factors: 1 2 3
28 is perfect
Factors: 1 2 4 7 14
public class NewClass {
public static void main(String[] args) {
Scanner input = new Scanner(System.in) ;
System.out.print("Enter max number: ") ;
int max = input.nextInt() ;
String result = isPerfect(max) ;
System.out.print(result) ;
}
public static String isPerfect(int number) {
String factors = "Factors: " ;
String perfect = " is perfect." ;
for (int test = 1; number >= test; test++) {
int sum = 0 ;
for (int counter = 1; counter <= test/2; counter++) {
if (test % counter == 0) {
sum += counter ;
}
}
if (sum == test) {
perfect = test + perfect ;
for (int counter = 1; counter <= test/2; counter++) {
if (test % counter == 0) {
factors += counter + " " ;
}
}
}
}
return perfect + factors ;
}
}
Couple of things you could do:
Firstly, you do not need two loops to do this. You can run one loop till number and keep checking if it's divisible by the iterating variable. If it is, then add it to a variable called sum.
Example:
.
factors = []; //this can be a new array or string, choice is yours
sum=0;
for(int i=1; i<number; i++){
if(number % i == 0){
sum += i;
add the value i to factors variable.
}
}
after this loop completes, check if sum == number, the if block to return the output with factors, and else block to return the output without factors or factors = null(like in the problem statement)
In your return answer add a newline character between perfect and the factors to make it look like the teacher's output.
You can try the solution below:
public String isPerfect(int number) {
StringBuilder factors = new StringBuilder("Factors: ");
StringBuilder perfect = new StringBuilder(" is perfect.");
int sum = 0;
for (int i = 1; i < number; i++) {
if (number % i == 0) {
sum += i;
factors.append(" " + i);
}
}
if (sum == number) {
return number + "" + perfect.append(" \n" + factors);
}
return number + " is not perfect";
}
Keep separate variables for your template bits for the output and the actual output that you are constructing. So I suggest that you don’t alter factors and perfect and instead declare one more variable:
String result = "";
Now when you’ve found a perfect number, add to the result like this:
result += test + perfect + '\n' + factors;
for (int counter = 1; counter <= test/2; counter++) {
if (test % counter == 0) {
result += counter + " ";
}
}
result += '\n';
I have also inserted some line breaks, '\n'. Then of course return the result from your method:
return result;
With these changes your method returns:
6 is perfect.
Factors: 1 2 3
28 is perfect.
Factors: 1 2 4 7 14
Other tips
While your program gives the correct output, your method doesn’t follow the specs in the assignment. It was supposed to check only one number for perfectness. Only your main program should iterate over numbers to find all perfect numbers up to the max.
You’ve got your condition turned in an unusual way here, which makes it hard for me to read:
for (int test = 1; number >= test; test++) {
Prefer
for (int test = 1; test <= number; test++) {
For building strings piecewise learn to use a StringBuffer or StringBuilder.
Link
Java StringBuilder class on Javapoint Tutorials, with examples.
I solved the Project Euler problem #14 https://projecteuler.net/problem=14 on Java, but when I run it in Powershell, it stops iterating at exactly i = 113383 every time. I rewrote the solution on python, and it works perfectly fine, albeit slowly. According to my (identical) python solution, the answer is that the number that produces the longest chain is 837799 and the chain is 524 operations long.
Why does the Java solution not finish the for-loop? Is there some kind of limit in Java on how long it can stay in a loop? I cannot come up with any other explanation. Java code below. I wrote the System.out.println(i) there just to see what is going on.
class ProjectEuler14 {
public static void main(String[] args) {
int largestNumber = 1;
int largestChain = 1;
int currentNumber;
int chainLength;
for (int i = 2; i < 1000000; i++) {
System.out.println(i);
currentNumber = i;
chainLength = 0;
while (currentNumber != 1) {
if (currentNumber % 2 == 0) currentNumber /= 2;
else currentNumber = 3 * currentNumber + 1;
chainLength++;
}
if (chainLength > largestChain) {
largestChain = chainLength;
largestNumber = i;
}
}
System.out.println("\n\nThe number under million that produces the "
+ "longest chain is " + largestNumber +
" and the chain's length is " + largestChain);
}
}
It's not the for loop. It's the while loop. The condition currentNumber != 1 is always true; forever.
In java, an int is specifically defined as an integral number between -2^31 and +2^31 -1, inclusive, and operations 'roll over'. try it!
int x = 2^31 -1;
x++;
System.out.println(x);
this prints a large negative number (in fact, precisely -2^31).
It's happening in your algorithm, and that's why it never finishes.
A trivial solution is to 'upgrade' to longs; they are just as fast, really (yay 64-bit processors!) and use 64 bits, thus giving them a range of -2^63 to +2^63-1.
Python sort of scales up its numbers into slowness silently, java makes different choices (and, for crypto and other purposes, that rollover thing is in fact desired).
If you want to go even further, you can always use BigInteger, which grows as much as you need forever (becoming slower and taking more memory as it goes).
To know rollover occurred, the 3* operation would then result in a number that is lower than the original, and you can check for that:
replace:
else currentNumber = 3 * currentNumber + 1;
with:
else {
int newNumber = currentNumber * 3 + 1;
if (newNumber < currentNumber) throw new IllegalStateException("Overflow has occurred; 3 * " + currentNumber + " + 1 exceeds ints capacities.");
currentNumber = newNumber;
}
and rerun it. You'll see your app nicely explain itself.
The currentNumber is exceeding size of int, use long instead.
Do you hava problem overflow int.
Change int to long.
long largestNumber = 1;
long largestChain = 1;
long currentNumber;
long chainLength;
for (int i = 2; i < 1000000; i++) {
//System.out.println(i);
currentNumber = i;
chainLength = 0;
while (currentNumber != 1) {
//System.out.println("# = " + currentNumber);
if (currentNumber % 2 == 0) {
currentNumber /= 2;
} else {
currentNumber = (3 * currentNumber) +1 ;
}
chainLength++;
}
// System.out.println("################################ " + i);
if (chainLength > largestChain) {
largestChain = chainLength;
largestNumber = i;
}
}
System.out.println("\n\nThe number under million that produces the "
+ "longest chain is " + largestNumber
+ " and the chain's length is " + largestChain);
I am currently in a Java 1 class, and made a number guessing game for fun. Basic take input, tells you if it's too high or low, then lets you guess again. I thought it would be interesting to make it so the computer guesses as well, then compares your guesses to its. I have all of the generation and comparing working, but it continues to guess numbers without taking the greater/less than into account, which I want to add. I have:
public static void autoPlay(int num){
Random rand = new Random();
int guess1 = rand.nextInt(100) + 1;
int counter = 0;
while(guess1 != num){
counter++;
int guess = rand.nextInt(100) + 1;
int initialHigh = 100;
int initialLow = 0;
// I want it to guess smart and recognize if it were too high or too low, and generate a number between there
if(guess1 > num){
int newGuess = rand.nextInt(initialHigh - guess1) + 1;
}else if(guess1 < num){
int newGuess2 = rand.nextInt(initialLow + guess1) + 1;
}
initialLow = guess;
initialHigh = guess;
guess1 = guess;
System.out.printf("%3d", guess1);
}
System.out.println("It took " + counter + " guesses to get the correct number");
}
I can't tell what is wrong with my math in the if statement, or if theres just something I can call to do that.
If you want to avoid duplicates, then generate the appropriate numbers and shuffle it (for a full random function):
List<Integer> values = IntStream.range(0, /* max */).collect(Collectors.toList());
Collections.shuffle(values);
int guesses = values.indexOf(/* some number */) + 1;
The list would be fully randomly ordered, so you'd guess in order of the randomized list, thus the index is the number of guesses (-1, since it's 0-indexed)
The problem with your code is that you are just using the same bounds for the random number. You generate new bounds here:
if(guess1 > num){
int newGuess = rand.nextInt(initialHigh - guess1) + 1;
}else if(guess1 < num){
int newGuess2 = rand.nextInt(initialLow + guess1) + 1;
}
But you don't use them at all, you just reuse the values you had before:
initialLow = guess;
initialHigh = guess;
guess1 = guess;
System.out.printf("%3d", guess1);
You must use the values produced by newGuess and newGuess2 (althought you don't need these two variables, declare one of them outside the if and just assign a value to it inside the if). Then you will be using updated values.
I also noticed that you created many variables that store the same value, such as guess and guess1, which you don't need, you just need to declare one of them and reuse later (so you can save memory : ) ).
Also, I see a problem in setting initialHigh and initialLow both as guess, why would you want that?
Try to review your code logic and clean up some variables, some of them are duplicated.
But, in summary, I think the problem is that you are generating new bounds but you are not using them.
Let me know if this helped you and remember to upvote/select this answer as correct if it did : ). If you still have questions, post again.
My assignment asks for a command-line input to be put through nested while loops to find if a number is a happy number or not. So far I have this:
int i = 0;
int sum = 0;
int dig2, dig1, dig3, dig4, dig1next, dig2next, dig3next;
int digit1sum, digit2sum, digit3sum;
happyNumber = number;
while (i < 500){
while (happyNumber > 0){
while (sum!=1){
dig3 = happyNumber / 100;
dig2 = happyNumber % 10;
dig1 = happyNumber / 10;
dig2next = dig2 % 10;
dig1next = dig1 % 10;
dig3next = dig3 % 10;
digit1sum = dig1next * dig1next;
digit2sum = dig2next * dig2next;
digit3sum = dig3next * dig3next;
sum = digit1sum + digit2sum + digit3sum;
happyNumber = sum;
}
System.out.println("It is a happy number.");
System.exit(0);
}
i++;
System.out.println(i);
System.exit(0);
}
I set i<500 so when i++ reaches 500, the loop should stop. I've pretty much tried putting i++ in every section of the code possible, it never works. what am i doing wrong here?
also: i am not allowed to use for loops or do-while loops on this assignment. i have to use nested while loops only
Happy number: Starting with any positive integer, replace the number by the sum of the squares of its digits, and repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1(how long the loop will be: 500).
After a quick glance at your code:
while (sum!=1)
....
sum = digit1sum + digit2sum + digit3sum;
happyNumber = sum;
This while test is likely to be always true -> infinite loop -> stack overflow
You will never get out of your innermost while-loop in case of a number that loops endlessly (it is by no means stopped by the 500- limit and your logic is wrong here).
Secondly, something to think about:
digit1sum = dig1next*dig1next;
digit2sum = dig2next*dig2next;
digit3sum = dig3next*dig3next;
these (digitxsum) will always be positive.
sum = digit1sum + digit2sum + digit3sum;
sum will therefore always be positive
happyNumber = sum;
happynumber will always be positive
while (happyNumber > 0)
what is this for?
I'm fairly new to java and I'm attempting to create a simple java program that checks for arithmetic and geometric sequences and lists the desired amount of terms from the sequence out. Everything in the program works properly until the printing of the next terms in the for statement occurs. There is no errors, and I can't find anything wrong. Any help is appreciated.
if(num2-num1 == num3-num2){
d = num2-num1;
System.out.println("This is a arithmetic sequence.\nCommon Difference = " + d);
System.out.println("How many terms of this sequence would you like?");
int a = scanner.nextInt();
for(int i = 1; i >= a; i++){
num3 += d;
System.out.println(num3);
}
suc = 1;
}
Please change i>=a to i<=a.
your for loop parameters are wrong :
change the for loop :
for(int i = 1; i >= a; i++)
to something like this :
for(int i = 1; i <= a; i++)