I solved the full Programming Praxis Alien Numbers exercise in Clojure. This enabled me to learn more about Clojure and to train my algorithmic parts of the brain a bit.
In all this I was a bit disappointed. It took me too much time to reach a full solution and then, in the core part of the exercise I had to resort to one of the other persons to reach a better way to convert a decimal number to an arbitrary radix number given its language.
I was also a bit disappointed in the way that I wasn't able to use Clojure's laziness more in the algorithms, resorting too much for my taste to loop
. From a positive point of view, the Clojure abstractions work as advertised and the only difference from the code bellow and another that would use instead of string
s a vector
s or list
s would be the conversion in the return value of decimal-to-lang
.
Follows the core of the exercise solution. Note that the full solution with tests is here. Still considering the Clojure sweet points, I think I could easily explore its excellent support for concurrency and convert the main
algorithm into a parallel one if there were hundreds of lines to be processed.
(defn decimal-to-lang "Converts decimal-num to the equivalent number in lang as a string. The algorithm was a translation of the algorithm by Rodrigo Menezes in C# that he posted in the programming praxis site." [decimal-num lang] (let [lang-radix (count lang)] (loop [decimal-value decimal-num lang-num []] (if (>= 0 decimal-value) (apply str lang-num) (recur (int (/ decimal-value lang-radix)) (concat [(nth lang (mod decimal-value lang-radix))] lang-num)))))) (defn digit-index [digit lang] (loop [i 0] (if (= digit (nth lang i)) i (recur (inc i))))) (defn lang-to-decimal [alien-num lang] (let [radix (count lang) ralien-num (reverse alien-num)] (loop [i 0 decimal-num 0 product 1] (if (= i (count ralien-num)) decimal-num (recur (inc i) (+ decimal-num (* (digit-index (nth ralien-num i) lang) product)) (* radix product)))))) (defn convert-num "Convert alien-num which is in source-lang into the same number in target-lang" [alien-num source-lang target-lang] (decimal-to-lang (lang-to-decimal alien-num source-lang) target-lang))