diff --git a/src/main/java/org/fundacionjala/coding/abel/PerfectPower.java b/src/main/java/org/fundacionjala/coding/abel/PerfectPower.java new file mode 100644 index 0000000..6ba9e8c --- /dev/null +++ b/src/main/java/org/fundacionjala/coding/abel/PerfectPower.java @@ -0,0 +1,37 @@ +package org.fundacionjala.coding.abel; + +/** + * A perfect power is a classification of positive integers: + * In mathematics, a perfect power is a positive integer that can be expressed as an integer power of another positive + * integer. More formally, n is a perfect power if there exist natural numbers m > 1, and k > 1 such that mk = n. + * Your task is to check wheter a given integer is a perfect power. If it is a perfect power, return a pair m and k + * with mk = n as a proof. Otherwise return Nothing, Nil, null, None or your language's equivalent. + * Note: For a perfect power, there might be several pairs. For example 81 = 3^4 = 9^2, so (3,4) and (9,2) are valid + * solutions. However, the tests take care of this, so if a number is a perfect power, return any pair that proves it. + */ +public final class PerfectPower { + + /** + * Default Constructor. + */ + private PerfectPower() { + + } + + /** + * Check if exists a Perfect Power for the given number. + * + * @param n int. + * @return int[] or null. + */ + public static int[] isPerfectPower(int n) { + for (int i = 2; i <= n / 2; i++) { + for (int j = 2; Math.pow(i, j) <= n; j++) { + if (Math.pow(i, j) == n) { + return new int[]{i, j}; + } + } + } + return null; + } +} diff --git a/src/test/java/org/fundacionjala/coding/abel/PerfectPowerTest.java b/src/test/java/org/fundacionjala/coding/abel/PerfectPowerTest.java new file mode 100644 index 0000000..480837e --- /dev/null +++ b/src/test/java/org/fundacionjala/coding/abel/PerfectPowerTest.java @@ -0,0 +1,149 @@ +package org.fundacionjala.coding.abel; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Modifier; +import java.util.Random; + +import org.junit.Test; + +import static java.lang.Math.log; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +/** + * Created by abelb on 8/23/2017. + */ +public class PerfectPowerTest { + + /** + * Test for Private Constructors. + * + * @throws NoSuchMethodException Thrown when a particular method cannot be found. + * @throws IllegalAccessException Thrown when an application tries to reflectively create an instance. + * @throws InvocationTargetException thrown by an invoked method or constructor. + * @throws InstantiationException Thrown when an application tries to create an instance of a class + * using the {@code newInstance} method in class. + */ + @Test + public void privateConstructorTest() throws NoSuchMethodException, IllegalAccessException, + InvocationTargetException, InstantiationException { + Constructor constructor = PerfectPower.class.getDeclaredConstructor(); + assertTrue(Modifier.isPrivate(constructor.getModifiers())); + constructor.setAccessible(true); + constructor.newInstance(); + } + + /** + * First Test. + */ + @Test + public void test0() { + assertNull("0 is not a perfect number", PerfectPower.isPerfectPower(0)); + } + + /** + * Second Test. + */ + @Test + public void test1() { + assertNull("1 is not a perfect number", PerfectPower.isPerfectPower(1)); + } + + /** + * Third Test. + */ + @Test + public void test2() { + assertNull("2 is not a perfect number", PerfectPower.isPerfectPower(2)); + } + + /** + * Fourth Test. + */ + @Test + public void test3() { + assertNull("3 is not a perfect number", PerfectPower.isPerfectPower(3)); + } + + /** + * Fifth Test. + */ + @Test + public void test4() { + assertArrayEquals("4 = 2^2", new int[]{2, 2}, PerfectPower.isPerfectPower(4)); + } + + /** + * Sixth Test. + */ + @Test + public void test5() { + assertNull("5 is not a perfect power", PerfectPower.isPerfectPower(5)); + } + + /** + * Seventh Test. + */ + @Test + public void test8() { + assertArrayEquals("8 = 2^3", new int[]{2, 3}, PerfectPower.isPerfectPower(8)); + } + + /** + * Eight Test. + */ + @Test + public void test9() { + assertArrayEquals("9 = 3^2", new int[]{3, 2}, PerfectPower.isPerfectPower(9)); + } + + /** + * Ninth Test. + */ + @Test + public void testUpTo500() { + int[] pp = {4, 8, 9, 16, 25, 27, 32, 36, 49, 64, 81, 100, 121, 125, 128, 144, 169, 196, 216, 225, + 243, 256, 289, 324, 343, 361, 400, 441, 484}; + for (int i : pp) { + assertNotNull(i + " is a perfect power", PerfectPower.isPerfectPower(i)); + } + } + + /** + * Tenth Test. + */ + @Test + public void testRandomPerfectPowers() { + Random rnd = new Random(); + for (int i = 0; i < 100; i++) { + int m = rnd.nextInt(254) + 2; + int k = (int) (rnd.nextDouble() * (log(Integer.MAX_VALUE) / log(m) - 2.0) + 2.0); + int l = ipow(m, k); + int[] r = PerfectPower.isPerfectPower(l); + assertNotNull(l + " is a perfect power", r); + assertEquals(r[0] + "^" + r[1] + "!=" + l, l, ipow(r[0], r[1])); + } + } + + /** + * Helper Method for last test. + * + * @param b int. + * @param e int. + * @return int. + */ + private static int ipow(int b, int e) { + int p = 1; + for (; e > 0; e >>= 1) { + if ((e & 1) == 1) { + p *= b; + } + b *= b; + } + return p; + } +}