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.
Related
I have a question regarding an answer that was given here a while ago.
I came up with the same answer myself in the code attached but I'm trying to understand why do I need to divide the input number by 2 (line 10), and not just let the loop run its course till the value of the input number achieved.
1 import java.util.Scanner;
2 public class numIsPrime {
3 public static void main(String[] args) {
4 Scanner sc = new Scanner(System.in);
5 int i = 2;
6 boolean isPrime = true;
7 System.out.println("Enter a number");
8 int num = sc.nextInt();
9
10 while (i < num ) // (i <= num / 2)
11 {
12 if (num % i == 0)
13 isPrime = false;
14 i++;
15 }
16
17 if (isPrime)
18 System.out.println(num + " is a prime number");
19 else // !isPrime
20 System.out.println(num + " isn't a prime number");
21
22 }
23 }
This is the simplest way to calculate if an integer n is probably a prime:
public static boolean isPrime (int n) {
if (n < 2) return false;
BigInteger bigInt = BigInteger.valueOf(n);
return bigInt.isProbablePrime(100);
}
You can insert this function call in a loop where you can pass a new number every iteration. I am using the implementation of BigInteger provided by Java to do the calculation, rather than writing my own. UNLESS this is a homework and you are required to write your own algorithm, I would use this solution.
This base method can then be used for calculating other types of prime numbers. A complete answer can be found here.
UPDATE:
The int parameter in BigInteger.isProbablePrime(int) is a measure of the uncertainty that the caller is willing to tolerate. The larger the number, the "slower" it executes (but the more certain it is). Also, going back to the original question (already answered in the OP's comments section):
why do I need to divide the input number by 2 (line 10), and not just
let the loop run its course till the value of the input number
achieved.
This is an optimization that will make your evaluation run twice as fast. For example, suppose an evaluation of n integers take 10 minutes to complete, excluding even numbers should take half the time. That's a significant improvement. Although you should not optimize prematurely, these sort of optimizations should be done right from the get go. Basically, we all know that even numbers are not prime, so why evaluate it? You want to evaluate unknowns. In my solution, I only evaluate values greater than 2 because by definition, values less or equal to 2 are not prime. I am merely solving that by definition or by mathematical properties.
As mentioned in the comments, dividing by 2 is a simplest optimization to reduce the number of checks, however, existing code has a few issues (e.g. returning true for 0 and 1 which are NOT prime numbers) and may be further optimized:
break/end the loop as soon as isPrime is set to false
skip even numbers by incrementing by 2
calculate until i * i <= num
If this limit is reached, it means that no factor i of num has been found in the range [2, num/i], therefore by definition of the prime numbers, all the remaining numbers in the range [num/i, num] are neither the factors of num, and therefore num is prime.
Scanner sc = new Scanner(System.in);
System.out.println("Enter a number");
int num = sc.nextInt();
boolean isPrime = num > 1 && (num % 2 != 0 || num == 2);
int i = 3;
while (isPrime && i * i <= num) {
if (num % i == 0)
isPrime = false;
i += 2; // skip even numbers
}
if (isPrime)
System.out.println(num + " is a prime number");
else
System.out.println(num + " isn't a prime number");
More optimizations are possible if the divisibles of 3 (except 3) are excluded similar to the exclusion of even numbers, then the search continues from 5 and the candidates for primality comply with 6n ± 1 rule (e.g., 5 = 6 - 1, 7 = 6 + 1, 11 = 12 - 1, 13 = 12 + 1, etc.):
boolean isPrime = num > 1 && (num % 2 != 0 || num == 2) && (num % 3 != 0 || num == 3);
int i = 5;
int d = 2;
while (isPrime && i * i <= num) {
if (num % i == 0)
isPrime = false;
i += d; // check only non-even numbers
d = 6 - d; // switch 2 to 4 and back to 2
}
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 !
I'm trying to create a method to validate a credit card number, but we have to process it as a string
heres some information about my task...
Credit card numbers follow certain patterns. A credit card must have between 13 and 16 digits.
In 1954, Hans Luhn of IBM proposed an algorithm for validating credit card numbers. The algorithm is useful to determine if a card number is entered correctly or if a credit card is scanned correctly by a scanner. Almost all credit card numbers are generated following this validity check, commonly know as the Luhn check or the Modulus 10 check, which can be described as follows. For illustration, consider the card number 4388576018402625.
Double every second digit from right to left. If doubling of a digit results in a 2-digit number, add up the two digits to get a single-digit number.
2 x 2 = 4
2 x 2 = 4
4 x 2 = 8
1 x 2 = 2
6 x 2 = 12 (1+2= 3)
5 x 2 = 10 (1+0= 1)
8 x 2 = 16 (1+6= 7)
4 x 2 = 8
Add all the single digit numbers from step 1 4 + 4 +8 + 2 +3 + 1 + 7 + 8 = 37
Add all digits in the odd places from right to left in the card number
5 + 6 + 0 + 8 + 0 + 7 + 8 + 3 = 37
Sum the results from step 2 and step 3 37 + 37 = 74
If the result from step is divisible by 10, the card number is valid; otherwise, it’s invalid. For example, the number 4388576018402625 is invalid, but the number 4388576018410707 is a valid Visa card; the number 6011000593748745 is invalid, but the number 6011000593748746 is a valid Discover card.
here's what I have so far
static void CreditCardValidator() {
System.out.println("enter a credit card number");
String temp = options.nextLine();
if (temp.length() < 13 || temp.length() > 16) {
System.out.println("Input is invalid");
}
// inside loop with char at command do all the math
int tmpdouble;
int sum = 0;
int counter = temp.length() - 1;
for (int i = temp.length(); i != 0; i--) {
char tmp = temp.charAt(i);
//tmp converted to int
tmpdouble = tmp * 2;
int firstDigit;
int secondDigit;
if (tmpdouble >= 10) {
firstDigit = i / 10;
secondDigit = i % 10;
sum = sum + firstDigit + secondDigit;
}
else if(tmpdouble <= 9) {
sum = sum + tmpdouble;
}
HELP HERE{
// need to have it do the same thing as above but for odd numbers
}
where do I go from there? ^^
Thanks
Don't roll your own. This algorithm is already provided via commons.
https://commons.apache.org/proper/commons-validator/apidocs/org/apache/commons/validator/routines/CreditCardValidator.html
So, I want to find what numbers between 1 and 100 are divisible by 3 and 7. I got it to work, except for one of the numbers. For some reason, 3 % 3 is giving me 3 as a remainder, but 6 % 3 is giving me 0. This is my code:
public class factors
{
public static void main(System args[])
{
//Variables
int integer, remainder;
//Displays header
System.out.print("Integers less than 100 that are \nevenly divisible by 3 or 7");
//Loops through each integer
for (integer = 1; integer <= 100; integer++)
{
remainder = integer % 3; //determines if 3 is a factor
if (remainder == 0) //displays integer
{
System.out.println(integer + " is divisible by 3");
}
remainder = integer % 7; //determines if 7 is a factor
if (remainder == 0) //displays integer
{
System.out.println(integer + " is divisible by 7");
}
}
}
}Does anyone know why this isn't working for the number 3?
You code is actually doing
remainder = 3 % 7; // equals 3.
The best way to determine why your code is not doing what you think is to step through your code using a debugger.
All the multiples of 3 & 7 will be multiples of 21, i.e. 21, 42, 63, 84.
Your 3 is getting tacked onto the end of the line of text above. You'll be seeing
Integers less than 100 that are
evenly divisible by 3 or 73
because you wrote print instead of println for this line of text. The % operator is working just fine, and 3 % 3 is indeed 0, not 3.
You are not outputting a remainder - you are displaying integer. So for 3 it should print 3.
Make you print statements more definite:
System.out.println(integer + " is divisible by 3"); // for the first `if`
and
System.out.println(integer + " is divisible by 7"); // for the second `if`
This should clear your confusion.
Your logic prints number divisible by 3 or 7.
Firstly, your code can be shortened to:
//and
for (int i = 1; i <= 100; i++){
if(i % 3 == 0 && i % 7 == 0) {
System.out.println(i);
}
}
//or
for (int i = 1; i <= 100; i++){
if(i % 3 == 0 || i % 7 == 0) {
System.out.println(i);
}
}
Also I note you're not declaring a type for your integer, remainder variables. I didn't attempt to recreate with those issues; start by solving that.
I'd like to create a program wherein a user will type a number and the program will tell if it is divisible by 3 or not. But %, /, +, * can't be used in the program. Anybody here got some ideas how to do that?
public static void main(String[] args) {
String number = "123456";
int sum = 0;
for (char c : number.toCharArray()) {
sum = sum - (0 - c) - '0';
while (sum >= 3) {
sum -= 3;
}
}
System.out.print("divisible by 3? ");
System.out.println(sum == 0);
}
Alternatively you can keep subtracting 3 until your number is either 0 (divisible by 3) or <0: not divisible by 3.
ps: it needs to be adapted if you want to deal with negative numbers
easy peasy...
boolean divisibleBy3(int n) {
return (""+n).matches("([0369]|[147]([0369]|[147][0369]*[258])*([" +
"258]|[147][0369]*[147])|[258]([0369]|[258]" +
"[0369]*[147])*([147]|[258][0369]*[258]))*");
}
A number is divisible by there if the sum of all the digits is also divisible by 3. You can iterate the process until you have a number smaller than 10 and compare it which known divisors (3,6 and 9)
Since it is most likely a game or homework and you can use + you can simple use minus two times: a - - b is equivalent to a + b
Assuming you can use the - operator then
bool divBy3(int n)
{
while (n >= 0)
{
n -= 3;
}
return n == 0;
}
This will return true if n is exactly divisible by 3, false otherwise. Note that this is really inefficient! Using the % operator would be far better.
Divisibility by 3 in binary representation is like divisibility by 11 in decimal (10+1): sum of digits in even places minus sum of digits on odd places is in turn divisible by 3 (maybe 0).