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 !
Related
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 3 years ago.
Improve this question
I am trying to find the O(N) solution with Divide & Conquer for the next problem:
Given a circularly sorted array, I need the sum of the positive numbers on it. i.e:
If the array is: {-2, 0, 3, 4, 11, 13, -23, -15, -8}
Then the algorithm should return 31.
I think I'm close to it with the following code, but it's weirdly returning -17 and I cannot find the problem debugging:
public class Main {
private static final int[] TEST_VECTOR = new int[]{-2, 0, 3, 4, 11, 13, -23, -15, -8};
public static int sumPositives2(int[] vector) {
return maximumSum(vector,0, vector.length - 1);
}
// Function to find Maximum subarray sum using
// divide and conquer
public static int maximumSum(int[] A, int left, int right)
{
// If array contains only one element
if (right == left) {
return A[left];
}
// Find middle element of the array
int mid = (left + right) / 2;
// Find maximum subarray sum for the left subarray
// including the middle element
int leftMax = Integer.MIN_VALUE;
int sum = 0;
for (int i = mid; i >= left; i--)
{
if(A[i] > 0) {
sum += A[i];
}
}
// Find maximum subarray sum for the right subarray
// excluding the middle element
int rightMax = Integer.MIN_VALUE;
sum = 0; // reset sum to 0
for (int i = mid + 1; i <= right; i++)
{
if(A[i] > 0) {
sum += A[i];
}
}
// Recursively find the maximum subarray sum for left
// subarray and right subarray and tale maximum
int maxLeftRight = maximumSum(A, left, mid) +
maximumSum(A, mid + 1, right);
// return maximum of the three
return maxLeftRight + leftMax + rightMax;
}
public static void main(String[] args)
{
System.out.println("The Maximum sum of the subarray is " +
maximumSum(TEST_VECTOR, 0, TEST_VECTOR.length - 1));//Should be 31
}
}
Edit: Would this solution be O(N)?
Thank you for your time.
You can easily get an O(n) solution if you go through the array once and sum up only positive numbers. An enhanced for loop seems suitable:
public static void main(String[] args) {
int[] circularlySortedArray = {-2, 0, 3, 4, 11, 13, -23, -15, -8};
// define a variable for the sum
int sumOfPositives = 0;
// go through all numbers in the array (n numbers)
for (int number : circularlySortedArray) {
// check if the number is positive
if (number >= 0) {
// and add it to the sum variable
sumOfPositives += number;
}
}
// then print the result
System.out.println("The sum of positive numbers is " + sumOfPositives);
}
The output in this case is
The sum of positive numbers is 31
The sorting does not have any influence on the algorithm.
Your solution would be O(n) if it was working, but you don't really have to divide and conquer here because it cannot be done in less than O(n) anyway, it's not a binary search.
EDIT
Since the text and code above seems not to be satisfying enough, I re-thought my statement about divide and conquer here. The task may be done in less than n steps, but O(n) will still be correct. The sorting does provide a possibility of not going through all elements of the array, but that won't be achievable in every case.
Imagine the following arrays, which are all circularly sorted, and please have a look at the patterns below them, they may be the key to a divide-and-conquer solution here and/or to a solution with an average case (Big Theta) of less than n, while the worst case (Big O) will still stay O(n)…
The examples all have n = 7 elements and each one has p = 4 positive elements (including 0) and l = 3 negative elements. Iterating through all of them will always be O(n), which would be O(6) here. In some of the cases, the sorting provides information about what's at the end of the array, which enables a programmer to reduce the best case (Big Omega) to O(p + 1) = O(p) = O(4) in some of the situations:
The following array takes n steps because one has to check every element
{-3, -2, -1, 0, 1, 2, 3}
n n n p p p p
The next example takes n - 1 steps, because there is are two negative numbers after all the positives and you only have to find the first one in order to meet a break condition. That's because there was a negative number already at a lower index.
{-1, 0, 1, 2, 3, -2, -3}
n p p p p n n
This next one takes only p + 1 (which means O(p + 1) = O(p)) steps because you can break the loop at the first negative number found. Why? Because the array starts with the smallest possible number that is positive (by definition) and the first negative number found indicates no need for further processing.
{0, 1, 2, 3, -1, -2, -3}
p p p p n n n
This last example requires n steps again, because you are looking for positive numbers which are at the beginning and at the end of the array. There is no chance of directly knowing at which index they are.
{3, -3, -2, -1, 0, 1, 2}
p n n n p p p
The only way (I know) to optimize the average case would be implementing the break conditions of the loop according to the possible patterns. So store indexes and do checks based on them, but I think the effect won't be that huge.
This is my first approach, may be optimized in several ways, I have only tried it with the examples of this edit:
public static void main(String[] args) {
int[] circularlySortedArray = { 0, 1, 2, 3, -1, -2, -3 };
// define a variable for the sum of positive values
int sumOfPositives = 0;
// define a variable for the lowest index of a positive number
int firstPositiveIndex = -1;
// define a variable for the lowest positive number found
int smallesPositiveNumber = 0;
// start iterating the array
for (int i = 0; i < circularlySortedArray.length; i++) {
System.out.println("Current index: " + i
+ ", current value: " + circularlySortedArray[i]);
// provide a variable for the current number to make this code a little more
// readable
int number = circularlySortedArray[i];
// check if the current number is positive
if (number >= 0) {
// add it to the sum
sumOfPositives += number;
System.out.println("Added " + number
+ " to sumOfPositives (now: " + sumOfPositives + ")");
// check if it is the first positive number found
if (firstPositiveIndex < 0) {
// if yes, set the variable value accordingly
System.out.println("First and smallest positive number ("
+ number
+ ") found at index "
+ i);
firstPositiveIndex = i;
smallesPositiveNumber = number;
}
System.out.println("————————————————————————————————");
} else {
// break conditions based on index & value of the smallest positive number found
if (i > firstPositiveIndex && firstPositiveIndex > 0) {
System.out.println("Stopped the loop at index " + i);
break;
} else if (smallesPositiveNumber == 0 && firstPositiveIndex == 0) {
System.out.println("Stopped the loop at index " + i);
break;
}
System.out.println(number + " is not positive, skip it");
System.out.println("————————————————————————————————");
continue;
}
}
System.out.println("The sum of positive numbers is " + sumOfPositives);
}
What you're asking for is impossible.
The input array could potentially be all positive values which means you have to at least read and sum all elements. That's O(n).
Even if not all elements are positive, unless it's defined that no more than O(log n) elements are positive the same conclusion remains.
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.)
When i study from Introduction to Java programming book of Liang, i am stuck at a point. The problem is to find prime numbers efficiently.
In order to find whether n is prime or not, we must check whether n is divisible by numbers 2,3,4,...,sqrt(n) .
We can make this algorithm more efficient by checking whether n is divisible by numbers 2,3,4,...,floor(sqrt(n)).
For example, numbers between 36 and 48, their (int)(Math.sqrt(number)) is 6. But, according to the below program, for number=40, squareRoot is 7, not 6. Namely, according to the mathematical proof, we check whether 40 is prime by checking 40 is divisible by 2,3,4,5,6.
According to the below program, we check whether 40 is prime by checking 40 is divisible by 2,3,4,5,6,7. This the contradiction. I don't understand it. Help please.
Here is the algorithm implementing this problem :
import java.util.Scanner;
public class EfficientPrimeNumbers {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Find all prime numbers <= n, enter n: ");
int n = input.nextInt();
// A list to hold prime numbers
java.util.List<Integer> list =
new java.util.ArrayList<Integer>();
final int NUMBER_PER_LINE = 10; // Display 10 per line
int count = 0; // Count the number of prime numbers
int number = 2; // A number to be tested for primeness
int squareRoot = 1; // Check whether number <= squareRoot
System.out.println("The prime numbers are \n");
// Repeatedly find prime numbers
while (number <= n) {
// Assume the number is prime
boolean isPrime = true; // Is the current number prime?
if (squareRoot * squareRoot < number) squareRoot++;
// For numbers between 36 and 48, squareRoot is 7 which contradicts with the matematical proof.!!!
// ClosestPair if number is prime
for (int k = 0; k < list.size()
&& list.get(k) <= squareRoot; k++) {
if (number % list.get(k) == 0) { // If true, not prime
isPrime = false; // Set isPrime to false
break; // Exit the for loop
}
}
// Print the prime number and increase the count
if (isPrime) {
count++; // Increase the count
list.add(number); // Add a new prime to the list
if (count % NUMBER_PER_LINE == 0) {
// Print the number and advance to the new line
System.out.println(number);
}
else
System.out.print(number + " ");
}
// Check if the next number is prime
number++;
}
System.out.println("\n" + count +
" prime(s) less than or equal to " + n);
}
}
The program only checks for divisibility by primes lower than or equal to sqrt(number) + 1. Once a prime number is detected, it gets added to your list object:
if (isPrime) {
count++; // Increase the count
list.add(number); // Add a new prime to the list
Here is where you check for divisibility by numbers in this list:
for (int k = 0; k < list.size() && list.get(k) <= squareRoot; k++) {
if (number % list.get(k) == 0) { // If true, not prime
So for numbers between 36 and 48, it checks 2, 3, 5, 7, which is actually better than 2, 3, 4, 5, 6. Asymptotically, they're still the same, but in practice, you save some work by only checking for divisibility against the primes.
In fact you can save an operation and change the <= in list.get(k) <= squareRoot to <, for the reasons you describe. Then it won't even bother with 7 for numbers between 36 and 48, and it will be closer to the theory you have.
I need to write a method which takes in an int and returns true if the number can be written as a sum of two or more consecutive positive integers and false otherwise.
boolean IsSumOfConsecutiveInts(int num)
I figured out that all odd numbers (except the number 1) can be written as the sum of 2 consecutive positive integers:
return (num > 1 && num % 2 == 1);
but this doesn't account for numbers that can be written as the sum of more than 2 consecutive positive integers (such as 6 == 1 + 2 + 3).
How can I determine whether a number can be written as a sum of two or more consecutive positive integers?
These numbers are called Polite Numbers.
And, conveniently, the only numbers that aren't polite are the powers of 2.
So, that gives us 2 options. We can either determine that a number is polite, OR we can determine that it is not a power of 2.
I did both; the latter is easier (and more efficient).
This determines whether or not a number is polite:
boolean IsSumOfConsecutiveInts(int num)
{
int sumOfFirstIIntegers = 3;
for (int i = 2; sumOfFirstIIntegers <= num; i++)
{
if (i%2 == 0 ? (num%i == i/2) : (num%i == 0))
{
return true;
}
sumOfFirstIIntegers += i + 1;
}
return false;
}
This one is pretty hard to understand. It took me a while to come up with.
Basically, i is the number of consecutive integers that we are checking;
sumOfFirstIIntegers is equal to the sum of the first i integers, so that means that all the numbers that can be expressed as a sum of i consecutive integers are greater than or equal to sumOfFirstIIntegers.
The last part that deserves discussing is the boolean statement i%2 == 0 ? (num%i == i/2) : (num%i == 0). Let's look at some examples:
i all sums of i consecutive positive integers
2 3, 5, 7, 9...
3 6, 9, 12, 15...
4 10, 14, 18, 22...
5 15, 20, 25, 30...
There are two cases, but in either case, we can express all possible numbers that are a sum of i consecutive integers pretty simply.
When i is even, num must be equal to (i * n) + (i / 2) where n is a non-negative integer. This can of course be written as num % i == i / 2.
When i is odd, num must be equal to i * n, where n is a non-negative integer. Which gives us our second condition num % i == 0.
In addition to these conditions, num can not be less than the sum of the first i positive integers. Hence, our for loop's conditional: sumOfFirstIIntegers <= num.
This determines whether a number is not a power of 2:
boolean IsSumOfConsecutiveInts(int num)
{
return (num & (num - 1)) != 0;
}
This answer does a good job of explaining why this works.
Note that both of the above solutions have the same result, they are just different ways of thinking about the problem.
From Java Malik textbook- determine if an number is divisible by 11..
Code Solution provided:
import java.util.*;
public class Divby11
{
static Scanner console = new Scanner(System.in);
public static void main (String[] args)
{
int num, temp, sum;
char sign;
System.out.print("Enter a positive integer: ");
num = console.nextInt();
System.out.println();
temp = num;
sum = 0;
sign = '+';
do
{
switch (sign)
{
case '+' :
sum = sum + num % 10;
sign = '-';
break;
case '-' :
sum = sum - num % 10;
sign = '+';
}
num = num / 10; //remove the last digit
}
while (num > 0);
if (sum % 11 == 0)
System.out.println(temp + " is divisible by 11");
else
System.out.println(temp + " is not divisible by 11");
}
Why go through all the effort above and just say...
if (sum % 11 == 0)
System.out.println(temp + " is divisible by 11");
else
System.out.println(temp + " is not divisible by 11");
Can any of you experts see why the author would do it this way (long way)?
for the Divisibility Rule of 11:
form the alternating sum of the digits
if this sum is divisible for 11 then the number is divisible for 11
Examples
68090 = 0 - 9 + 0 - 8 + 6 = -11 => TRUE
493827 = 7 - 2 + 8 - 3 + 9 - 4 = 15 = 4 => FALSE
This code example isn't actually dividing by eleven. If you see, it's alternating between adding and subtracting each digit, then checks at the very end if the result is divisible by 11.
For example, look at the following number and how this algorithm works with it:
Start with sum=0, sign='+', num=517
First iteration: sum=7, sign='-', num=51
Second iteration: sum=6, sign='+', num=5
Final iteration: sum=11, sign='-', num=0
The final result is divisible by eleven.
EDIT: The algorithm does indeed look to be implementing the divisibility rule for 11 as dfa mentions in his answer.
You will have to provide more context from the book as to what the author was trying to demonstrate. This code example does not check to see if the number entered is divisible by 11. What it does is it adds every other digit, subtracts every other digit and then checks THAT number to see if it's divisible by 10.
EX
Entered number is 4938
It takes the 8 adds it to sum
Divides by ten giving 493
Takes the 3 subtracts it from sum: sum = 5
Divides by ten giving 49
Takes 9 and adds it to sum: sum = 14
Divides by ten giving 4
Takes 4 subtracts it from sum: sum = 10
THEN it checks if this is divisible by 11.
Ok, I know why now. He/she's trying to teach you something besides computing about numbers
I suspect it is simulating the manual test that digits in the odd positions and the digits in the even positions differ by a factor of 11. In practice using %11 would be the way to go.
EDIT: If the example were truly trying to avoid doing % 11, it should send the sum through again until it is 0.
It an example to show how to implement that particular check. Using your example would not demonstrate the same code methodologies.