# Embarrassing code I wrote under stress at a job interview

(written by lawrence krubner, however indented passages are often quotes). You can contact lawrence at: lawrence@krubner.com, or follow me on Twitter.

(Note: this post was, in part, inspired by John Lawrence Aspden’s post about FizzBuzz.)

I write terrible code when I go to a job interview. That’s mostly because, when they ask me to solve a coding question, I get nervous. I thought it might be entertaining if I wrote about one such encounter.

Recently I went to a job interview, at a company in New York that had once built their stack (for managing online advertising) in Ruby but who are now transitioning all of their stuff to Clojure (Adaptly).

On this particular day, I was to talk to 3 of their senior developers, and 2 of them would hit me with their favorite questions about how to find something in a given number series.

When I got to the company office, they put me in a conference room and sent in one of their senior engineers. He asked me to fire up a REPL, so I launched Emacs and then “nrepl-jack-in”. I was ready to go, but I was also very nervous, because of these 3 reasons:

1.) I’ve got a guy looking over my shoulder and he’s watching every mistake I’m making

2.) I’m suddenly self-conscious about the prettiness of my code — it doesn’t matter if I can solve the problem, since I’m also competing against candidates who can solve the problem, so the real competition is probably about how elegant and idiomatic our code is

3.) this isn’t just about getting the job done, it’s also about being quick — the pressure to move fast is strong

I was typing code into a live environment, which would then execute my code when I hit “enter”. For those of you who haven’t seen the REPL in Emacs, my screen looked like this:

In addition to the above problems, one extra problem I eventually faced wasn’t Clojure or math, it was English — we had a misunderstanding in our native language!

He asked me if I knew what the “Happy number sequence” was. I said I had never heard of it. He described it like this:

“Take each digit in a number and square it, then add the sums together. Keep doing this recursively.”

The next sentence of English is where the problem started. I thought he said:

“The sequence will either go to one or to infinity.”

but he actually said:

“The sequence will either go to one or infinitely.”

He then offered an example of how to find the next number in the sequence:

“Suppose you start with the number 31. Well, 3 squared is 9 and 1 squared is 1, and 9 and 1 added together is 10, so the next number in the sequence, after 31, is 10.”

And then, with “10”, the “1” squared is 1 and the “0” squared is 0, and when you add 1 and 0, you get “1”, therefore we know that “31” is part of the Happy sequence, because, after 2 iterations, it ended up being “1”.

That much was obvious, but I could not figure out how to test a sequence that goes to infinity — how would I know when to stop testing for more numbers? I mean, I might get to a septillion, but I’d only be taking a small step toward infinity — and then I would need to keep testing till I get to infinity… which is impossible? But I wanted to appear smart, so I didn’t express any confusion. I was thinking that if I dove into the problem, then it would eventually make sense to me. So I started coding in the REPL. The first thing I needed was a function that would find the next number in the sequence, and this would surely be easy:

user>
(defn [x]
(loop [snc (str x) snc-sum 0]
(if (seq (rest snc)
(recur
(rest snc)
(+ (+ (* (first snc) (first snc)) sum)))



but that got me:


RuntimeException EOF while reading, starting at line 4  clojure.lang.Util.runtimeException (Util.java:219)



Oh hell, why am I so clumsy? I tried again:

user>
(defn [x]
(loop [snc (str x) snc-sum 0]
(if (seq (rest snc))
(recur
(rest snc)
(+ (+ (* (first snc) (first snc)) sum))))))



and that got me:


IllegalArgumentException First argument to defn must be a symbol  clojure.core/defn (core.clj:277)



Embarrassing! And now I felt even more nervous! So I tried:

user>
(defn happy [x]
(loop [snc (str x) snc-sum 0]
(if (seq (rest snc))
(recur
(rest snc)
(+ (+ (* (first snc) (first snc)) sum))))))



and I got:


CompilerException java.lang.RuntimeException: Unable to resolve symbol: sum in this context, compiling:(NO_SOURCE_PATH:7:10)



Ugh! What a stupid typo! I tried again:

user>
(defn happy [x]
(loop [snc (str x) snc-sum 0]
(if (seq (rest snc))
(recur
(rest snc)
(+ (+ (* (first snc) (first snc)) snc-sum))))))
#'user/happy



Finally! At least it compiled! Now maybe I can repair my damaged credibility! Let’s try to use it:

user>
(happy 31)
ClassCastException java.lang.Character cannot be cast to java.lang.Number  clojure.lang.Numbers.multiply (Numbers.java:146)



Oh, good lord. This was the only way I could think to get each digit in a number:

snc (str x)

but this actually gave me a sequence of Characters, not strings. In the real world, I would have stopped at this point, gone to look at the documentation, and maybe found a more elegant way to do this. However, under pressure of time, I just started piling on bandaids to try to fix things enough to get it to work:

user>
(defn happy [x]
(loop [snc (str x) snc-sum 0]
(if (seq (rest snc))
(recur
(rest snc)
(+ (+ (* (int (first snc)) (int (first snc))) snc-sum))))))
#'user/happy
user>
(happy 31)
nil



Damn. I forgot to return any value from the loop. So I tried again:

user>
(defn happy [x]
(loop [snc (str x) snc-sum 0]
(if (seq (rest snc))
(recur
(rest snc)
(+ (+ (* (int (first snc)) (int (first snc))) snc-sum))))   snc-sum))



And I get:

CompilerException java.lang.UnsupportedOperationException: Can only recur from tail position, compiling:(NO_SOURCE_PATH:5:4)



Now I am angry with myself. This whole process is dragging on too long, and I keep making simple mistakes. And it’s a job interview!

I try again:

user>
(defn happy [x]
(loop [snc (str x) snc-sum 0]
(if (seq (rest snc))
(recur
(rest snc)
(+ (+ (* (int (first snc)) (int (first snc))) snc-sum))) snc-sum)))
#'user/happy



Finally! It compiled! Let’s see it work:

user>
(happy 31)
2601



Ah, damn! The correct answer is “10”, but I am getting 2601! What the hell went wrong?

At this point, the guy interviewing me is starting to get bored. I can see his eyes drifting elsewhere, he starts checking his phone for messages. I am thinking that in his mind he has already decided that I’m a pathetic loser. In a different industry, he might simply shout “Next” and kick me out and drag the next applicant in, but our industry is slightly more polite than that. So he waits for me to stop screwing up. But he looks very bored.

I notice that I am, for some strange reason, summing twice, so I take out the redundant “+”:

user>
(defn happy [x]
(loop [snc (str x) snc-sum 0]
(if (seq (rest snc))
(recur
(rest snc)
(+ (* (int (first snc)) (int (first snc))) snc-sum)) snc-sum)))
#'user/happy
user>
(happy 31)
2601



Damn! Damn! Damn! What the hell is wrong with my code?

In retrospect, the error is obvious, but under the pressure of time, my mind was racing and I was not seeing the problem, so I added some print statements so I could better understand what was happening:

user>
(defn happy [x]
(loop [snc (str x) snc-sum 0]  (print (rest snc))  (print (first snc))
(if (seq (rest snc))
(recur
(rest snc)
(+ (* (int (first snc)) (int (first snc))) snc-sum)) snc-sum)))
#'user/happy
user>
(happy 31)
(1)3()1
2601



Hmm, so, the sequence of numbers is exactly what I thought it would be, so everything should work perfectly, but it is not because…

Oh, right! I am casting a string to an integer, and getting back the ASCII value of the string. Awful!

So, I try to fix that:

user>
(defn happy [x]
(loop [snc (str x) snc-sum 0]
(if (seq (rest snc))
(recur
(rest snc)
(+ (* (.parseInteger (first snc)) (.parseInteger (first snc))) snc-sum)) snc-sum)))
#'user/happy
user>
(happy 31)
IllegalArgumentException No matching field found: parseInteger for class java.lang.Character  clojure.lang.Reflector.getInstanceField (Reflector.java:271)



Hell! What is the right method call? I’ve done this many times before, I just can’t recall, right now, the way to write this. I turn to the guy and ask him permission to look this up in my old code. He gives me permission. I look at some code that I’ve written and see the correct way, and so I can do this correctly:

user>
(defn happy [x]
(loop [snc (str x) snc-sum 0]
(if (seq (rest snc))
(recur
(rest snc)
(+ (* (Integer/parseInt (first snc)) (Integer/parseInt (first snc))) snc-sum)) snc-sum)))
#'user/happy



It compiles! So I try it:

user>
(happy 31)
ClassCastException java.lang.Character cannot be cast to java.lang.String  user/happy (NO_SOURCE_FILE:7)



FML!!!!!

I know there must be something elegant I can do here, but for now I go for the fastest shortcut I can think of:

user>
(defn happy [x]
(loop [snc (str x) snc-sum 0]
(if (seq (rest snc))
(recur
(rest snc)
(+ (* (Integer/parseInt (str (first snc))) (Integer/parseInt (str (first snc)))) snc-sum)) snc-sum)))
#'user/happy



Holy hell, this code is ugly! If someone came into a job interview, and I was the one doing the interview, I would have some doubts about the candidate if I saw them write this code.

But anyway, I try it:

user>
(happy 31)
9



Hmm, very close! I want “10” but I get “9”. What did I do wrong? Oh wait, I forgot to add in the “false” clause of the “if” statement! That is, what happens if we don’t recur?

user>
(defn happy [x]
(loop [snc (str x) snc-sum 0]
(if (seq (rest snc))
(recur
(rest snc)  (do (print (first snc))
(+ (* (Integer/parseInt (str (first snc))) (Integer/parseInt (str (first snc)))) snc-sum)) snc-sum))))
CompilerException java.lang.IllegalArgumentException: Mismatched argument count to recur, expected: 2 args, got: 3, compiling:(NO_SOURCE_PATH:5:4)



Uh, so, I have a bracket in the wrong place? I have keybindings set up so that Control-1 takes me to the start of any form, and Control-2 takes me to the end of any form, so I can usually, rather easily, see how the brackets line up. But that doesn’t save me from bad thinking under stress.

Maybe I’ll add in a print statement again:

user>
(defn happy [x]
(loop [snc (str x) snc-sum 0]
(if (seq (first snc))
(recur
(rest snc)  (do (print (first snc))
(+ (* (Integer/parseInt (str (first snc))) (Integer/parseInt (str (first snc)))) snc-sum))) snc-sum)))
#'user/happy
user>
(happy 31)
3
9



So, this never gets to the “1”, it only does the “3”. Why is that? Maybe instead of this:

(seq (rest snc))

I should do this:

(seq (first snc))

So I try:

user>
(defn happy [x]
(loop [snc (str x) snc-sum 0]
(if (seq (first snc))
(recur
(rest snc)  (do (print (first snc))
(+ (* (Integer/parseInt (str (first snc))) (Integer/parseInt (str (first snc)))) snc-sum))) snc-sum)))

#'user/happy
user>
(happy 31)
IllegalArgumentException Don't know how to create ISeq from: java.lang.Character  clojure.lang.RT.seqFrom (RT.java:505)



Yeah, what a stupid idea. I change it back, since that is obviously not where the problem is:

user>
(defn happy [x]
(loop [snc (str x) snc-sum 0]
(if (seq (rest snc))
(recur
(rest snc)  (do (print (first snc))
(+ (* (Integer/parseInt (str (first snc))) (Integer/parseInt (str (first snc)))) snc-sum))) snc-sum)))

#'user/happy



But where is the real problem? Oh, I see, in the “false” clause of the “if” statement, I need to sum the results:

user>
user>
(defn happy [x]
(loop [snc (str x) snc-sum 0]
(if (seq (rest snc))
(recur
(rest snc)  (do (print (first snc))
(+ (* (Integer/parseInt (str (first snc))) (Integer/parseInt (str (first snc)))) snc-sum))) (+ (first snc) snc-sum))))

#'user/happy
user>
(happy 31)
ClassCastException java.lang.Character cannot be cast to java.lang.Number  clojure.lang.Numbers.add (Numbers.java:126)
3



FML!!!! FML!!!! FML!!!! FML!!!! FML!!!! FML!!!! FML!!!! FML!!!! FML!!!!

The guy who is interviewing me has mostly stopped watching, because he’s already decided there is no chance in hell that they will be hiring me. He is looking at his phone. I half expect him to start playing Flappy Bird.

I realize now that the verbose and horrible “Integer/parseInt (str” needs to be applied to the sum at the end of the “if” statement:

user> (defn happy [x]
(loop [snc (str x) snc-sum 0]
(if (seq (rest snc))
(recur
(rest snc)  (do (print (first snc))
(+ (* (Integer/parseInt (str (first snc))) (Integer/parseInt (str (first snc)))) snc-sum))) (+  (Integer/parseInt (str (first snc))) snc-sum))))

#'user/happy
user>
(happy 31)
3
10



Awesome! I finally got “10”! I finally got the right number!

And yet, I am only at the start of this problem. Writing a simple function to find the next number in the sequence was suppose to be the easy part, and I just wasted 10-15 minutes on it!

So, how do I find out if a number is in a sequence, when the algorithm might lead to infinity? I had previously postponed the question, but now I came back to it. Again, our problem was English, not Clojure.

Thinking out loud, I said: “If the sequence can go to infinity, then I could create a generator that returns the numbers lazily… but at some point we would need to realize those values, to check them… ”

“That is one way to think about it,” he said.

I kept thinking out loud: “…and if they go to infinity, then they will crash my machine…”

“Are you sure?” he said.

I thought long and hard about that. Was I missing something obvious? Was there a way that my machine could count to infinity?

I was quiet a long moment because I was worried that whatever I said next would make me look stupid.

“Well, I could pass in some bound, like perhaps 10,000. I could pursue a finite number of tries before giving up.”

“Are you sure?” he repeated. “Are you sure the numbers go to infinity?”

“Didn’t you tell me that they go to infinity?”

“No,” he said, “I said they go infinitely.”

Finally, the light dawned in my head.

“Oh,” I said, “So they loop?”

“Yes.”

“Oh!” I finally got it. “So they loop over a finite set of numbers?”

“Yes.”

“Ah! So I only need to store the numbers in a set and then I can see if I start to loop?”

“Yes.”

Okay, so now I got it. I could store the numbers in a set, and if I ever saw the same number twice, then I knew that the number that I started with was not in the Happy sequence.

user>
(defn happy [x]
(loop [snc (str x) snc-sum 0 seen-so-far #{}]
(if (seen-so-far (Integer/parseInt (str (first snc))))
nil
(if (seq (rest snc))
(recur
(rest snc)
(+ (* (Integer/parseInt (str (first snc))) (Integer/parseInt (str (first snc)))) snc-sum))
(conj seen-so-far (Integer/parseInt (str (first snc))))
(+  (Integer/parseInt (str (first snc))) snc-sum)))))

CompilerException java.lang.RuntimeException: Too many arguments to if, compiling:(NO_SOURCE_PATH:5:7)



Ah, stupid! I’ve got a bracket in the wrong place for that second “if” statement. I’ll try again:

user>
(defn happy [x]
(loop [snc (str x) snc-sum 0 seen-so-far #{}]
(if (seen-so-far (Integer/parseInt (str (first snc))))
nil
(if (seq (rest snc))
(recur
(rest snc)
(+ (* (Integer/parseInt (str (first snc))) (Integer/parseInt (str (first snc)))) snc-sum)
(conj seen-so-far (Integer/parseInt (str (first snc)))))
(+  (Integer/parseInt (str (first snc))) snc-sum)))))

#'user/happy



Great! It compiles! So now I can:

user>
(happy 31)
10



Wait, what am I doing? The “happy” function simply finds me the next number in the sequence. I need a function, higher up the chain, that can loop through the whole series, and call “happy” on each iteration of the loop. I reset the “happy” function to the previous version that was working, and then I start on a new function:

(defn find-happiness [starting-integer]
(loop [test-integer starting-integer seen-so-far #{}]
(let [next-integer (happy next-integer)]
(if (seen-so-far next-integer)
nil
(recur
next-integer
(conj seen-so-far next-integer))))))



which gives me:

CompilerException java.lang.RuntimeException: Unable to resolve symbol: next-integer in this context, compiling:(NO_SOURCE_PATH:3:27)



Sloppy! I am not impressing myself.

I have to take a deep breath and think, for a moment, about what I want to return. By this point, so much time has dragged by that the guy who is suppose to be interviewing me has largely stopped paying attention to what I’m doing. I figure the interview is a bust anyway, so I can take a moment and think about things clearly. The pressure of time disappears once I realize there is no chance I am getting this job.

I know I want this:

	        (if (= next-integer 1)
true



That is, if the next number in the series is ever 1, then we know the starting number does belong to the Happy sequence, so we should return true.

And I know I want:

	      	   (if (seen-so-far next-integer)
nil



That is, if I have a set called “seen-so-far”, and I store all the numbers that I discover as I iterate through sequence, then if ever I see a number twice, I can conclude that the series is settling into an infinite loop, and I can return false, because then I will know that the starting number is definitely not part of the Happy sequence.

So this should work:

(defn find-happiness [starting-integer]
(loop [test-integer starting-integer seen-so-far #{}]
(let [next-integer (happy test-integer)]
(if (= next-integer 1)
true
(if (seen-so-far next-integer)
nil
(recur
next-integer
(conj seen-so-far next-integer)))))))
#'user/find-happiness



So I try it:

user>
(find-happiness 31)
true
user>
(find-happiness 32)
nil
user>
(find-happiness 33)
nil
user>
(find-happiness 34)
nil



Nice!!!! Very cool!!!

How about the first 100 numbers?

(map find-happiness (range 100))
(nil true nil nil nil nil nil nil nil nil true nil nil nil nil nil nil nil nil true nil nil nil nil nil nil true nil nil nil nil true nil nil nil nil nil nil nil nil nil nil nil true nil nil nil nil nil nil nil true nil nil nil nil true nil nil nil nil nil nil nil nil nil nil true nil nil nil nil true nil nil nil nil true nil nil nil nil nil true nil nil nil nil true nil nil nil true nil nil nil nil true nil nil)



Hmm, cool, but that is hard to read. Let me add in some print statements, so I can better understand the output:

user>
(defn find-happiness [starting-integer]
(println (str starting-integer))
(loop [test-integer starting-integer seen-so-far #{}]
(let [next-integer (happy test-integer)]
(if (= next-integer 1)
(do
(println " true ")
true)
(if (seen-so-far next-integer)
(do
(println " false ")
nil)
(recur
next-integer
(conj seen-so-far next-integer)))))))
#'user/find-happiness



And then:

user>
(map find-happiness (range 100))
(0
false
1
true
2
false
3
false
4
false
5
false
6
false
7
false
8
false
9
false
10
true
11
false
12
false
13
false
14
false
15
false
16
false
17
false
18
false
19
true
20
false
21
false
22
false
23
false
24
false
25
false
26
true
27
false
28
false
29
false
30
false
31
true
32
false
33
false
34
false
35
false
36
false
37
false
38
false
39
false
40
false
41
false
42
false
43
true
44
false
45
false
46
false
47
false
48
false
49
false
50
false
51
true
52
false
53
false
54
false
55
false
56
true
57
false
58
false
59
false
60
false
61
false
62
false
63
false
64
false
65
false
66
false
67
true
68
false
69
false
70
false
71
false
72
true
73
false
74
false
75
false
76
false
77
true
78
false
79
false
80
false
81
false
82
false
83
true
84
false
85
false
86
false
87
false
88
true
89
false
90
false
91
false
92
true
93
false
94
false
95
false
96
false
97
true
98
false
99
false )



Very cool!

And then I wanted to test one of these by hand just to make sure everything was working the way it should. It says that 97 is in the Happy sequence, so I tested to see if that was true:

user>
(happiness 97)
CompilerException java.lang.RuntimeException: Unable to resolve symbol: happiness in this context, compiling:(NO_SOURCE_PATH:1:1)



The level of self-sabotage is impressive, isn’t it?

Let’s try that again with a function I actually wrote:

user>
(happy 97)
88
user>
(happy 88)
72
user>
(happy 72)
51
user>
(happy 51)
26
user>
(happy 26)
10
user>
(happy 10)
1



Cool! It does work! And this is a cool number series!

Needless to say, the job interview was a disaster. I think they want someone who can write something like this in 5 minutes, but between the English-language confusion over the definition of the sequence, and the many mistakes I made, this dragged on for almost 30 minutes.

After I was done, the guy said something polite about “good effort” and then he said he would sent in the next engineer.

A few minutes later the next engineer came in. He asked me if I knew what the Collatz number sequence was. I said no. He drew a definition of it on the white board. He asked me to write some functions that would allow me to find the longest iterations through the Collatz sequence, given a set of starting numbers.

What followed was similar to the above: for more than 30 minutes I stumbled through the process, making dozens of mistakes as I went.

Interviews are weird: the pressure of time, and not being able to look things up, distorts the code. I am aware that the code I wrote was ugly, especially the atrocious casting of the number to a string, then to a sequence of Characters, then back to a string, and then back to an integer. But now that I am back in the real world, and able to do a Google Search, a quick search brings a top result that points me to an example by Saul Hazledine:

(map #(Character/digit % 10) (str number)))

So, in the real world, that is what I would have gone with and my code would have looked a bit better.

I guess there are engineers who stay calm in situations like this, and I assume this must be true of all the programmers who got hired at the place. I guess this is a bit like the situation in basketball, do you panic when a defender is faster and taller than you, or do you stay calm and pass the ball in an intelligent way. These tests perhaps bring out how I write code under pressure, like if its the end of the sprint and I’m working on a task that absolutely has to go out during this sprint, though hopefully such crunch-mode programming makes up less than 5% of our programming, since this is when the worst kinds of “technical debt” gets created. Or, possibly, tests like this allow them to hire those programmers who never create “technical debt” no matter how much pressure they are under — but I would be skeptical of that claim.

[UPDATE] David Tuite writes:

Expressing confusion in an interview doesn’t make you appear dumb. In reality it’s quite the opposite.