I need to print the factors of a perfect number. Here's the gist of my main class:
ArrayList<Integer> perfNums = new ArrayList<>();
Scanner in = new Scanner(System.in);
System.out.print("Enter the upperbound: ");
upperbound = in.nextInt();
for (int i = 1; i <= upperbound; i++) {
if (isPerfect(i)) { //boolean to check if number is a perfect number
perfNums.add(i);
}
}
System.out.println("Perfect numbers between 1 and " + upperbound + " are:");
for (int i = 0; i < perfNums.size(); i++) {
System.out.print(perfNums.get(i) + " = ");
printFactor((int)perfNums.get(i));
System.out.println();
}
Here's the printFactor class.
private static void printFactor(int number){
int factor = 1;
while(factor < number){
if (number%factor == 0) System.out.print(factor+ " + ");
//I don't know how to print the + sign otherwise.
factor++;
}
}
And here's a sample output:
Enter the upperbound: 10000
Perfect numbers between 1 and 10000 are:
6 = 1 + 2 + 3 +
28 = 1 + 2 + 4 + 7 + 14 +
496 = 1 + 2 + 4 + 8 + 16 + 31 + 62 + 124 + 248 +
8128 = 1 + 2 + 4 + 8 + 16 + 32 + 64 + 127 + 254 + 508 + 1016 + 2032 + 4064 +
I've got the main gist of it but I've struggled with an output issue. Due to the restrictions of my online submission system, my output needs to fit exact specifications.
My question is how do I go about printing all the factors of my perfect number but removing the + sign at the end? (e.g)6 = 1 + 2 + 3
I'm not too sure of many methods to print from a while loop. Would a for-loop be better for my goals? Or are there alternative methods to print the factors of a number?
The least amount of change to address this might be something like this:
private static void printFactor(int number)
System.out.print(1);
int factor = 2;
while (factor<number) {
if (number%factor == 0) System.out.print(" + " + factor);
factor++;
}
}
1 is always a factor, so you can print that before the loop and then prepend + to every subsequent factor.
You should cache the output you want to print into a StringBuilder. Then you are able to remove the last plus sign before you print the whole String. It also has a better performance.
private static void printFactor(int number)
{
StringBuilder output = new StringBuilder();
int factor = 1;
while (factor < number)
{
if (number % factor == 0)
output.append(factor + " + ");
factor++;
}
// remove last plus sign
output.deleteCharAt(output.length() - 1);
// print the whole string
System.out.print(output.toString());
}
Since factor starts from value 1 and number % 1 == 0 will always be true, you might print 1 first and then flip factor and + in System.out.print. Like this:
private static void printFactor(int number) {
if(number > 0) {
System.out.print(1);
}
int factor = 2;
while (factor<number) {
if (number % factor == 0) {
System.out.print(" + " + factor);
}
factor++;
}
}
Not the best solution, but it will do the job.
Try to create a variable String numb and use substring method like this:
String numb ="";
while(factor<number){
if(number%factor == 0)
numb= numb + factor+ " + ";
factor++;
}
System.out.print(numb.substring(0, numb.trim().length()-1));
Just for the sake of using Java 8 :)
private static void printFactor(int number){
System.out.println(IntStream.range(1, number)
.filter(p -> number % p == 0)
.mapToObj(i -> String.valueOf(i))
.collect(Collectors.joining(" + ")));
}
Thanks everyone for the quick response. You all have been a lifesaver, and I managed to pick up some new things to consider when I code in the future.
Anyway, while waiting for a reply I was fiddling with the code and came up with a rather inelegant solution, if anybody's interested. Here's the changes to the main class:
System.out.println("Perfect numbers between 1 and " + upperbound + " are:");
for(int i=0; i<perfNums.size(); i++){
System.out.print(perfNums.get(i) + " = ");
outputString = printFactor2(perfNums.get(i));
if(outStr.endsWith(" + ")) outStr = outStr.substring(0, outStr.length()-3);
//because the submission system would cry foul with even a single extra space
System.out.println(outStr);
}
And here's the changes to the printFactor class:
private static String printFactor2(int number){
String out = "";
int factor = 1;
while(factor<number){
if(number%factor == 0) out += factor + " + ";
factor++;
}
return out;
}
Basically, what I did was append the factors to a string, then removing the trailing + sign using the substring method. On hindsight, I probably should've called the substring method inside the printFactor class instead. Something like return out.substring(0, out.length()-3); perhaps?
Nevertheless, thanks everyone!
Related
I made a program for the question and it's working fine, but in some cases it's not working like when I enter 656, it's showing like this:
The error
The code is showed below:
public static void main(String[] args) {
Scanner rx = new Scanner(System.in);
int ui,uiy,troll3,troll1;
float uix,uis,uiz,uit;
System.out.println("Enter a valid three digit number to calculate the frequency of the digits in it. \n");
ui = rx.nextInt();
if(ui>99&&ui<=999) {
uis = (float) ui;
//System.out.println(uis+" uis");
uix = uis / 10;
//System.out.println(uix+" uix");
uiy = (int) uix;
//System.out.println(uiy+" uiy");
troll3 = (int) ((uix - uiy) * 10); //1st digit
//System.out.println("3d " + troll3);
uiz = uix / 10;
//System.out.println(uiz+ " uiz");
troll1 = (int) uiz;
//System.out.println("1d " + troll1);
uit = (uiz - troll1) * 10;
//System.out.println(uit+" uit");
int troll2 = (int) uit;
//System.out.println("2d " + troll2);
if (troll1 == troll2 && troll1 == troll3) {
System.out.println("The number " + troll1 + " appears three times.");
} else if (troll1 != troll2 && troll2 != troll3 && troll1 != troll3) {
System.out.println("The number " + troll1 + " appears one time.");
System.out.println("The number " + troll2 + " appears one time.");
System.out.println("The number " + troll3 + " appears one time.");
} else if (troll1 == troll2) {
System.out.println("The number " + troll1 + " appears two times.");
System.out.println("The number " + troll3 + " appears one time.");
} else if (troll1 == troll3) {
System.out.println("The number " + troll3 + " appears two times.");
System.out.println("The number " + troll2 + " appears one time.");
} else if (troll2 == troll3) {
System.out.println("The number " + troll2 + " appears two times.");
System.out.println("The number " + troll1 + " appears one time.");
}
}
else{
System.out.println("The entered number is invalid");
}
}
It mostly gives an error when it consists of digit 5 in the middle. It shows an increment in values and swap in values. Please do help.
Thanks in advance! :-)
Why are you converting to float? float and double attempts to represent an infinite infinity of numbers (there are an infinite amount of integers. Between 2 integers, there are an infinite amount of numbers too: An infinite amount of infinities)... using only 32 bits. This is obviously impossible so instead only a few numbers are representable, and anything else is silently rounded to one of the select few. This means float and double introduce rounding errors.
After any math done to any double or float, == is broken. You can't use those; at best, you can try 'delta equality' (not a == b, but Math.abs(a - b) < 0.00001) but making the claim that your code works for all possible inputs becomes very difficult indeed, it's not going to be very fast, and the code readability isn't great either. So, don't.
Stop using floats, problem solved.
Your 'math' to get the individual digits is a bit circumspect and isn't going to just work if you replace things with int either. What you're missing is the % operator: Module (a.k.a. remainder).
Given, say, 656:
int in = 657;
int digit1 = in % 10;
in = in / 10;
System.out.println(in); // 65
System.out.println(digit1); // 7
int digit2 = in % 10;
in = in / 10;
System.out.println(in); // 6
System.out.println(digit1); // 5
int digit3 = in;
I am practicing Java and I was trying to create a program to calculate the amount of ways an number could be divided using a set number of dividers.
For instance:
100 is the number and the dividers are 50,20,5. What are the possible divisions.
The answer would be:
Amount of 50 : 0, Amount of 20 : 0, Amount of 10 : 10
Amount of 50 : 0, Amount of 20 : 1, Amount of 10 : 8
Amount of 50 : 0, Amount of 20 : 2, Amount of 10 : 6
Amount of 50 : 0, Amount of 20 : 3, Amount of 10 : 4
Amount of 50 : 0, Amount of 20 : 4, Amount of 10 : 2
Amount of 50 : 1, Amount of 20 : 0, Amount of 10 : 5
Amount of 50 : 1, Amount of 20 : 1, Amount of 10 : 3
Amount of 50 : 1, Amount of 20 : 2, Amount of 10 : 1
Amount of 50 : 2
I wrote a code that asks the user an amount and 3 dividers. Now I am trying to figure out if there is a way to dynamically create a code for as many dividers as the user wants. The code is in a way very repetitive and there is a certain pattern to add another divider but I cannot figure out how to implement this dynamic change to the code.
The first code I came up with to do this is the following:
public class Test2 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Insert the amount:");
int amount = scanner.nextInt();
List<Integer> dividers = new ArrayList<>();
System.out.println("Insert the first divider:");
int tempDivider = scanner.nextInt();
if (!dividers.contains(tempDivider)) {
dividers.add(tempDivider);
}
while (dividers.size()<3) {
System.out.println("Insert the next divider: (" + (3-dividers.size()) + " more to go)");
tempDivider = scanner.nextInt();
if (!dividers.contains(tempDivider)) {
dividers.add(tempDivider);
}
}
dividers.sort(Collections.reverseOrder());
System.out.print("Dividers are: ");
System.out.println(dividers);
int getal1 = dividers.get(0);
int getal2 = dividers.get(1);
int getal3 = dividers.get(2);
int fiftyAmount = amount / getal1;
int fiftyRemainder = amount % getal1;
for (int i = 0; i <= fiftyAmount; i++) {
int currentFiftyAmount = amount - (getal1 * i);
int twentyAmount = currentFiftyAmount / getal2;
int twentyRemainder = currentFiftyAmount % getal2;
if (twentyAmount == 0) {
StringBuilder output = new StringBuilder();
output.append("Amount of " + getal1 + " banknotes: " + i);
if (fiftyRemainder != 0) output.append(", Remainder: " + fiftyRemainder);
System.out.println(output);
} else {
for (int j = 0; j <= twentyAmount; j++) {
int currentTwentyAmount = currentFiftyAmount - (getal2 * j);
int tenAmount = currentTwentyAmount / getal3;
int tenRemainder = currentTwentyAmount % getal3;
if (tenAmount == 0) {
StringBuilder output = new StringBuilder();
output.append("Amount of " + getal1 + " banknotes: " + i + ", Amount of " + getal2 + " banknotes: " + j);
if (tenRemainder != 0) output.append(", Remainder: " + twentyRemainder);
} else {
StringBuilder output = new StringBuilder();
output.append("Amount of " + getal1 + " banknotes: " + i + ", Amount of " + getal2 + " banknotes: " + j +
", Amount of " + getal3 + " banknotes: " + tenAmount);
if (tenRemainder != 0) output.append(", Remainder: " + tenRemainder);
System.out.println(output);
}
}
}
}
}
}
I tried to make this more abstract to figure out a way to automate the creation of the extra dividing loops but I cannot figure it out.
The more abstract version I wrote is the following:
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Insert the amount:");
int amount = scanner.nextInt();
List<Integer> dividers = new ArrayList<>();
System.out.println("Insert the first divider:");
dividers.add(scanner.nextInt());
int divider;
while (dividers.size()<2) {
System.out.println("Insert the next divider: (" + (2-dividers.size()) + " more to go)");
divider = scanner.nextInt();
if (!dividers.contains(divider)) {
dividers.add(divider);
}
}
dividers.sort(Collections.reverseOrder());
System.out.print("Dividers are: ");
System.out.println(dividers);
int divided1Amount = amount / dividers.get(0);
int divided1Remainder = amount % dividers.get(0);
for (int i = 0; i <= divided1Amount; i++) {
int currentDivided1Amount = amount - (dividers.get(0) * i);
int divided2Amount = currentDivided1Amount / dividers.get(1);
int divided2Remainder = currentDivided1Amount % dividers.get(1);
if (divided2Amount == 0) {
StringBuilder output = new StringBuilder();
output.append(dividers.get(0) + ":" + i);
if (divided1Remainder != 0) {
output.append(", Remainder: " + divided1Remainder);
}
System.out.println(output);
} else {
StringBuilder output = new StringBuilder();
output.append(dividers.get(0) + ":" + i + "," + dividers.get(1) + ":" + divided2Amount);
if (divided2Remainder != 0) {
output.append(", Remainder: " + divided2Remainder);
}
System.out.println(output);
}
}
}
}
This is also available on GitHub: https://github.com/realm1930/rekendin/blob/master/src/Main.java
Could anybody please enlighten me. I am sorry if I am not clear at my description of the issue.
Thanks
While a fixed number of dividers can be well approached with nested loops, I suggest for the general case to write the solution as a recursive function.
This problem is a good fit for dynamic programming. What I mean by this is that the problem can be broken down into simpler subproblems, and in this way the solution is naturally implemented with recursion. For instance, in your example of expressing 100 as a sum of multiples of 50, 20, and 10, there are three solutions found that all use one 50:
Amount of 50 : 1, Amount of 20 : 0, Amount of 10 : 5
Amount of 50 : 1, Amount of 20 : 1, Amount of 10 : 3
Amount of 50 : 1, Amount of 20 : 2, Amount of 10 : 1
Look at this as solving the subproblem of finding the ways that value 50 can be expressed as multiples of 20 and 10 (that is, 50 is equal to 20*0 + 10*5, 20*1 + 10*3 and 20*2 + 10*1). So you can divide-and-conquer the original problem in this sense.
Let X be the number (e.g. 100) to express, and D1, D2, ... DN the dividers. Here is a possible outline:
If there is just one divider, N = 1, it is easy: there just zero or one solution depending on whether D1 divides X.
Otherwise, possible solutions might have D1 with any multiple from 0, 1, ..., X/D1. So make a loop m1 = 0, 1, ..., X/D1, and recursively solve the subproblem having X' = X - m1*D1 and the remaining dividers D2, ..., DN. This subproblem has one fewer divider, so after enough recursions it reduces to the N = 1 case.
That solves the problem. Note, though, that fully recursing may result in a combinatorially vast number of subproblems to solve. So for efficient solution it is a good idea to store or "memoize" the solutions of previously-solved subproblems in a table so that work isn't repeated.
Other thoughts:
Let Q be the greatest common divisor (GCD) of all the dividers {D1, ..., DN}. If X isn't divisible by Q, then there are no solutions, in which case we can skip the above recursive search entirely. E.g. there is no way to express X = 103 with dividers 50, 20, and 10. This GCD test can also be applied to every subproblem so that some recursive calls can return early.
This problem is a kind of Diophantine equation, more specifically, it is related to the Frobenius coin problem and Frobenius numbers. There is a mathoverflow post discussing it.
do
{
System.out.println("Enter either limit, abundant, deficient, perfect, or prime = value:");
condition = scan.next();
String equals = scan.next();
num = scan.next();
value=Integer.parseInt(num);
if (Type.isInteger(condition) || !Type.isInteger(num) || value<0)
System.out.println("Please enter in condition = value format");
else
break;
}while(stop);
System.out.println("N" + "\t" + "Abundant" + " " + "Deficient" + " " + "Perfect" + " " + "Prime");
sigma = 0; //sets sigma=0
n=1;
while (stop)
{
for (f = 1; f <= n/2; f++)
{
if (n % f == 0)
sigma = sigma + f;
}
System.out.print(n + "\t");
if (sigma>n)
acount++;
if (sigma == 1)
p++; //prime counter
if (sigma<n)
dcount++; //deficient counter
if (sigma == n)
pcount++; //perfect counter
System.out.print(acount + " " + "\t" + " " + dcount + "\t" + " " + pcount + "\t" + " " + p); //prints abundant column
System.out.println();
if (condition.equals("limit"))
{
if(n<value)
n++;
else
break;
}
if(condition.equals("abundant"))
{
if(acount<value)
n++;
else
break;
}
if (condition.equals("deficient"))
{
if (dcount<value)
n++;
else
break;
}
if (condition.equals("perfect"))
{
if (pcount<=value)
n++;
else
break;
}
if (condition.equals("prime"))
{
if (p<value)
n++;
else
break;
}
}
}
}
Essentially, the code is supposed to print out 5 columns: n, abundant, deficient, perfect, and prime. And each row will have a column of numbers under it. The user is supposed to type in specifications in a 'condition = value' format. So if they type in limit = 10 then it will print 10 rows. And if they input abundant = 10 then it will continue to print rows until the value of abundant reaches 10. The problem I am encountering is that my program will infinity loop when I input certain values and I am not sure what the cause is. For example, if I input deficient = 2 it will work fine but if I input deficient = 10 then it will start an infinite loop. However, when I input perfect = 10 it will only print out 1 row. Like my title says I am a beginner and I can't figure out what is causing the error. Any suggestions?
Try initializing the value of sigma inside the loop:
while (stop)
{
sigma = 0;
...
}
Since sigma is never reset to zero, it just keeps growing for every number. So you will quickly stop finding deficient numbers or perfect numbers, and everything will be be abundant. That's why the abundant keyword works, but deficient does not.
I have written a simple program in java to find the factorial, which works fine. I am now trying to refine the output, but I'm not sure how to do it.
My Program:
import java.util.Scanner;
public class UserInput {
public static void main(String[] args) {
int fact = 1;
Scanner number = new Scanner(System.in);
System.out.println("Enter the number : ");
int n = number.nextInt();
if (n < 0) {
System.out.println("Enter positive number");
} else {
System.out.print("Factorial Sequence is :");
for (int i = n; i >= 1; i--) {
fact = fact * i;
System.out.print(i + "*");
}
System.out.println("Factorial of number " + n + " is :" + fact);
}
}
}
Output shown is in this format (a single line, * after the 1):
Factorial Sequence is :5*4*3*2*1*Factorial of number 5 is :120
I want output in this format:
Factorial Sequence is :5*4*3*2*1
Factorial of number 5 is :120
Since 1 is not going to modify the factorial result your code can be rewriten as:
for (int i = n; i >= 2; i--) {
fact = fact * i;
System.out.print(i + "*");
}
System.out.println("1");
Another option is to use string concatenation during your for loop:
String s = "Factorial Sequence is :";
for (int i = n; i >= 1; i--) {
fact = fact * i;
s += i + (i > 1 ? "*" : "");
}
System.out.println(s);
Only 'benefit' this has over the other options is it saves calling System.out.print each iteration, at the expense of a string concatenation operation. Probably no performance difference at all, and certainly not significant here, but it is an alternate means to the same end.
EDIT: Use #demostene's excellent suggestion to avoid the final '*' after the final '1' - it avoids the conditional expression within the for loop, which is really nice as your factorial becomes larger.
To make the gap, you can add an \n literal to represent a newline.
System.out.println("\nFactorial of number " + n + " is :" + fact);
And for the last *, you can either remove it at the end or not add it if i is 1..
System.out.print(i + (i > 1?"*":""));
This says if i is greater than 1, return a *, otherwise return an empty string.
Just add a print line statement:
System.out.println(); // add this line
System.out.println("Factorial of number " + n + " is :" + fact);
I am working on a program where I have to use recursion to calculate the sum of 1/3 + 2/5 + 3/7 + 4/9 + ... + i / (2i + 1). However, I am not sure how to make my program show the term that must be added in order to reach the number enter by the user. For example. If I enter 12, I want to know how many terms of the series [1/3 + 2/5 + 3/7 + 4/9 + ... + i / (2i + 1)] were added to get approximately to the number 12.
What I don't want to get is the sum of inputting 12 which in this case is 5.034490247342584 rather I want to get the term that if I were to sum all numbers up to that term I would get something close to 12.
Any help will be greatly appreciated!
This is my code
import java.util.Scanner;
public class Recursion {
public static void main(String[] args) {
double number;
Scanner input = new Scanner(System.in);
System.out.println("Enter a value= ");
number = input.nextInt();
System.out.println(sum(number) + " is the term that should be added in order to reach " + number);
}
public static double sum(double k) {
if (k == 1)
return 1/3;
else
return ((k/(2*k+1))+ sum(k-1));
}
}
You have this question kind of inside out. If you want to know how many terms you need to add to get to 12, you'll have to reverse your algorithm. Keep adding successive k / (2k + 1) for larger and larger k until you hit your desired target. With your current sum method, you would have to start guessing at starting values of k and perform a sort of "binary search" for an acceptably close solution.
I don't think that this problem should be solved using recursion, but... if you need to implement it on that way, this is a possible solution:
import java.util.Scanner;
public class Recursion {
public static void main(String[] args) {
double number;
Scanner input = new Scanner(System.in);
System.out.println("Enter a value= ");
number = input.nextInt();
double result = 0;
double expectedValue = number;
int k = 0;
while (result < expectedValue) {
k++;
result = sum(k);
}
System.out.println(k
+ " is the term that should be added in order to reach "
+ number + " (" + sum(k) + ")");
}
public static double sum(double k) {
if (k == 1)
return 1 / 3;
else
return ((k / (2 * k + 1)) + sum(k - 1));
}
}