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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 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;
}
}
TestNG test cases for this problem which all passed:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 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);
}
}