Why codility is not doing it right

This topic was bothering me for some time. So let’s move the stone, shall we?

It’s not a discovery to say the recruitment companies have no idea how to verify incoming waves of programmers. IT is a complex field of various technologies. There is no straight telling if the candidate has good coding skills or not. I will discuss the latest trend I tend to see.

Which is: Programmer recruitment process using SaaS tool, called codility.

recruiting_with_codility

Hey wait, so what is codility anyway?

If you are not already aware of, there is already a tool that let you do that. I mean, to hire good coders. You, as the company register on their system, then they supply you with links your HR people can sent to candidates. Each candidate receive a link leading to 3-5 algorithmic tasks and has a time limit to solve them(usually 90 – 120 minutes). These tasks get scored by codility algorithms. Recruiters later see their score and continue recruitment process with only the selected ones. That way company professional employees (ie. the experienced coders) time get saved. As well bad coders will drop out.

That’s in theory.

I used it a few times, with less or more success as a candidate. And here are some of my thoughts.

  • The codility website is quite sensibly designed, on the left you have task description, on right editor waiting for input, and on top timer and tasks tab
  • tasks are in many times badly or lengthy formulated leaving place to wonder about correct implementation, that’s why they supply for each one example input and expected results
  • to solve these tasks it requires candidate to learn tasks pattern before, so spending one day doing codility tasks may be sensible for success on real test
  • tests I was assigned so far did not involved any language specific work, codility team main weapons of choices are: loops, nested loops recurrency and sorting, it’s like coming back to stone age of programming, they make it harder by supplying computing restrictions
  • you don’t get any idea how good you performed, unless the recruiter lets you know. After one of the tests I got response that I needed 120 out of 300 points for 3 tasks to be able to apply for next phase.
  • Editor is not so good if you want to test your algorithm before confirming your result, for this you need external IDE to do the sensible test on more data.
Codility

the battle arena of codility looks like this

My conclusion

it’s might be good for many fresh programmers to train their loops or basic understanding of programming. Theses codility tasks are not complicated, though they require some analyzis, on average you get 30min per task, this is really small amount of time if you want to test algorithm really well.

Good thing after you learn the codility platform and how it works, you may always decline for participating in this kind of test. Not everyone has to be a master on primitive data looping. More and more devs are better on design or API usage or functional programming. In this case codility will undervalue your skills, which you most likely do not desire for happen.

Below are few examples of tasks you may stumble upon codility, verify for yourself if they are solvable in 90 mins.


Task 1:array investigation

An integer X and a non-empty zero-indexed array A consisting of N integers are given. We are interested in which elements of A are equal to X and which are different from X. The goal is to split array A into two parts, such that the number of elements equal to X in the first part is the same as the number of elements different from X in the other part. More formally, we are looking for a number K such that:

0 < K < N, and
the number of elements equal to X in A[0..K-1] is the same as the number of elements different from X in A[K..N?1].(For K = 0, A[0..K-1] does not contain any elements. For K = N, A[K..N-1] does not contain any elements.)
For example, given integer X = 5 and array A such that:

  A[0] = 5
  A[1] = 5
  A[2] = 1
  A[3] = 7
  A[4] = 2
  A[5] = 3
  A[6] = 5
K equals 4, because:

two of the elements of A[0..3] are equal to X, namely A[0] = A[1] = X, and
two of the elements of A[4..6] are different from X, namely A[4] and A[5].
Write a function:

int solution(int X, int A[], int N);

that, given an integer X and a non-empty zero-indexed array A consisting of N integers, returns the value of number K satisfying the above conditions. It can be shown such index K always exists and it is unique.

For example, given integer X and array A as above, the function should return 4, as explained above.

Assume that:

N is an integer within the range [1..100,000];
X is an integer within the range [0..100,000];
each element of array A is an integer within the range [0..100,000].
Complexity:
   expected worst-case time complexity is O(N);
   expected worst-case space complexity is O(1), beyond input storage 
   (not counting the storage required for input arguments). 
   Elements of input arrays can be modified.

Task 2: sequence manipulation

In base --2, integers are represented by sequences of bits in the following way. Bits are ordered from the least to the most significant. Sequence B of N bits represents the number: sum{ B[i]*(2)i for i = 0..N-1 }. The empty sequence represents 0.

Note that such a representation is suitable for both positive and negative integers.

Assume that the following declarations are given:

struct Results {
  int * B;
  int N;
};

Write a function:
     struct Results solution(int A[], int M);

that, given a zero-indexed array A of M bits, containing a sequence representing some integer X, returns the shortest sequence of bits representing --X.

The sequence should be returned as:

a structure Results (in C), or
a vector of integers (in C++), or
a record Results (in Pascal), or
an array of integers (in any other programming language).
For example, given A = [1,0,0,1,1] (X = 9), the function should return [1,1,0,1] (--X = -9).
Given A = [1,0,0,1,1,1] (X = -23), the function should return [1,1,0,1,0,1,1] (--X = 23).

Assume that:

M is an integer within the range [0..100,000];
each element of array A is an integer that can have one of the following values: 0, 1.
Complexity:
   expected worst-case time complexity is O(M);
   expected worst-case space complexity is O(M), beyond input storage 
   (not counting the storage required for input arguments).
Elements of input arrays can be modified.

Task 3: minimal horse moves

The knight is a piece in the game of chess that in one turn can move two
squares horizontally and one square vertically or two squares vertically
and one square horizontally.

An infinite chessboard is given. All of its squares are empty except for
the square with coordinates (0, 0) where a knight stands.

Write a function:
  int solution(A,B)

that given two numbers A and B returns the minimal number of turns required
for the knight to move from square (0, 0) to square (A, B). The function
should return -1 if the knight cannot reach given square. The function
should return −2 if the required number of turns exceeds 100,000,000.

Assume that:
  A is an integer within the range [-100,000,000..100,000,000];
  B is an integer within the range [-100,000,000..100,000,000].

For example, given A = 4 and B = 5 the function should return 3 because the
knight requires 3 turns to move from square (0, 0) to square (4, 5): in the
first turn the knight moves from square (0, 0) to square (2, 1), in the
second turn the knight moves from square (2, 1) to square (3, 3), in the
third turn the knight moves from square (3, 3) to square (4, 5).

Complexity:
  expected worst-case time complexity is O(1);
  expected worst-case space complexity is O(1).
,