CountDiv – Codility – Solution

Java solution to Codility CountDiv problem (Lesson 5 – Prefix Sums) which scored 100%. The problem is to calculate number of integers divisible by a given number form a sequential range of integers. The strategy is to find the first and last non zero divisors and perform simple subtraction and division to get total number of divisors.


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
41
42
package com.codility.lesson05.prefixsums;

public class CountDiv {
  public int solution(int A, int B, int K) {
    int divisors = 0;
   
    //nothing to do when K > B
    if(K > B) {
      if(A == 0 || B == 0) {
        return 1; //K mod 0 == 0 so count a single divisor
      }
      return 0; //no divisors when A, B both != 0
    }

    if(A == 0) {
      divisors++;  //K mod 0 == 0
    }
   
    int updatedA = A;
    if(K > A) {
      updatedA = K; //skip checking all values < K
    }
   
    int firstNonZeroDivisor = 0;
    int lastNonZeroDivisor = 0;
   
    for(int i=updatedA; i<=B; i++) { if(i % K == 0) { firstNonZeroDivisor = i; break; } } for(int i=B; i>=updatedA; i--) {
      if(i % K == 0) {
        lastNonZeroDivisor = i;
        break;
      }
    }
    if(firstNonZeroDivisor == 0 && lastNonZeroDivisor == 0) {
      divisors = 0;
    }
    else {
      divisors += ((lastNonZeroDivisor - firstNonZeroDivisor) / K) + 1;
    }
   
    return divisors;
  }
}

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
41
42
43
44
45
46
47
48
package test.com.codility.lesson05.prefixsums;

import org.testng.Assert;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import com.codility.lesson05.prefixsums.CountDiv;

public class CountDivTests {
  private CountDiv solution;
 
  @BeforeTest
  public void setUp() {
    solution = new CountDiv();
  }

  @DataProvider(name = "test1")
  public Object [][] createData1() {
    return new Object [][] {
      new Object [] {  5, 11, 2,  3 },
      new Object [] {  6, 11, 2,  3 },
      new Object [] {  0, 11, 5,  3 },
      new Object [] {  0, 11, 12, 1 }, //K>B, A==0
      new Object [] {  1, 11, 12, 0 }, //K>B, A>0
      new Object [] {  0, 0,  12, 1 }, //K>B, A==0, B==0
      new Object [] { 11, 33, 3, 8 },
     
      new Object [] { 10, 10,  5, 1 }, //A = 10, B = 10, K in {5,7,20}
      new Object [] { 10, 10,  7, 0 }, //A = 10, B = 10, K in {5,7,20}
      new Object [] { 10, 10, 20, 0 }, //A = 10, B = 10, K in {5,7,20}
     
      new Object [] { 33, 33, 33, 1 }, //A == B
      new Object [] { 100000, 1000000, 1000, 901 },
      new Object [] { 1000, 10000, 10, 901 },
      new Object [] { 100, 1000, 1, 901 },
      new Object [] { 0, 2000000000, 2000000000, 2 }, //max B
      new Object [] { 2000000000, 2000000000, 2000000000, 1 }, //max A, B
      new Object [] { 100, 123000000, 2, 61499951 }, //A = 100, B=123M+, K=2
      new Object [] { 101, 123000000, 10000, 12300 }, //A = 101, B = 123M+, K = 10K
    };
  }

  @Test(dataProvider = "test1")
  public void verifySolution(int pA, int pB, int pK, int pExpected) {
    Assert.assertEquals(solution.solution(pA, pB, pK), pExpected);
  }
}