Last active
May 8, 2018 20:53
-
-
Save HenriBeck/df18567020f0e177e27bfac0497d88cd to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Grp45_ueb01 { | |
public static void main(String[] args) { | |
final int MIN = -1000; | |
final int MAX = 25; | |
final int DIGIT_COUNT = getDigitCount(MAX); | |
for (int i = MIN; i <= MAX; i++) { | |
boolean isSmithNumber = Grp45_ueb01.isSmithNumber(i); | |
boolean isFermatNumber = Grp45_ueb01.isFermatNumber(i, 0); | |
boolean isCatalanNumber = Grp45_ueb01.isCatalanNumber(i, 0); | |
boolean isMersenneNumber = Grp45_ueb01.isMersenneNumber(i, true); | |
if (isSmithNumber || isFermatNumber || isCatalanNumber || isMersenneNumber) { | |
System.out.printf( | |
"Zahl %" + DIGIT_COUNT + "d:%s%s%s%s%n", | |
i, | |
isSmithNumber ? " Smith" : "", | |
isFermatNumber ? " Fermat" : "", | |
isCatalanNumber ? " Catalan" : "", | |
isMersenneNumber ? " Mersenne" : "" | |
); | |
} | |
} | |
} | |
/** | |
* Check if a number is a Fermat Number. | |
* | |
* Fn = 2^2^n + 1 | |
* | |
* @param number | |
* @param n | |
* @return | |
*/ | |
public static boolean isFermatNumber(int number, int n) { | |
double fermatNumber = pow(2, pow(2, n)) + 1; | |
if (fermatNumber == number) { | |
return true; | |
} | |
if (fermatNumber > number) { | |
return false; | |
} | |
return isFermatNumber(number, n +1); | |
} | |
/** | |
* Check if a number is a Catalan number. | |
* | |
* Fn = (2n)! / ((n+1)! * n!) | |
* | |
* @param number | |
* @param n | |
* @return | |
*/ | |
public static boolean isCatalanNumber(int number, int n) { | |
long catalanNumber = faculty(2 * n) / (faculty(n + 1) * faculty(n)); | |
if (catalanNumber == number) { | |
return true; | |
} | |
if (catalanNumber > number) { | |
return false; | |
} | |
return isCatalanNumber(number, n + 1); | |
} | |
/** | |
* Check if a number is a Mersenne number. | |
* | |
* @param number | |
* @return | |
*/ | |
public static boolean isMersenneNumber(int number, boolean isFirstRun) { | |
if (number < 0) { | |
return false; | |
} | |
// Check the lsb for a 1, if so we shift the bits by one bit to the right | |
if ((number & 0b1) == 1) { | |
return isMersenneNumber(number >> 1, false); | |
} | |
// Check if we have only zeros left, and make sure we actually had a 1 | |
return number == 0 && !isFirstRun; | |
} | |
/** | |
* Check if a number is a smith number. | |
* | |
* @param number | |
* @return | |
*/ | |
public static boolean isSmithNumber(int number) { | |
return findPrimesChecksum(number, true) == getChecksum(number); | |
} | |
/** | |
* Get the checksum of a number. | |
* | |
* @param number | |
* @return Returns the checksum for all number bigger or equal than 0 and -1 for all negative numbers. | |
*/ | |
public static int getChecksum(int number) { | |
// Checksum is only defined for natural numbers | |
// We define the chechsum of a negative number as -1 here! | |
if (number < 0) { | |
return -1; | |
} | |
if (number == 0) { | |
return 0; | |
} | |
int lastDigit = number % 10; | |
return lastDigit + getChecksum((number - lastDigit) / 10); | |
} | |
/** | |
* Caclulate the faculty of a number. | |
* | |
* @param number | |
* @return | |
*/ | |
public static long faculty(int number) { | |
return number <= 1 ? 1 : faculty(number - 1) * number; | |
} | |
/** | |
* Calculates base^exponent | |
* Reimplementation of Math.pow | |
* | |
* @param base | |
* @param exponent | |
* @return | |
*/ | |
public static int pow(int base, int exponent) { | |
switch (exponent) { | |
case 0: return 1; | |
case 1: return base; | |
default: return base * pow(base, exponent - 1); | |
} | |
} | |
/** | |
* Get the checksum of the primes for a number. | |
* | |
* @param number | |
* @param firstRun | |
* @return Returns the checksum of all the primes | |
* or when the number is a prime, we return -1 | |
* and when the number is negative we return 0. | |
*/ | |
public static int findPrimesChecksum(int number, boolean firstRun) { | |
if (number < 0) { | |
return 0; | |
} | |
// Check all number from 2 up to number / 2 | |
for (int i = 2; i < number / 2; i++) { | |
if (number % i == 0) { | |
// i divides the number, so we get the checksum of i and check for more primes | |
return getChecksum(i) + findPrimesChecksum(number / i, false); | |
} | |
} | |
// If it's the first run, the number is a prime so we return -1 else we just calculate the chesum | |
return firstRun ? -1 : getChecksum(number); | |
} | |
/** | |
* Get the count of the digits. | |
* | |
* @param number | |
* @return | |
*/ | |
public static int getDigitCount(int number) { | |
return number < 10 ? 1 : 1 + getDigitCount(number / 10); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment