A while back we were looking for someone to join our dev team, at least mid-level. After sifting through the resumes and doing the initial screening, we were down to 4 candidates who seemed really bright. Out of the 4, two were shown to be all talk. This WTF is about the worst of the four.
He had done an alright job with the SQL and first, very simple, C# exercise, so we found it encouraging. Even if he fumbled a bit on the last test, we weren't too picky, since we had an existing group of well-rounded programmers and if he showed willingness to learn, we could strengthen his skills if he had a few weak points. We just didn't realize just how bad his skills would be.
The final exercise was simple enough: Write a function which takes a time of day and, given an analog clock, calculate the angle between the hour hand and the minute hand. This was relevant to our job, since we deal with a lot of geometry in our projects.
The question is vague on purpose. We want to see if the person asks questions (e.g. do you expect hour and minute parameters or a different format? Do seconds count? Do you want the result in degrees or radians? etc.). While at first one might be thinking such an exercise requires trigonometry functions and the like, after thinking about it for a moment, you realize it's really just a simple arithmetic exercise a middle schooler could figure out.
The candidate started out strong, at least asking a couple questions about it, and then he wanted to demonstrate his TDD approach by writing a unit test first.
[Theory]
public void ClockExercise()
{
var clock = new Clock();
var angle = clock.getAngle(12, 0);
Assert.equal(0, angle);
}
Then he got to work on the implementation. We knew he wasn't going to get away with such a limited and degenerate test case, but we let him continue.
public class Clock
{
public float getAngle(int hour, int minute)
{
var result = hour * 12 / 360;
return result;
}
}
...test fails. My boss and I look at eachother incredulously, but was willing to give him the benefit of the doubt. After all, he was showing signs of being a little nervous. He realizes he is not even accounting for minutes in his equation, so he adds it:
public class Clock
{
public float getAngle(int hour, int minute)
{
var result = hour + minute * 12 / 360 * 60;
return result;
}
}
...umm, whut?
I can hear the lightbulb go in his head. "Oh... between!" he realizes. "That infers subtraction!"
public class Clock
{
public float getAngle(int hour, int minute)
{
var result = hour - minute * 12 / 360 * 60;
}
}
He then sees that in his unit test the result is 12, when it's expecting 0...
public class Clock
{
public float getAngle(int hour, int minute)
{
var result = hour * 12 - minute * 60 / 360;
}
}
This yielded 144. "Well, that's not good," he surmises. "I'm going AWAY from where I want to be."
Then he realized something. Clocks are 12 hours, while there are 24 hours in a day! He was going about this all wrong. If the hour were 12, then mathematically speaking, that's really the 0th hour on a 12 hour clock.
public class Clock
{
public float getAngle(int hour, int minute)
{
if (hour >= 12) {
return hour * 12 - minute * 60 / 360 - 12;
}
else {
return hour * 12 - minute * 60 / 360;
}
}
}
Now the value is 132, getting closer...
public class Clock
{
public float getAngle(int hour, int minute)
{
if (hour >= 12) {
return hour - 12 * 12 - minute * 60 / 360);
}
else {
return hour * 12 - minute * 60 / 360;
}
}
}
And the pendulum swings to -132.
public class Clock
{
public float getAngle(int hour, int minute)
{
if (hour >= 12) {
return (hour - 12) * 12 - minute * 60 / 360);
}
else {
return hour * 12 - minute * 60 / 360;
}
}
}
And now the unit test passes. "There," he said satisfied with himself. "That was a tough one."
We said, "Alright, the test passes, but you only have one test in there. You should be seeing if other tests pass, like 6:00 should be 180 degrees, and so on."
He said, "You're right" and continued on.
[Theory]
public void ClockExercise()
{
var clock = new Clock();
var angle = clock.getAngle(12, 0);
Assert.equal(0, angle);
angle = clock.getAngle(4, 30);
Assert.equal(90, angle);
}
That's not a typo. He is expecting 4:30 to be 90 degrees on an analog clock. He then fumbled with the code for another several minutes until he came up with the following equation:
public class Clock
{
public float getAngle(int hour, int minute)
{
if (hour >= 12) {
hour = hour - 12;
}
return (hour*12+minute*(60*hour)/180)+hour/2;
}
}
This interestingly passed the unit test, and I could tell he felt quite proud of himself, saying that was a challenging problem, and one he hadn't seen before. We concluded the interview, and after he hung up all we could say to eachother was "Wow." I know I said in the beginning we were willing to accept someone who had some weak points in programming if they showed strength in other areas, but seeing that we had two much stronger candidates, and there were layers of WTFs in his failed solution, we turned him down.