Java solution to Codility MinPerimeterRectangle problem (Lesson 10 – Prime and composite numbers) which scored 100%. The problem is to find the minimal perimeter of a rectangle whose area equals N.
The strategy is to:
- compute each factor using same technique as CountFactors problem (using square root method)
- calculate second factor by simple division since know first factor and N
[cc lang="java" escaped="true"] package com.codility.lesson10.primecomposite; public class MinPerimeterRectangle { public int solution(int N) { int squareRootN = (int) Math.sqrt(N); int factor2 = 0; int perimeter = 0; int minPerimeter = Integer.MAX_VALUE; if(Math.pow(squareRootN, 2) != N) { squareRootN++; //round up for any non-perfect squares } else { //perfect square root won't be reached inside loop so calculate and set min perimeter minPerimeter = 2 * (squareRootN + squareRootN); } for(int i=1; i<squareRootN; i++) { if(N % i == 0) { //calculate 2nd factor by simple division since know 1st factor and N factor2 = N / i; perimeter = 2 * (factor2 + i); minPerimeter = Math.min(perimeter, minPerimeter); } } return minPerimeter; } } [/cc]
TestNG test cases for this problem which all passed:
[cc lang="java" escaped="true"] package test.com.codility.lesson10.primecomposite; import org.testng.Assert; import org.testng.annotations.BeforeTest; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import com.codility.lesson10.primecomposite.MinPerimeterRectangle; public class MinPerimeterRectangleTests { private MinPerimeterRectangle solution; @BeforeTest public void setUp() { solution = new MinPerimeterRectangle(); } @DataProvider(name = "test1") public Object [][] createData1() { return new Object [][] { new Object [] { 1, 4 }, //2x(1+1)=4 new Object [] { 2, 6 }, //2x(1+2)=6 new Object [] { 3, 8 }, //2x(1+3)=8 new Object [] { 4, 8 }, //2x(1+4)=10, 2x(2+2)=8 new Object [] { 10, 14 }, //2x(1+10)=22, 2x(2+5)=14 new Object [] { 24, 20 }, //2x(1+24)=50, 2x(2+12)=48, 2x(3+8)=22, 2x(4+6)=20 new Object [] { 25, 20 }, //2x(1+25)=52, 2x(5+5)=20, new Object [] { 30, 22 }, //2x(1+30)=62, 2x(2+15)=34, 2x(3+10)=26, 2x(5+6)=22 new Object [] { 36, 24 }, //2x(1+36)=72, 2x(2+18)=40, 2x(3+12)=30, 2x(4+9)=26, 2x(6+6)=24, new Object [] { 56, 30 }, //2x(7+8)=30 new Object [] { 100, 40 }, //2x(10+10)=40 }; } @Test(dataProvider = "test1") public void verifySolution(int pA, int pExpected) { Assert.assertEquals(solution.solution(pA), pExpected); } } [/cc]