How to add 'n' amount of odd integers? - java

I'm trying to write a program that computes the sum of the first n positive odd integers.
I'm having trouble figuring out how to incorporate n into finding the sum. I already have a do/while loop to ensure I get a positive value when assigning n value. I know that I have to use a for loop but I'm not really sure how I would do that.
Scanner input = new Scanner(System.in); // open input stream
String cleanUpStr; // clean kbd buffer
int n; // number
int sum; // sum of numbers
int cntr; // counter for loop
cleanUpStr = "nothing yet";
n = 0;
sum = 0;
cntr = 0;
//prompt user for the value of n
// use a loop to ensure a positive output
do
{
System.out.println("Enter the value of n");
n = input.nextInt();
cleanUpStr = input.nextLine();
// print error if n is invalid
if (n < 0)
{
System.out.println("Invalid n value of " + n + ", try again.");
} // end if
}while(n < 0);
for(cntr = 0; cntr < n; ++cntr)
{
} // end for
} // end main
For example: if n = 5, then this should compute 1 + 3 + 5 + 7 + 9.

The nice thing about this problem, is that you don't need to write a loop! The sum of the first n positive odd integers is the square of n (written throughout this post as n^2). This is how you express the sum in terms of n. So the following will suffice:
// Calculate the sum of first n positive odd integers by using the n^2 formula.
public static int sumOddIntegers(int n) {
return n*n;
}
If you're set on using a loop, you can do the following by observing that the i-th positive odd integer can be calculated using the formula (2i-1):
// Calculate the sum of first n positive odd integers by adding each number iteratively in a loop.
public static int sumOddIntegers(int n) {
int oddSum = 0;
for (int i = 1; i <= n; i++) {
oddSum += (2*i - 1);
}
return oddSum;
}
To visualize this, consider the following examples:
n = 1 List: {1} S(n) = 1 = 1 = n^2
n = 2 List: {1, 3} S(n) = 1 + 3 = 4 = n^2
n = 3 List: {1, 3, 5} S(n) = 1 + 3 + 5 = 9 = n^2
n = 4 List: {1, 3, 5, 7} S(n) = 1 + 3 + 5 + 7 = 16 = n^2
n = 5 List: {1, 3, 5, 7, 9} S(n) = 1 + 3 + 5 + 7 + 9 = 25 = n^2
And so on...
Here is a proof by induction showing that the sum of the first n positive odd numbers is n^2. I'm new to Stack Overflow, so I hope my formatting is legible. If it can be improved, please feel free to suggest edits :) It seems like Stack Overflow doesn't support LaTeX style exponent and subscript formatting, so I did my best.
Proof
P(n): The sum of the first n positive odd integers is n^2.
Base Case
P(1): n = 1
The n = 1 case is trivial. The list of the first n positive odd integers is simply {1}. Therefore the sum of the first n positive odd integers is 1. Since 1 = n = n^2, the predicate P(1) holds true.
Inductive Hypothesis
Assume that P(k) holds for any arbitrary positive integer k > 0.
Inductive Step
Given P(k), we will prove that P(k+1) also holds true. In words, if the sum of the first k positive odd integers is k^2, then the sum of the first (k+1) positive odd integers is (k+1)^2.
As part of this proof, assume the following lemma.
Lemma 1: The nth positive odd integer can be expressed as 2n-1.
If P(k) holds, then the sum of the first k positive odd integers {a_1, ... a_k} is k^2 where the element a_k is expressed as 2k-1 (by Lemma 1). It follows that adding the (k+1)st positive odd integer, a_(k+1) to the list of the first k positive odd integers will produce a list of the first (k+1) positive odd integers as follows: {a_1, ... a_k, a_(k+1)}. Therefore, the sum of this list of the first (k+1) positive odd integers will be equal to the sum of the list of the first k positive odd integers plus the value of a_(k+1), the (k+1)st positive odd integer. By Lemma 1, the (k+1)st positive odd integer is expressed as 2(k+1)-1 = 2k+1.
Let S(k) = the sum of the first k positive odd integers. Therefore, S(k) = k^2. The above statements imply that
S(k+1) = S(k) + a_(k+1), adding the (k+1)st positive odd integer
S(k+1) = S(k) + (2(k+1)-1), by Lemma 1
S(k+1) = S(k) + (2k+1)
S(k+1) = k^2 + (2k+1), by inductive hypothesis
S(k+1) = k^2 + 2k + 1
S(k+1) = (k+1)^2, by factoring
We have therefore shown that if S(k) = k^2, then S(k+1) = (k+1)^2. This shows that P(k) -> P(k+1).
By induction, we have proved that P(n) holds for any positive integer n > 0.
The sum of the first n positive odd integers is therefore n^2. QED.
Proof of Lemma 1:
Here is a proof of this by induction.
P(n): The nth positive odd integer, a_n, can be expressed as 2n-1.
Base case: P(1): 1 is the first positive odd integer (case n = 1).
1 = 2(1)-1 = 1.
Therefore, a_1 = 1 = 2n-1. Correct.
Inductive Hypothesis: Assume P(k) holds.
Inductive Step: If P(k) holds, then P(k+1) holds.
If P(k) holds, then the kth positive odd integer can be expressed as 2k-1. By addition, the next positive odd integer (the (k+1)st positive odd integer), would be (2k-1) + 2.
= (2k-1) + 2
= 2k-1 + 2
= 2k+2 - 1
= 2(k+1) -1
We have shown that P(k) -> P(k+1). Therefore, by induction, P(n) holds for all integers n > 0. QED.
Good luck! Hope this was helpful :)

Stream is good, but if you're a beginner a plain old for loop is your best friend.
public static int sumForOddNumbers(int total) {
int sum = 0;
for(int i = 0, odd = 1; i < total; i++, odd += 2) {
sum += odd;
}
return sum;
}

Java stream API suggests quite clear solution:
IntStream.iterate(1, i -> i + 2)
.limit(n)
.sum();
More about IntStream by link

While streams would be a great way to go about this if you were concerned with functional programming, just learning Java I would suggest the below.
int oddValue = 1;
int answer = 0;
for(cntr = 0; cntr < n; ++cntr)
{
//adds oddvalue to your answer
answer += oddValue;
//adds two to odd value (next odd)
oddValue+=2;
}

There are numerous approaches to this problem.
The way you're thinking about it, yes, you can use a loop. Generally, you have a loop counter and some maximum.
The first observation to make is that odd numbers are written in the form 2k-1. Such as k=3, 2 * 3 - 1 = 5, i.e., 5 is the 3rd odd number.
Given this, you can write a loop for k, as follows:
for (int k = 1; k <= n; k++) {
int oddNumber = 2 * k - 1; // the kth odd number
}
You can then sum these up.
Another way to do it is the way #Ruslan has shown, which uses a lambda expression to encode a similar idea. It walks over a list of integers, starting at 1 and stepping 2 each time: 1, 3, 5, 7, .... This can be done in a loop as well:
for (int oddNumber = 1; oddNumber <= (2*n - 1); oddNumber += 2) {
// calculate a sum here
}
Notice that this 2*n - 1 expression came up again. We're counting odd numbers until we reach the nth one.
There are also ways to do this without loops, such as realizing the following pattern:
1 = 1
1 + 3 = 4
1 + 3 + 5 = 9
1 + 3 + 5 + 7 = 16
1 + 3 + 5 + 7 + 9 = 25
This means that the sum of the first n odd numbers is just n^2. No loops needed. (Proofs for this are available on your favourite math website.)

Related

Meaning of the formula how to find lost element in array?

The task is to find lost element in the array. I understand the logic of the solution but I don't understand how does this formula works?
Here is the solution
int[] array = new int[]{4,1,2,3,5,8,6};
int size = array.length;
int result = (size + 1) * (size + 2)/2;
for (int i : array){
result -= i;
}
But why we add 1 to total size and multiply it to total size + 2 /2 ?? In all resources, people just use that formula but nobody explains how that formula works
The sum of the digits 1 thru n is equal to ((n)(n+1))/2.
e.g. for 1,2,3,4,5 5*6/2 = 15.
But this is just a quick way to add up the numbers from 1 to n. Here is what is really going on.
The series computes the sum of 1 to n assuming they all were present. But by subtracting each number from that sum, the remainder is the missing number.
The formula for an arithmetic series of integers from k to n where adjacent elements differ by 1 is.
S[k,n] = (n-k+1)(n+k)/2
Example: k = 5, n = 10
S[k,n] = 5 6 7 8 9 10
S[k,n] = 10 9 8 7 6 5
S[k,n] = (10-5+1)*(10+5)/2
2S[k,n] = 6 * 15 / 2
S[k,n] = 90 / 2 = 45
For any single number missing from the sequence, by subtracting the others from the sum of 45, the remainder will be the missing number.
Let's say you currently have n elements in your array. You know that one element is missing, which means that the actual size of your array should be n + 1.
Now, you just need to calculate the sum 1 + 2 + ... + n + (n+1).
A handy formula for computing the sum of all integers from 1 up to k is given by k(k+1)/2.
By just replacing k with n+1, you get the formula (n+1)(n+2)/2.
It's simple mathematics.
Sum of first n natural numbers = n*(n+1)/2.
Number of elements in array = size of array.
So, in this case n = size + 1
So, after finding the sum, we are subtracting all the numbers from array individually and we are left with the missing number.
Broken sequence vs full sequence
But why we add 1 to total size and multiply it to total size + 2 /2 ?
The amount of numbers stored in your array is one less than the maximal number, as the sequence is missing one element.
Check your example:
4, 1, 2, 3, 5, 8, 6
The sequence is supposed to go from 1 to 8, but the amount of elements (size) is 7, not 8. Because the 7 is missing from the sequence.
Another example:
1, 2, 3, 5, 6, 7
This sequence is missing the 4. The full sequence would have a length of 7 but the above array would have a length of 6 only, one less.
You have to account for that and counter it.
Sum formula
Knowing that, the sum of all natural numbers from 1 up to n, so 1 + 2 + 3 + ... + n can also be directly computed by
n * (n + 1) / 2
See the very first paragraph in Wikipedia#Summation.
But n is supposed to be 8 (length of the full sequence) in your example, not 7 (broken sequence). So you have to add 1 to all the n in the formula, receiving
(n + 1) * (n + 2) / 2
I guess this would be similar to Missing Number of LeetCode (268):
Java
class Solution {
public static int missingNumber(int[] nums) {
int missing = nums.length;
for (int index = 0; index < nums.length; index++)
missing += index - nums[index];
return missing;
}
}
C++ using Bit Manipulation
class Solution {
public:
int missingNumber(vector<int> &nums) {
int missing = nums.size();
int index = 0;
for (int num : nums) {
missing = missing ^ num ^ index;
index++;
}
return missing;
}
};
Python I
class Solution:
def missingNumber(self, nums):
return (len(nums) * (-~len(nums))) // 2 - sum(nums)
Python II
class Solution:
def missingNumber(self, nums):
return (len(nums) * ((-~len(nums))) >> 1) - sum(nums)
Reference to how it works:
The methods have been explained in the following links:
Missing Number Discussion
Missing Number Solution

Adding Values to a List and Converting to BigInteger - Java [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I'm writing a code that determines the smallest integer that is a sequence of sevens followed by some number of zeros (possibly none) that is divisible by int n. Since this number can be massive, the return value should be a BigInteger.
My code so far has an if-else ladder that covers the case that if any int n is not divisible by two or five is guaranteed to only contain sevens (no zeros). In the case where int n is not divisible by two or five, my thought process was to continue adding sevens to a LinkedList in a while loop, until that list (converted to a BigInteger) is divisible by int n. The same logic goes for the case where int n is divisible by two or five, except a two for-loops would add seven and zero to the list.
My code is getting a runtime error when converting the list to a string and then to a BigInteger, specifically on the line BigInteger numBig = new BigInteger(str);. The error is: "java.lang.NumberFormatException: Zero length BigInteger (in java.math.BigInteger)" Also, I'm not quite sure the logic is sound for the case where int n is divisible by two or five.
You don't need BigInteger for this task. The idea is the following:
First you determine the number of required zeros. Since number composed of only sevens cannot be divided by 2 or 5, the number of zeros is equal to the maximum power of 2 or 5 in number n.
Now we have a number n which is not divisible by 2 or 5. Suppose that a remainder of the division of a number composed of m sevens by n is equal to r:
777...m-times..777 mod n = r
Then number composed of (m+1) sevens will have a remainder 10*r + 7, because
777..(m+1)-times...777 = 777...m-times...7 * 10 + 7
So you can just recalculate the remainder until it becomes zero.
public static BigInteger method(int n) {
int two;
for (two = 0; n % 2 == 0; two++) n /= 2;
int five;
for (five = 0; n % 5 == 0; five++) n /= 5;
int zeros = Math.max(two, five);
int sevens = 1;
int r = 7 % n;
while (r != 0) {
r = (r * 10 + 7) % n;
sevens++;
}
// Now just make a number of 'sevens' sevens and 'zeros' zeros:
StringBuilder result = new StringBuilder();
for (int i = 0; i < sevens; i++) {
result.append("7");
}
for (int i = 0; i < zeros; i++) {
result.append("0");
}
return new BigInteger(result.toString());
}
"Zero length BigInteger" means you're trying to create a BigInteger from something that has length of 0. The stack trace would tell you on which line exactly.
I would guess the bug is in your convert method. If you pass in an empty list, it tries to convert an empty string into BigInteger with new BigInteger("")
I don't know what your algorithm is supposed to do in this case. If for example you want to convert an empty list into the number zero, you can do:
if (res.isEmpty()) return BigInteger.ZERO;

How would I loop over the permutations of N numbers with a given range, preferably without recursion?

I have N numbers, and a range, over which I have to permute the numbers.
For example, if I had 3 numbers and a range of 1-2, I would loop over 1 1 1, 1 1 2, 1 2 1, etc.
Preferably, but not necessarily, how could I do this without recursion?
For general ideas, nested loops don't allow for an arbitrary number of numbers, and recursion is undesireable due to high depth (3 numbers over 1-10 would be over 1,000 calls to the section of code using those numbers)
One way to do this, is to loop with one iteration per permuation, and use the loop variable to calculate the values that a permuation is made off. Consider that the size of the range can be used as a modulo argument to "chop off" a value (digit) that will be one of the values (digits) in the result. Then if you divide the loop variable (well, a copy of it) by the range size, you repeat the above operation to extract another value, ...etc.
Obviously this will only work if the number of results does not exceed the capacity of the int type, or whatever type you use for the loop variable.
So here is how that looks:
int [][] getResults(int numPositions, int low, int high) {
int numValues = high - low + 1;
int numResults = (int) Math.pow(numValues, numPositions);
int results[][] = new int [numResults][numPositions];
for (int i = 0; i < numResults; i++) {
int result[] = results[i];
int n = i;
for (int j = numPositions-1; j >= 0; j--) {
result[j] = low + n % numValues;
n /= numValues;
}
}
return results;
}
The example you gave in the question would be generated with this call:
int results[][] = getResults(3, 1, 2);
The results are then:
1 1 1
1 1 2
1 2 1
1 2 2
2 1 1
2 1 2
2 2 1
2 2 2

Why does my code fail the hidden input test cases?

This is the problem to be solved:
John is assigned a new task today. He is given an array A containing N integers. His task is to update all elements of array to some minimum value x , that is, A[i] = x; 1 <= i <= N; such that sum of this new array is strictly greater than the sum of the initial array.
Note that x should be as minimum as possible such that the sum of the new array is greater than the sum of the initial array.
Input Format:
First line of input consists of an integer N denoting the number of elements in the array A.
Second line consists of N space separated integers denoting the array elements.
Output Format:
The only line of output consists of the value of x.
Sample Input:
5
12345
Sample Output:
4
Explanation:
Initial sum of array= 1 + 2 + 3 + 4 + 5 = 15
When we update all elements to 4, sum of array = 4 + 4 + 4 + 4 + 4 = 20 which is greater than 15.
Note that if we had updated the array elements to 3, sum = 15 which is not greater than 15. So, 4 is the minimum value to which array elements need to be updated.
** ==> Here is my code. How can I improve it? or What is the problem in this code? **
import java.util.Scanner;
public class Test2 {
public static void main(String []args){
Scanner s=new Scanner(System.in);
int check=0, sum=0, biggest=0;
int size=s.nextInt();
if(size>=1 && size<=100000) {
int[] arr=new int[size];
for(int i=0; i<size; i++){
int temp=s.nextInt();
if(temp>=1 && temp<=1000) {
arr[i] = temp;
biggest=biggest > temp ? biggest:temp;
sum=sum+temp;
}
else break;
}
for(int i=1; i<biggest; i++){
check=(size*i)>sum ? i:0;
}
System.out.print(check);
}
else System.err.print("Invalid input size");
}
}
Issue:
for(int i=1; i<biggest; i++){
check=(size*i)>sum ? i:0;
}
There are 2 problems with this, hence it doesn't work. They are as follows-
(size*i)>sum ? i - The problem statement states that it needs minimum possible sum greater than sum of array of elements. Your code blindly assigns i to check without checking the minimality.
check=(size*i)>sum ? i:0 - So, even if you had come across some integer previously, you lost it because you assigned it to 0 if the condition is not satisfied.
I will share my idea of how would I go about this.
Approach 1
Sum all elements like you did.
Now, take average of elements - sum / size of the array. Let's say we store it in a variable average.
Print average + 1 as your answer, as that is the value that could give you minimum possible sum > sum of array itself.
Time Complexity: O(n), where n is size of the array.
Space Complexity: O(1)
Approach 2
Sum all elements like you did.
Calculate min and max for the array and store it in variables, say mini and maxi.
Now, do a binary search between mini and maxi and keep checking the minimum sum > sum criteria.
In this process, you will have variables like low, mid and high.
low = mini,high = maxi
while low <= high:
mid = low + (high - low) / 2
If mid * size <= sum,
low = mid + 1
else
high = mid - 1
Now, print low as your answer.
Let range = maxi - mini.
Time Complexity: O(n) + O(log(range)) = O(n) asymptotically, where n is size of the array.
Space Complexity: O(1)
Not sure if I completely followed what your attempt was, but there should be a pretty straightfoward solution. You know the size of the array and you can easily iterate through the array to get the value of the elements stored in it. All you need to do to find your min x is to take sumOfArray/size of array and then add one to the result to make your result higher.
In your example 15/5=3. 3+1 = 4 so that's your answer. If the numbers summed to 43, 43/5 = 8 r 3, so your answer is 9 (9*5=45). Etc.
When trying some other test cases, then the results are wrong. Try:
Input:
5
1 1 1 1 5
Expected Output: 2 Actual Output: 4
and
Input:
5
5 5 5 5 5
Expected Output: 6 Actual Output: 0

How to count powerful numbers

I have ran into a rather peculiar Java coding question today, and I wish to get some clarifications.
Here is the question posed:
A powerful number is a positive integer m that for every prime number
p dividing m, p*p also divides m.
(a prime number (or a prime) is a natural number that has exactly two (distinct) natural number divisors,
which are 1 and the prime number itself, the first prime numbers are: 2, 3, 5, 7, 11, 13, ...)
The first powerful numbers are: 1, 4, 8, 9, 16, 25, 27, 32, 36, ...
Please implement this method to
return the count of powerful numbers in the range [from..to] inclusively.
My question is what exactly IS a powerful number? Here is my definition:
A positive integer
AND
A positive integer that is divisible by a prime number
AND
A positive integer that is divisible by a primeValX*primeValX and also divisible by a primeValX
Am I wrong on my assertion? Because it doesn't return the right result when i apply my assertions to my code.
The supposed result should be 1, 4, 8, 9, 16
Here is the actual result I got:
i: 4 j: 2 ppdivm: 0 pdivm: 0
powerful num is: 4
i: 8 j: 2 ppdivm: 0 pdivm: 0
powerful num is: 8
i: 9 j: 3 ppdivm: 0 pdivm: 0
powerful num is: 9
i: 12 j: 2 ppdivm: 0 pdivm: 0
powerful num is: 12
i: 16 j: 2 ppdivm: 0 pdivm: 0
powerful num is: 16
total count: 5
Here are my codes:
public static int countPowerfulNumbers(int from, int to) {
/*
A powerful number is a positive integer m that for every prime number p dividing m, p*p also divides m.
(a prime number (or a prime) is a natural number that has exactly two (distinct) natural number divisors,
which are 1 and the prime number itself, the first prime numbers are: 2, 3, 5, 7, 11, 13, ...)
The first powerful numbers are: 1, 4, 8, 9, 16, 25, 27, 32, 36, ...
Please implement this method to
return the count of powerful numbers in the range [from..to] inclusively.
*/
int curCount=0;
int curPrime;
int[] rangePrime;
int pdivm, ppdivm;
for(int i=from; i<=to; i++){
if(i<0){
continue;
}
rangePrime = primeRange(1 , i);
for(int j=0; j<rangePrime.length-1; j++){
pdivm = i%rangePrime[j];
ppdivm = i%(rangePrime[j]*rangePrime[j]);
//System.out.println("ppdivm: " + ppdivm + " pdivm: " + pdivm);
if(pdivm == 0 && ppdivm == 0){
curCount++;
System.out.println("i: " +i + " j: " + rangePrime[j] + " ppdivm: " + ppdivm + " pdivm: " + pdivm);
System.out.println("powerful num is: " + i);
}
}
}
System.out.println("total count: " + curCount);
return curCount;
}
public static int[] primeRange(int from, int to){
List<Integer> resultant = new LinkedList<Integer>();
for(int i=from; i<=to; i++){
if(isPrime(i)== true){
resultant.add(i);
}
}
int[] finalResult = new int[resultant.size()];
for(int i=0; i<resultant.size(); i++){
finalResult[i] = resultant.get(i);
}
return finalResult;
}
public static boolean isPrime(int item){
if(item == 0){
return false;
}
if(item == 1){
return false;
}
Double curInt, curDivisor, curDivi, curFloor;
for(int i=2; i<item; i++){
curInt = new Double(item);
//System.out.println(curInt);
curDivisor = new Double(i);
//System.out.println(curDivisor);
curDivi = curInt/curDivisor;
//System.out.println(curDivi);
curFloor = Math.floor(curDivi);
if(curDivi.compareTo(curFloor) == 0){
return false;
}
}
return true;
}
public static void main(String[] args){
System.out.println(isPrime(1));
int[] printout = primeRange(1, 10);
for(int i=0; i<printout.length; i++){
System.out.print(" " + printout[i] + " ");
}
System.out.println("");
countPowerfulNumbers(1, 16);
return;
}
Thanks!
Your definition is incorrect based on the Wiki article on Powerful Numbers.
It says that for each prime p dividing your number, p^2 also divides that number.
You're getting 12 as a result because your not making the restriction of ALL primes dividing the number. So 12 is divisible by 2 and 2^2=4. However, it's also divisible by 3, but not 3^2=9.
Your definition does not match the quoted definition. Part 1 is correct. Parts 2 and (as Draco18s commented) 3 are incorrect.
Your second point is almost a duplicate of the first. The singular difference is that 1 is a positive integer, but it is not divisible by any prime numbers (1 itself is not prime, as your isPrime() function correctly returns).
Your third point starts off with a (in my opinion) awkward wording of the conditions. It seems to suggest checking if (i % (p*p)) == 0 first, and then checking (i % p) == 0, which would then be redundant and allow for missing the crucial case where (i % (p*p)) != 0 but (i % p) == 0, because the first check would cause the second to be skipped. Fortunately, your code does the checks in the correct (p, then p*p) order.
Now we come to the major error in your third point, the one that Draco18s and Frank were trying to point out. You state that a powerful number must be divisible by a primeValX*primeValX and a primeValX. The given definition states a powerful number must be divisible by primeValX*primeValX for every primeValX it is divisible by.
What's the difference? Your version requires that there is at least one primeValX*primeValX that can divide a powerful number. Thus it will exclude 1, since it is not divisible by any primes, and include numbers like 12, which is divisible by the prime 2, and 2*2.
The given version requires that for all primes that divide a powerful number, the squares of the primes also divide them. This has two implications:
All or every succeeds by default if there are no candidates. Thus, since there are no prime divisors to fail the test for 1, 1 is a powerful number.
You cannot take a shortcut and succeed as soon as you find one p and p*p that work. You have to test all prime divisors and their squares before you can know if it is a powerful number. You can fail as soon as you get one prime divisor whose square is not also a divisor.
clarification, correction of you code, and faster method below
Your definition has errors:
2 : A positive integer that is divisible by a prime number => it is the definition of any non prime number
3 : A positive integer that is divisible by a primeValXprimeValX and also divisible by a primeValX => is equivalent of A positive integer that is divisible by a primeValXprimeValX (and it includes assertion 2)
Then your definition is "any not prime number with some prime divisor ^2 "
I took the original definition,you put:
A powerful number is a positive integer m that for every prime number
p dividing m, p*p also divides m.
like this one: http://mathworld.wolfram.com/PowerfulNumber.html
Then my algorithm: check for every prime dividor X of your number, if X*X is also a dividor. If not, it is finished.
I correct your code like this
for(int i=from; i<=to; i++)
{
// CHANGE THERE (or <=3)
if(i<=1)
continue;
I put one flag:
// by default:
boolean powerfull=true;
If i is prime itself, not powerfull !
// if prime: finished !
if (isPrime(i))
continue;
The big change is in your test:
// RULE is: i divisor => ixi must be a dividor
if(pdivm == 0)
if (ppdivm != 0)
{
// You lose !
System.out.println("i: " +i + " j: " + rangePrime[j] + " ppdivm: " + ppdivm + " pdivm: " + pdivm);
powerfull=false;
}
Then, in you main loop:
if (powerfull)
{
curCount++;
System.out.println("powerful num is: " + i);
}
SECOND METHOD, faster especially if your range is big:
as pointed in my link:
Powerful numbers are always of the form a^2b^3 for a,b>=1.
Then: make a loop from 2 to range^1/2
another embedded loop from 2 to range^1/3
and multiply
like that:
int from=4;
int to=100000;
Set<Integer> set=new TreeSet<Integer>(); // automatically sorted
// Max candidates
int maxSquarecandidate= (int) Math.sqrt(to);
int maxCubeCandidates=(int) Math.pow(to,1.0/3)+1;
for (int candidate1=1; candidate1<maxSquarecandidate;candidate1++)
for (int candidate2=1; candidate2<maxCubeCandidates;candidate2++)
{
int result=candidate1*candidate1*candidate2*candidate2*candidate2;
if ((result!=1) && (result>=from) && (result<=to)) set.add(result);
}
System.out.println(set);
hope it helps !

Categories