Another programming challenge

I woke up with another programming challenge in my inbox this morning. This one is from Square. They are a company that gives you a little device so that you can accept credit cards using a smart phone. The challenge is here – basically it's about removing credit cards numbers from logs. There are some details about what constitutes a credit card number, and how they are distinct from other numbers. I won't repeat that here, but you should read it to understand what's coming up.

As usual, I implemented my solution in Clojure. I particularly liked the function I called luhn-check. Here it is:

(defn luhn-check
  "Takes a sequence of digits and determines whether they pass the Luhn test.
   The sequence must be in order from right to left."
  [digits]
  (->> digits
       (partition 2 2 (repeat 0))
       (mapcat #(vector (first %) (* 2 (second %))))
       (reduce #(+ %1 (int (/ %2 10)) (int (mod %2 10))))
       (#(mod % 10))
       (= 0)))

I think this is a good illustration of the ->> operator in Clojure, which is also called the "thrush" operator. Basically, this operator can be thought of as taking the result from one expression and putting it at the end of the next expression.

In this case, we start out with a list of digits. We then partition them into pairs, padding with a zero if necessary. We then take the pairs and double the second number in the pair, concatenating all the pairs back into a single list. We then sum up all the digits in the list, using the reduce function. This leaves us with a number. We get its value \(\mod 10\) and test whether it is equal to zero. If it is, we return true, otherwise we return false.

All of this could be written with nested expressions (and the thrush operator is simply a macro that rewrites what you see as nested expressions), but I think the way it is written nicely shows what the data is doing in the function.

Anyway, I don't know if this solution will get me a job, but it was a bit of fun coding and didn't take too long.

blog comments powered by Disqus