Skip to content

Instantly share code, notes, and snippets.

@Tandrial
Last active September 21, 2016 15:29
Show Gist options
  • Save Tandrial/81fc34f661cfb11e741fb3112820b237 to your computer and use it in GitHub Desktop.
Save Tandrial/81fc34f661cfb11e741fb3112820b237 to your computer and use it in GitHub Desktop.
Divisibility rule
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';
}
}
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