Last active
September 21, 2016 15:29
-
-
Save Tandrial/81fc34f661cfb11e741fb3112820b237 to your computer and use it in GitHub Desktop.
Divisibility rule
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
import java.lang.reflect.InvocationTargetException; | |
import java.lang.reflect.Method; | |
public class DivRules { | |
public static boolean isDivBy(int divisor, long num) { | |
assert (divisor > 0 && divisor <= 10); | |
if (num == 0) | |
return true; | |
try { | |
Method method = DivRules.class.getDeclaredMethod("isDivBy" + divisor, Long.TYPE); | |
return (boolean) method.invoke(DivRules.class, num); | |
} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | |
| InvocationTargetException e) { | |
e.printStackTrace(); | |
} | |
return false; | |
} | |
private static boolean isDivBy1(long num) { | |
return true; | |
} | |
private static boolean isDivBy2(long num) { | |
return (getDigit(1, num) & 0x1) == 0; | |
} | |
private static boolean isDivBy3(long num) { | |
if (num > 9L) { | |
String numStr = Long.toString(num); | |
long sum = 0; | |
for (char c : numStr.toCharArray()) { | |
sum += c - '0'; | |
} | |
return isDivBy3(sum); | |
} else { | |
switch ((int) num) { | |
case 3: | |
case 6: | |
case 9: | |
return true; | |
default: | |
return false; | |
} | |
} | |
} | |
private static boolean isDivBy4(long num) { | |
if (num > 9L) { | |
boolean check = false; | |
int tens = getDigit(2, num); | |
int ones = getDigit(1, num); | |
if (isDivBy2(tens)) { | |
switch (ones) { | |
case 0: | |
case 4: | |
case 8: | |
check = true; | |
} | |
} else { | |
switch (ones) { | |
case 2: | |
case 6: | |
check = true; | |
} | |
} | |
return check && isDivBy4(2 * tens + ones); | |
} else { | |
switch ((int) num) { | |
case 0: | |
case 4: | |
case 8: | |
return true; | |
default: | |
return false; | |
} | |
} | |
} | |
private static boolean isDivBy5(long num) { | |
switch (getDigit(1, num)) { | |
case 0: | |
case 5: | |
return true; | |
default: | |
return false; | |
} | |
} | |
private static boolean isDivBy6(long num) { | |
return isDivBy2(num) && isDivBy3(num); | |
} | |
private static boolean isDivBy7(long num) { | |
if (Math.abs(num) > 14L) { | |
int ones = getDigit(1, num); | |
String numStr = Long.toString(num); | |
num = Long.valueOf(numStr.substring(0, numStr.length() - 1)); | |
return isDivBy7(num - 2 * ones); | |
} else { | |
switch ((int) Math.abs(num)) { | |
case 0: | |
case 7: | |
case 14: | |
return true; | |
default: | |
return false; | |
} | |
} | |
} | |
private static boolean isDivBy8(long num) { | |
if (num <= 9L) { | |
return (num == 0L) || (num == 8L); | |
} else if (num <= 99L) { | |
return isDivBy8(2 * getDigit(2, num) + getDigit(1, num)); | |
} else { | |
return isDivBy8(num % 100 + (isDivBy2(getDigit(3, num)) ? 0 : 4)); | |
} | |
} | |
private static boolean isDivBy9(long num) { | |
if (num > 9L) { | |
String numStr = Long.toString(num); | |
long sum = 0; | |
for (char c : numStr.toCharArray()) { | |
sum += c - '0'; | |
} | |
return isDivBy9(sum); | |
} else { | |
return (num == 9L); | |
} | |
} | |
private static boolean isDivBy10(long num) { | |
return getDigit(1, num) == 0; | |
} | |
private static int getDigit(int pos, long num) { | |
String numStr = Long.toString(num); | |
return numStr.charAt(numStr.length() - pos) - '0'; | |
} | |
} |
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
import static org.junit.Assert.assertFalse; | |
import static org.junit.Assert.assertTrue; | |
import java.util.Random; | |
import org.junit.Test; | |
public class testDivRules { | |
@Test | |
public void isDivRandom() { | |
Random r = new Random(0x31337); | |
for (int divisor = 1; divisor <= 10; divisor++) { | |
for (int i = 0; i < 100000; i++) { | |
long number = Math.abs(r.nextLong()); | |
boolean should = (number % divisor) == 0; | |
boolean is = DivRules.isDivBy(divisor, number); | |
assertTrue(String.format("%d is divisible by %d : %s! Rules say: %s\n", number, divisor, should, is), | |
should == is); | |
} | |
} | |
} | |
@Test | |
public void testDiv2() { | |
assertTrue(DivRules.isDivBy(2, 1924)); | |
assertFalse(DivRules.isDivBy(2, 1925)); | |
} | |
@Test | |
public void testDiv3() { | |
assertTrue(DivRules.isDivBy(3, 405)); | |
assertFalse(DivRules.isDivBy(3, 406)); | |
assertTrue(DivRules.isDivBy(3, 636)); | |
assertTrue(DivRules.isDivBy(3, 16_499_205_854_376L)); | |
} | |
@Test | |
public void testDiv4() { | |
assertTrue(DivRules.isDivBy(4, 40_832)); | |
assertFalse(DivRules.isDivBy(4, 40_834)); | |
} | |
@Test | |
public void testDiv5() { | |
assertTrue(DivRules.isDivBy(5, 495)); | |
assertFalse(DivRules.isDivBy(5, 496)); | |
} | |
@Test | |
public void testDiv6() { | |
assertTrue(DivRules.isDivBy(6, 1_458)); | |
assertFalse(DivRules.isDivBy(6, 1_457)); | |
} | |
@Test | |
public void testDiv7() { | |
assertTrue(DivRules.isDivBy(7, 483)); | |
assertTrue(DivRules.isDivBy(7, 483_595)); | |
assertFalse(DivRules.isDivBy(7, 48)); | |
} | |
@Test | |
public void testDiv8() { | |
assertTrue(DivRules.isDivBy(8, 624)); | |
assertTrue(DivRules.isDivBy(8, 352)); | |
assertTrue(DivRules.isDivBy(8, 56)); | |
assertTrue(DivRules.isDivBy(8, 34_152)); | |
assertFalse(DivRules.isDivBy(8, 34_150)); | |
} | |
@Test | |
public void testDiv9() { | |
assertTrue(DivRules.isDivBy(9, 2_880)); | |
assertFalse(DivRules.isDivBy(9, 2_881)); | |
} | |
@Test | |
public void testDiv10() { | |
assertTrue(DivRules.isDivBy(10, 2_880)); | |
assertFalse(DivRules.isDivBy(10, 2_881)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment