I am a starting programmer and need to program an application in java which ask for a number and then prints the first n number of Lucas Numbers. for example when 7 is put in, it outputs: 2, 1, 3, 4, 7, 11, 18.
Just to be clear, lucas numbers are defined as:
2 if n = 0
1 if n = 1
L(n-1) + L(n-2) if n>1
I am really not sure howver how to programm this in java. Because I cannot translate this into java code. I've been thinking for a while now but still can't figure it out. Also when i would have the code for calculating the Nth lucas number, i would now how to output all the first Lucan Numbers up until the Nth number. Can some of you guys help me gte on the right way or give me tips? Thanks a lot!
The definition you have for the Lucas number is recursive, i.e., to calculate the Nth lucas number, you already need to know the N-1th and the N-2nd.
A naive way to do this would be
public int lucas(int N) {
if( N == 0 ) return 2;
if( N == 1 ) return 1;
return lucas(N-1) + lucas(N-2);
}
However, you only have to print the numbers, don't you? Then it's quite easy, actually.
int L2 = 2;
int L1 = 1;
for( int i = 2; i <= N; i++ ) {
int L = L1 + L2;
print(L); //or whatever output function you have
L2 = L1;
L1 = L;
}
The idea is to keep the last two numbers, which you need to compute the next two numbers, always at hand.
PS: These Lucas numbers are just like the Fibonacci numbers with different starting values, so any algorithm for the Fibonacci numbers will do. If you're really good at math, you can even try to find a closed formula for the Lucas numbers, but it's definitely beyond high school math (search tag would be "linear difference equation with constant coefficients").
If you're not sure how to do the whole thing, break the problem down into smaller pieces until you can start.
Try taking each case, one at a time. Implement the '2 if n=0' case, test that it works. The calculation is trivial, but you will have to write the code that calls your implementation, too. The trivial case helps you check that the code around it works properly.
Then implement the next one, check it still works, implement the final one. It'll become clearer as you go.
Just in case someone is looking for a formula and happens on this page then maybe this will help. In Windows take the following line and replace each N with the desired integer, copy the modified line and paste it into Windows' calculator:
(5#/2+0.5)yN+(-(5#/2+0.5))y(-N)=
For example if you want to find the Lucus number for 7 you would paste this line into Windows' calculator:
(5#/2+0.5)y7+(-(5#/2+0.5))y(-7)=
And the result will be 29.
Related
I'm having trouble writing a recursive method that is meant to remove any odd digits from an int - for example: evenDigits(123456) should return 246. My first thought was to turn the int into a string and cycle through that way but the question explicitly states you cannot use Strings to solve it.
Any help is appreciated
EDIT: This is what I have so far, I'm not sure if its along the right lines, but I cannot figure out what to do if the last digit was to be even
public static int evenDigits(int n)
if(n==2)
{
return 2;
}
if(n==1)
{
return 0;
}
if((n%10)%2==1) //if the last digit is odd
{
return evenDigits(n/10); //run it again without the last digit
}
Since its obviously the homework, I can't provide a full solution, however here are some hints:
When you define recursion you should think when you stop (a stop condition).
If you follow the hints provided by #marksplace - then you will probably stop when the recursion will reach the point where no digits have left.
Another thing you should think of is where to store the result "accumulated so far". You'll pass it through the recursion. Its even called "accumulator" in the literature.
So when you reach the stop condition you'll return the accumulator. In addition think about how exactly you are going to update the accumulator.
Here is an example of how it can work without diving into the code:
123456
a. Last digit is 6, its even, preserve it, update an accumulator (=6)
b. recursive call for 12345
12345 - last digit is odd - remove it,
b. recursivce call for 1234
1234 - last digit is 4 - its even, preserve it, update the accumulator 6 -> 46 (here you should think about the math formula of such an update)
....
At last - stop when you reach the point, where there are no digits, accumulator will contain the answer
Good luck!
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
This is my task:
Use recursion to find 13th member of an array where every member is multiplication of last two members minus the second member. First two members are 3 and 3.
This is what I came up with:
public class Zadatak2 {
int array[] = {3,3,0,0,0,0,0,0,0,0,0,0,0};
public Zadatak2(){
find13(2);
}
public int find13(int index){
if (index == 13){
System.out.println("Member 13: " + array[index-1]);
return 0;
}
else{
array[index] = array[index-1] * array[index-2] - array[1];
System.out.println(index + " : " + array[index]);
return find13(index + 1);
}
}
}
Console output where I see index in array : value :
2 : 6
3 : 15
4 : 87
5 : 1302
6 : 113271
7 : 147478839
8 : 1947758222
9 : 465247871
10 : 818773103
11 : -459621106
12 : 383828239
Member 13: 383828239
But I am pretty sure I made a mistake or there is a better solution. Any help is appreciated.
As Kevin W. said in a comment, in the future, "if you want someone to review your code... use the codereview stackexchange". However, here are a few suggestions.
Firstly, as something to keep in mind, the problem you have is a lot like calculating the fibonacci sequence, and there are probably plenty of examples of using recursion to calculate members of that sequence.
Secondly, the way you built your recursive function makes it limited to being used only to find the 13th number in the sequence. You begin at the start of the sequence and work your way up to the 13th number, and what you are doing is basically an iterative solution to the problem with minor tweaks to make it work via recursion.
A better approach would be to generalize your function so that you can pass the sequence member number as a parameter, and the function will calculate it via recursion. The way to do this is to start at your target member number and through recursion, get the members required to make that member. This allows the function to be used to calculate any number in the sequence, not just the 13th number. It also has the added benefit that your code can be both shrunk and do more.
This is the code:
// index is the member number; it is 1 based e.g. index of 1 gives the first number in the sequence
int find(int index)
{
if (index == 1 || index == 2)
return 3;
return (find(index - 1) * find(index - 2)) - find(2);
}
When solving problems with recursion, the method generally used is to start with the problem you want to solve and break it down (as shown in my code above), rather than start with subproblems to find the larger problem (as your code shows).
When applying recursion to a sequence, write out the mathematical definition of the sequence first, and that is what must be returned from the recursive function. For example, in your problem, the definition is
a[n] = (a[n-1] * a[n-2]) - a[2]
Now take a look at the solution I wrote. What I am returning is precisely this sequence definition, just in terms of the recursive function. The base case at the beginning of the function is simply the initial member(s) required to calculate the rest of the sequence. I encourage you to work the algorithm through on paper and play with it to see exactly what is happening.
As a final note, this algorithm is horrendous in terms of run time. There are three recursive calls per call to find(), which means that finding the 13th member is on the order of 3^13, which is exponential. Exponential algorithms are terrible algorithms, and should always be avoided.
If the recursion is examined closely you can see that in order to calculate a[n], the code calculates a[n-1] and a[n-2]. But in order to calculate a[n-1], a[n-2] and a[n-3] are both calculated, meaning that a[n-2] is calculated TWICE. This observation is very important because we only went down one level of recursion. There are a total of about 3^13 member calculations occurring when all there should be are 13 (for the 13 members). All of that time performing the same calculations millions of times is a horrendous waste and is what makes exponential algorithms so awful.
So what if we stored each of the members that the function calculates? This technique is called dynamic programming, and is where answers to subproblems are stored on the way to solving a larger problem so calculations are not performed multiple times. The solution implementing dynamic programming is:
// a variable that persists across function calls such as an instance field
int[] array = new int[20]; // just giving some extra memory in case you want to calculate other members
array[0] = -1; //invalid member of the sequence since it is 1-based
array[1] = 3;
array[2] = 3;
//set the rest of the numbers to values letting you know they have not been set/found/calculated yet
for (int i = 3; i < 20; i++)
{
array[i] = -1;
}
// index is the member number; it is 1 based e.g. index of 1 gives the first number in the sequence
int find(int index)
{
if (array[index] != -1) //if already calculated that member, just return it
return array[index];
//store the answer
array[index] = (find(index - 1) * find(index - 2)) - find(2);
return array[index];
}
With this code, you can call find() for any number and it will calculate it for you, instead of just the 13th number.
Lastly, and most importantly, as Kevin W. pointed out in a comment, the presence of a negative number as a member means that you are getting numbers too big for ints. Luka Milosevic says that the 13th member is actually a number x10^90, which is too big for a long even. Doubles can work as long as you don't need more than 20 or so digits of precision, but because of at least 90 digits in the answer, doubles are not accurate enough. Fortunately Java has a class called BigInteger, which can store as large of numbers as you want, regardless of size. In order to obtain your answer, you probably have to use them, unless you want to do the math manually. The documentation for BigInteger is here.
As this is a task you were assigned to do I would like to give you a hint only. In our case a recursive function would call itself with a lower argument and finally end with some defined values.
In our case the lower values f(1) and f(2) are already defined as 3.
So f(n) = f(n-1) * f(n-2) - f(2) where f(1) = 3 and f(2) = 3.
(If I understood the task right)
Now your job is to do the coding and find f(13).
Does it help?
this is a copy of my post on mathexchange.com.
Let E(n) be the set of all possible ending arrangements of a race of n competitors.
Obviously, because it's a race, each one of the n competitors wants to win.
Hence, the order of the arrangements does matter.
Let us also say that if two competitors end with the same result of time, they win the same spot.
For example, E(3) contains the following sets of arrangements:
{(1,1,1), (1,1,2), (1,2,1), (1,2,2), (1,2,3), (1,3,2), (2,1,1), (2,1,2),(2,1,3), (2,2,1), (2,3,1), (3,1,2), (3,2,1)}.
Needless to say, for example, that the arrangement (1,3,3) is invalid, because the two competitors that supposedly ended in the third place, actually ended in the second place. So the above arrangement "transfers" to (1,2,2).
Define k to be the number of distinct positions of the competitors in a subset of E(n).
We have for example:
(1,1,1) -------> k = 1
(1,2,1) -------> k = 2
(1,2,3,2) -------> k = 3
(1,2,1,5,4,4,3) -------> k = 5
Finally, let M(n,k) be the number of subsets of E(n) in which the competitors ended in exactly k distinct positions.
We get, for example,M(3,3) = M(3,2) = 6 and M(3,1) = 1.
-------------------------------------------------------------------------------------------
Thus far is the question
It's a problem I came up with solely by myself. After some time of thought I came up with the following recursive formula for |E(n)|:
(Don't continue reading if you want to derive a formula yourself!)
|E(n)| = sum from l=1 to n of C(n,l)*|E(n-l)| where |E(0)| = 1
And the code in Java for this function, using the BigInteger class:
public static BigInteger E (int n)
{
if (!Ens[n].equals(BigInteger.ZERO))
return Ens[n];
else
{
BigInteger ends=BigInteger.ZERO;
for (int l=1;l<=n;l++)
ends=ends.add(factorials[n].divide(factorials[l].multiply(factorials[n-l])).multiply(E(n-l)));
Ens[n]=ends;
return ends;
}
}
The factorials array is an array of precalculated factorials for faster binomial coefficients calculations.
The Ens array is an array of the memoized/cached E(n) values which really quickens the calculating, due to the need of repeatedly calculating certain E(n) values.
The logic behind this recurrence relation is that l symbolizes how many "first" spots we have. For each l, the binomial coefficient C(n,l) symbolizes in how many ways we can pick l first-placers out of the n competitors. Once we have chosen them, we to need to figure out in how many ways we can arrange the n-l competitors we have left, which is just |E(n-l)|.
I get the following:
|E(3)| = 13
|E(5)| = 541
|E(10)| = 102247563
|E(100)| mod 1 000 000 007 = 619182829 -------> 20 ms.
And |E(1000)| mod 1 000 000 007 = 581423957 -------> 39 sec.
I figured out that |E(n)| can also be visualized as the number of sets to which the following applies:
For every i = 1, 2, 3 ... n, every i-tuple subset of the original set has GCD (greatest common divisor) of all of its elements equal to 1.
But I'm not 100% sure about this because I was not able to compute this approach for large n.
However, even with precalculating factorials and memoizing the E(n)'s, the calculating times for higher n's grow very fast.
Is anyone capable of verifying the above formula and values?
Can anyone derive a better, faster formula? Perhaps with generating functions?
As for M(n,k).. I'm totally clueless. I absolutely have no idea how to calculate it, and therefore I couldn't post any meaningful data points.
Perhaps it's P(n,k) = n!/(n-k)!.
Can anyone figure out a formula for M(n,k)?
I have no idea which function is harder to compute, either E(n) or M(n,k), but helping me with either of them will be very much appreciable.
I want the solutions to be generic as well as work efficiently even for large n's. Exhaustive search is not what I'm looking for, unfortunately.
What I am looking for is solutions based purely on combinatorial approach and efficient formulas.
I hope I was clear enough with the wording and what I ask for throughout my post. By the way, I can program using Java. I also know Mathematica pretty decently :) .
Thanks a lot in advance,
Matan.
E(n) are the Fubini numbers. M(n, k) = S(n, k) * k!, where S(n, k) is a Stirling number of the second kind, because S(n, k) is the number of different placing partitions, and k! is the number of ways to rank them.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Fast modulo 3 or division algorithm?
Everyone knows that modulo arithmetic can be a huge drawback on performance. Does anyone know of a good alternative for x%3 operations? I know that one exists for x%2, but I really need one for modulo 3 since I want to alternate between three buffers in a for loop.
Thanks!
Well instead of the usual "measure it" stuff an actual answer - because that stuff is actually real fun math. Although the compiler could and probably does this as well (at least modern optimizing c++ compilers, javac certainly won't and I've got no idea if the JVM does this) - so better check if it isn't already doing the work for you.
But still fun to know the theory behind the optimization: I'll use assembly because we need the higher 32bit word of a multiplication. The following is from Warren's book on bit twiddling:
n is the input integer we want the modulo from:
li M, 0x55555556 ; load magical number (2^32 + 2) / 3
mulhs q, M, n ; q = higher word of M * n; i.e. q = floor(M*n / 2^32)
shri t, n, 31 ; add 1 to q if it is negative
add q, q, t
Here q contains the divisor of n / 3 so we just compute the remainder as usual: r = n - q*3
The math is the interesting part - latex would be rather cool here:
q = Floor( (2^32+2)/ 3 * (n / 2^32) ) = Floor( n/3 + 2*n/(3*2^32) )
Now for n = 2^31-1 (largest n possible for signed 32bit integers) the error term is less than 1/3 (and non negative) which makes it quite easy to show that the result is indeed correct. For n = -2^31 we have the correction by 1 above and if you simplify that you'll see that the error term is always larger than -1/3 which means it holds for negative numbers as well.
I leave the proof with the error term bounds for the interested - it's not that hard.
If it's in a straight loop, no need to calculate a modulo. Hold a second int var that you reset every 3 steps.
int i, bn = 0;
for(i=0; i<whatever; i++) {
...
if(++bn == 3) bn = 0;
}
And that is not a premature optimisation, it's avoiding unecessary calculation.
EDIT: It was stated in OP that he was using a loop to switch between buffers, so my solution looks quite appropriate.
As for the downvote, if it was a mistake, no problem.
If 3 is known at compile time, then the compiler will generate the 'tricks' to do it as efficiently as possible. Modulo takes much longer when the divisor is unknown until run-time.
You are given a list of n numbers L=<a_1, a_2,...a_n>. Each of them is
either 0 or of the form +/- 2k, 0 <= k <= 30. Describe and implement an
algorithm that returns the largest product of a CONTINUOUS SUBLIST
p=a_i*a_i+1*...*a_j, 1 <= i <= j <= n.
For example, for the input <8 0 -4 -2 0 1> it should return 8 (either 8
or (-4)*(-2)).
You can use any standard programming language and can assume that
the list is given in any standard data structure, e.g. int[],
vector<int>, List<Integer>, etc.
What is the computational complexity of your algorithm?
In my first answer I addressed the OP's problem in "multiplying two big big numbers". As it turns out, this wish is only a small part of a much bigger problem which I'm going to address now:
"I still haven't arrived at the final skeleton of my algorithm I wonder if you could help me with this."
(See the question for the problem description)
All I'm going to do is explain the approach Amnon proposed in little more detail, so all the credit should go to him.
You have to find the largest product of a continuous sublist from a list of integers which are powers of 2. The idea is to:
Compute the product of every continuous sublist.
Return the biggest of all these products.
You can represent a sublist by its start and end index. For start=0 there are n-1 possible values for end, namely 0..n-1. This generates all sublists that start at index 0. In the next iteration, You increment start by 1 and repeat the process (this time, there are n-2 possible values for end). This way You generate all possible sublists.
Now, for each of these sublists, You have to compute the product of its elements - that is come up with a method computeProduct(List wholeList, int startIndex, int endIndex). You can either use the built in BigInteger class (which should be able to handle the input provided by Your assignment) to save You from further trouble or try to implement a more efficient way of multiplication as described by others. (I would start with the simpler approach since it's easier to see if Your algorithm works correctly and first then try to optimize it.)
Now that You're able to iterate over all sublists and compute the product of their elements, determining the sublist with the maximum product should be the easiest part.
If it's still to hard for You to make the connections between two steps, let us know - but please also provide us with a draft of Your code as You work on the problem so that we don't end up incrementally constructing the solution and You copy&pasting it.
edit: Algorithm skeleton
public BigInteger listingSublist(BigInteger[] biArray)
{
int start = 0;
int end = biArray.length-1;
BigInteger maximum;
for (int i = start; i <= end; i++)
{
for (int j = i; j <= end; j++)
{
//insert logic to determine the maximum product.
computeProduct(biArray, i, j);
}
}
return maximum;
}
public BigInteger computeProduct(BigInteger[] wholeList, int startIndex,
int endIndex)
{
//insert logic here to return
//wholeList[startIndex].multiply(wholeList[startIndex+1]).mul...(
// wholeList[endIndex]);
}
Since k <= 30, any integer i = 2k will fit into a Java int. However the product of such two integers might not necessarily fit into a Java int since 2k * 2k = 22*k <= 260 which fill into a Java long. This should answer Your question regarding the "(multiplication of) two numbers...".
In case that You might want to multiply more than two numbers, which is implied by Your assignment saying "...largest product of a CONTINUOUS SUBLIST..." (a sublist's length could be > 2), have a look at Java's BigInteger class.
Actually, the most efficient way of multiplication is doing addition instead. In this special case all you have is numbers that are powers of two, and you can get the product of a sublist by simply adding the expontents together (and counting the negative numbers in your product, and making it a negative number in case of odd negatives).
Of course, to store the result you may need the BigInteger, if you run out of bits. Or depending on how the output should look like, just say (+/-)2^N, where N is the sum of the exponents.
Parsing the input could be a matter of switch-case, since you only have 30 numbers to take care of. Plus the negatives.
That's the boring part. The interesting part is how you get the sublist that produces the largest number. You can take the dumb approach, by checking every single variation, but that would be an O(N^2) algorithm in the worst case (IIRC). Which is really not very good for longer inputs.
What can you do? I'd probably start from the largest non-negative number in the list as a sublist, and grow the sublist to get as many non-negative numbers in each direction as I can. Then, having all the positives in reach, proceed with pairs of negatives on both sides, eg. only grow if you can grow on both sides of the list. If you cannot grow in both directions, try one direction with two (four, six, etc. so even) consecutive negative numbers. If you cannot grow even in this way, stop.
Well, I don't know if this alogrithm even works, but if it (or something similar) does, its an O(N) algorithm, which means great performance. Lets try it out! :-)
Hmmm.. since they're all powers of 2, you can just add the exponent instead of multiplying the numbers (equivalent to taking the logarithm of the product). For example, 2^3 * 2^7 is 2^(7+3)=2^10.
I'll leave handling the sign as an exercise to the reader.
Regarding the sublist problem, there are less than n^2 pairs of (begin,end) indices. You can check them all, or try a dynamic programming solution.
EDIT: I adjusted the algorithm outline to match the actual pseudo code and put the complexity analysis directly into the answer:
Outline of algorithm
Go seqentially over the sequence and store value and first/last index of the product (positive) since the last 0. Do the same for another product (negative) which only consists of the numbers since the first sign change of the sequence. If you hit a negative sequence element swap the two products (positive and negative) along with the associagted starting indices. Whenever the positive product hits a new maximum store it and the associated start and end indices. After going over the whole sequence the result is stored in the maximum variables.
To avoid overflow calculate in binary logarithms and an additional sign.
Pseudo code
maxProduct = 0
maxProductStartIndex = -1
maxProductEndIndex = -1
sequence.push_front( 0 ) // reuses variable intitialization of the case n == 0
for every index of sequence
n = sequence[index]
if n == 0
posProduct = 0
negProduct = 0
posProductStartIndex = index+1
negProductStartIndex = -1
else
if n < 0
swap( posProduct, negProduct )
swap( posProductStartIndex, negProductStartIndex )
if -1 == posProductStartIndex // start second sequence on sign change
posProductStartIndex = index
end if
n = -n;
end if
logN = log2(n) // as indicated all arithmetic is done on the logarithms
posProduct += logN
if -1 < negProductStartIndex // start the second product as soon as the sign changes first
negProduct += logN
end if
if maxProduct < posProduct // update current best solution
maxProduct = posProduct
maxProductStartIndex = posProductStartIndex
maxProductEndIndex = index
end if
end if
end for
// output solution
print "The maximum product is " 2^maxProduct "."
print "It is reached by multiplying the numbers from sequence index "
print maxProductStartIndex " to sequence index " maxProductEndIndex
Complexity
The algorithm uses a single loop over the sequence so its O(n) times the complexity of the loop body. The most complicated operation of the body is log2. Ergo its O(n) times the complexity of log2. The log2 of a number of bounded size is O(1) so the resulting complexity is O(n) aka linear.
I'd like to combine Amnon's observation about multiplying powers of 2 with one of mine concerning sublists.
Lists are terminated hard by 0's. We can break the problem down into finding the biggest product in each sub-list, and then the maximum of that. (Others have mentioned this).
This is my 3rd revision of this writeup. But 3's the charm...
Approach
Given a list of non-0 numbers, (this is what took a lot of thinking) there are 3 sub-cases:
The list contains an even number of negative numbers (possibly 0). This is the trivial case, the optimum result is the product of all numbers, guaranteed to be positive.
The list contains an odd number of negative numbers, so the product of all numbers would be negative. To change the sign, it becomes necessary to sacrifice a subsequence containing a negative number. Two sub-cases:
a. sacrifice numbers from the left up to and including the leftmost negative; or
b. sacrifice numbers from the right up to and including the rightmost negative.
In either case, return the product of the remaining numbers. Having sacrificed exactly one negative number, the result is certain to be positive. Pick the winner of (a) and (b).
Implementation
The input needs to be split into subsequences delimited by 0. The list can be processed in place if a driver method is built to loop through it and pick out the beginnings and ends of non-0 sequences.
Doing the math in longs would only double the possible range. Converting to log2 makes arithmetic with large products easier. It prevents program failure on large sequences of large numbers. It would alternatively be possible to do all math in Bignums, but that would probably perform poorly.
Finally, the end result, still a log2 number, needs to be converted into printable form. Bignum comes in handy there. There's new BigInteger("2").pow(log); which will raise 2 to the power of log.
Complexity
This algorithm works sequentially through the sub-lists, only processing each one once. Within each sub-list, there's the annoying work of converting the input to log2 and the result back, but the effort is linear in the size of the list. In the worst case, the sum of much of the list is computed twice, but that's also linear complexity.
See this code. Here I implement exact factorial of a huge large number. I am just using integer array to make big numbers. Download the code from Planet Source Code.