Calculating factorials in Java and printing the steps - java

The following Java code calculates the factorial of a given number and also prints the intermediate steps.
public class Factorial {
public static int getFactorial(int number) {
int n = number;
int factorial = 1;
while(n > 1) {
factorial *= n;
n--;
System.out.println(factorial + " * " + n + " = " + factorial);
}
return factorial;
}
}
When the method is called:
Factorial.getFactorial(4);
Should print to the console something like the following:
4 * 3 = 12
12 * 2 = 24
24 * 1 = 24
But instead it prints something like the following:
4 * 3 = 4
12 * 2 = 12
24 * 1 = 24
What am I doing wrong?

That is happening because you're printing the factorial variable only. Replace:
System.out.println(factorial + " * " + n + " = " + factorial);
with:
System.out.println(factorial + " * " + n + " = " + factorial * n);

Related

How to trace through basic recursive code in java

I'm new to recursion and don't understand how it works.
This was a classwork problem that had the answer 18, but I don't understand how. From what I know, this should return 6 + 5 + 4 + 3 (3 + m-1 on the recursive line)?
Are the subtraction signs not indicative of subtraction? (assuming that m = 5)
public int test(int m)
{
int value;
if (m == 0)
value = 3;
else
value = test(m - 1) + 3;
return value;
}
6 + 5 + 4 + 3 (3 + m-1 on the recursive line)? Are the subtraction
signs not indicative of subtraction?
No the +3 will happen for every one of the recursive calls, actually what your function is doing is given the value of (m times 3) + 3.
So for m=5 the recursive calls will be like:
Is m = 0 ? No so let us called recursively:
test(4) + 3
m = 4; then test(3) + 3 + 3
m = 3; then test(2) + 3 + 3 + 3
m = 2; then test(1) + 3 + 3 + 3 + 3
m = 1; then test(0) + 3 + 3 + 3 + 3 + 3
m = 0; then exit with 3 + 3 + 3 + 3 + 3 + 3
Hence, for m=5 you get 18.
A side-note you can use the ternary operator to simplify your method to:
static public int test(int m) {
return (m == 0) ? 3 : test(m - 1) + 3;
}
For visualizing what happens, scatter the code with messages:
public int test(int m)
{
System.out.println("entering test("+m+")");
int value;
if (m == 0)
value = 3;
else
value = test(m - 1) + 3;
System.out.println("returning "+value+" from test("+m+")");
return value;
}
Of course this is just the minimal program, you could also show which branch of the if was taken, m-1, and so on.
JavaScript equivalent, so it can run here in the browser:
function test(m) {
console.log("entering test(" + m + ")");
var value;
if (m == 0)
value = 3;
else
value = test(m - 1) + 3;
console.log("returning " + value + " from test(" + m + ")");
return value;
}
console.log("result: "+test(3));
On the longer run it is a good idea to learn using the debugger of the environment you are using. Among other things, debuggers can step through code line-by-line.

How to calcucate a product of n adjecent numbers using ArrayList and subList?

Im trying to solve EulerProblem8 https://projecteuler.net/problem=8 and i just don't get it , what am i doing wrong ? I tried before with a file and ArrayList but couldn't pull it off ... Whats wrong , the subtsrings , the loops , the *= ... i dont know what to do anymore?
package largestproductinaseries_ep8;
//The four adjacent digits in the 1000-digit number
//that have the greatest product are 9 × 9 × 8 × 9 = 5832.
//Find the thirteen adjacent digits in the 1000-digit number
//that have the greatest product. What is the value of this product?
public class LargestProductInASeries_EP8 {
public static void main(String[] args){
String bigNum = "73167176531330624919225119674426574742355349194934" +
"96983520312774506326239578318016984801869478851843" +
"85861560789112949495459501737958331952853208805511" +
"12540698747158523863050715693290963295227443043557" +
"66896648950445244523161731856403098711121722383113" +
"62229893423380308135336276614282806444486645238749" +
"30358907296290491560440772390713810515859307960866" +
"70172427121883998797908792274921901699720888093776" +
"65727333001053367881220235421809751254540594752243" +
"52584907711670556013604839586446706324415722155397" +
"53697817977846174064955149290862569321978468622482" +
"83972241375657056057490261407972968652414535100474" +
"82166370484403199890008895243450658541227588666881" +
"16427171479924442928230863465674813919123162824586" +
"17866458359124566529476545682848912883142607690042" +
"24219022671055626321111109370544217506941658960408" +
"07198403850962455444362981230987879927244284909188" +
"84580156166097919133875499200524063689912560717606" +
"05886116467109405077541002256983155200055935729725" +
"71636269561882670428252483600823257530420752963450";
int a = 0;
String peace = "";
String onePeace = "";
int onePeaceNum = 0;
int multi = 1;
int maxMulti = 0;
while(a<bigNum.length()-12){
peace = bigNum.substring(a, a+13);
if(!peace.contains("0")){
for(int i = 12; i>=0; i--){
onePeace = peace.substring(i, i+1);
onePeaceNum = Integer.parseInt(onePeace);
multi *= onePeaceNum;
if(multi>maxMulti){
maxMulti = multi;
}
}
multi = 1;
}
a++;
}
System.out.println(maxMulti);
}
}
//23514624000 this is Euler answer
// 2091059712 this is my output
You have a problem in your implementation, you never reset the mult value so you keep multiplying and you don't stop after 13 numbers.
Your code should be:
if (mult > maxMult) {
maxMult = mult;
mult = 1;
} else {
mult = 1;
}

String with 1000 digits, find the biggest 5 digits without an array

I know my code can be simpler and more efficient... My code is supposed to grab the biggest set of 5 digits. It works, except it only is grabbing 3 digits, what would i need to modify to change that?
public class thousandDigits {
public static void main(String[] args) {
int greatest = 0;
String num = ("73167176531330624919225119674426574742355349194934"
+ "96983520312774506326239578318016984801869478851843"
+ "85861560789112949495459501737958331952853208805511"
+ "12540698747158523863050715693290963295227443043557"
+ "66896648950445244523161731856403098711121722383113"
+ "62229893423380308135336276614282806444486645238749"
+ "30358907296290491560440772390713810515859307960866"
+ "70172427121883998797908792274921901699720888093776"
+ "65727333001053367881220235421809751254540594752243"
+ "52584907711670556013604839586446706324415722155397"
+ "53697817977846174064955149290862569321978468622482"
+ "83972241375657056057490261407972968652414535100474"
+ "82166370484403199890008895243450658541227588666881"
+ "16427171479924442928230863465674813919123162824586"
+ "17866458359124566529476545682848912883142607690042"
+ "24219022671055626321111109370544217506941658960408"
+ "07198403850962455444362981230987879927244284909188"
+ "84580156166097919133875499200524063689912560717606"
+ "05886116467109405077541002256983155200055935729725"
+ "71636269561882670428252483600823257530420752963450");
for (int n = 0; n < num.length() - 5; n++) {
greatest = ((num.charAt(n)) + (num.charAt(n+1)) + (num.charAt(n+2)) + (num.charAt(n+3))
+ (num.charAt(n+4)));
if (greatest > n) {
n = greatest;
}
}
System.out.print(greatest);
}
}
OUTPUT:
357
I think you want to use String.substring(int, int) to iterate all possible 5 character substrings, and then you might use Math.max(int, int) to update greatest. Something like
int greatest = Integer.MIN_VALUE;
for (int i = 0; i < num.length() - 4; i++) {
// int value = Integer.parseInt(num.substring(i, i + 5));
int value = Integer.parseInt(String.valueOf(num.charAt(i))
+ num.charAt(1 + i) + num.charAt(2 + i) + num.charAt(3 + i)
+ num.charAt(4 + i));
greatest = Math.max(greatest, value);
}
System.out.println(greatest);
I get 99890.
I think you are trying to add 5 consecutive characters to get sum, and store starting index of highest sum.
But you should be using Character.getNumricValue(char) to convert (num.charAt(n)) to numeric value and then add.
greatest = Character.getNumericValue((num.charAt(n)) + Character.getNumericValue((num.charAt(n+1)) + Character.getNumericValue((num.charAt(n+2)) +
Character.getNumericValue((num.charAt(n+3)) +
Character.getNumericValue((num.charAt(n+4));
You need a valirable to store old value to compare and index
if(greatest > oldGreatest) {
index = n;
}
Then finally print using index out side loop:
System.out.print((num.charAt(index)) + (num.charAt(index+1) + (num.charAt(index +2)) + (num.charAt(index +3)) + (num.charAt(index +)));
Although #ElliottFrisch and #dave provides more elegant answer, I tried to modify from your original version and here is my code (I have tested it):
public class ThousandDigits {
public static void main(String[] args) {
int greatest = 0;
String num = ("73167176531330624919225119674426574742355349194934"
+ "96983520312774506326239578318016984801869478851843"
+ "85861560789112949495459501737958331952853208805511"
+ "12540698747158523863050715693290963295227443043557"
+ "66896648950445244523161731856403098711121722383113"
+ "62229893423380308135336276614282806444486645238749"
+ "30358907296290491560440772390713810515859307960866"
+ "70172427121883998797908792274921901699720888093776"
+ "65727333001053367881220235421809751254540594752243"
+ "52584907711670556013604839586446706324415722155397"
+ "53697817977846174064955149290862569321978468622482"
+ "83972241375657056057490261407972968652414535100474"
+ "82166370484403199890008895243450658541227588666881"
+ "16427171479924442928230863465674813919123162824586"
+ "17866458359124566529476545682848912883142607690042"
+ "24219022671055626321111109370544217506941658960408"
+ "07198403850962455444362981230987879927244284909188"
+ "84580156166097919133875499200524063689912560717606"
+ "05886116467109405077541002256983155200055935729725"
+ "71636269561882670428252483600823257530420752963450");
int max = -1;
for (int n = 0; n < num.length() - 4; n++) {
greatest = ((num.charAt(n) - '0') * 10000 + (num.charAt(n + 1) - '0') * 1000
+ (num.charAt(n + 2) - '0') * 100 + (num.charAt(n + 3) - '0') * 10 + (num.charAt(n + 4) - '0'));
if (max < greatest) {
max = greatest;
}
}
System.out.print(max);
}
}
I think you'll find it's not grabbing three digits, but rather the sum of the six characters you are pulling out is a 3-digit number.
If you're after the largest five digit number, you need to extract five digits (not six) as you do and assign them a weight. So the first digit must be multiplied by 10,000, the second by 1,000 and so on.
But there's more: you're are getting the character at an index within your string. This is not what you want as it is not the same as the numeric value of that character. For that you need:
num.charAt(n) - '0'
These changes should allow you to correct your algorithm as it stands.
A more efficient approach would be to extract 5-digit sub-strings and convert them to integers. The first one would be:
Integer.parseInt(num.subString(0, 5));
You can iterate to get each one to find the greatest.

Making a method analyzing a given value [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I want to make a method that analyze a given value
void method(int value)
if this value equals for example 7, I want output to be like this :
7 = 12 * 0 + 7
if value = 13 output : 13 = 12 * 1 + 1
if value = 24 output : 24 = 12 * 2 + 0
if value = 39 output : 39 = 12 * 3 + 3
if value = 289 output : 289 = 12 * 24 + 1
and so on
12 is constant
How can I make this ?
Looks like you are looking for
12 * x + y
This means:
x = value / 12;
y = value % 12;
void method(int value) {
int x = value / 12;
int y = value % 12;
System.out.print(value + " = 12 * " + x + " + " + y);
}
The method that you are looking for could be something like the snippet that I have written above.
Here is the complete code:
public class SingleItemView {
public static void main(String[] args) {
SingleItemView.getNumber(14); // Pass the value for which you need the expression
}
public static void getNumber(int n) {
int temp1 = 0;
int temp2 = 0;
if (n > 12) {
temp1 = n / 12;
temp2 = n % 12;
System.out.println(n + " = 12 * " + temp1 + " + " + temp2);
} else {
System.out.println(n + " = 12 * 0 + " + n);
}
}
}
In your main method you are passing value to the method for which you need to expression.

Using Recursion given m(i)=1+1/2+1/3+1/4+1/5... + 1/i

This is what I have so far. I can't tell exactly how to change the numbers so it makes sense. Do I need to include the index as part of the equation? Although it seems like n1(the previous number) + (1/n2) should give me a new n2. Any thoughts?
package myrecursivemethod;
public class MyRecursiveMethod {
private static double index = 0;
private static double stoppingPoint=10;
public static void main(String[] args) {
double n1= 0;
double n2= 1;
System.out.println("index: " + index + "->" + n1 );
myRecursiveMethod(n1, n2);
}
public static void myRecursiveMethod(double n1, double n2)
{
System.out.println("index: " + index + " -> " + (n1+(1/n2)));
if (index == stoppingPoint)
return;
index ++;
myRecursiveMethod(n2, n1+(1/n2));
}
}
You need to take a look at your formula little closer and try to find a way to present this formula using similar formula with different arguments. For instance
sum(i) = 1 + 2 + 3 + 4 + ... + (i-1) + i
is same as
sum(i) = (1 + 2 + 3 + 4 + ... + (i-1)) + i
but since
1 + 2 + 3 + 4 + ... + (i-1) = sum(i-1)
we can rewrite entire formula as
sum(i) = sum(i-1) + i
(or actually)
{ sum(i-1) + i if i>0
sum(i) = {
{ 0 if i==0
Formula from your question is very similar to this one and can be presented in similar (recursive) way.

Categories