 An Armstrong number is a number that is the sum of its own digits each raised to the power of the number of digits.

For example:

• 9 is an Armstrong number, because 9 = 91 = 9
• 10 is not an Armstrong number, because 10 != 12 + 02 = 1
• 153 is an Armstrong number, because: 153 = 13 + 53 + 33 = 1 + 125 + 27 = 153
• 154 is not an Armstrong number, because: 154 != 13 + 53 + 43 = 1 + 125 + 64 = 190

Write some code to determine whether a number is an Armstrong number.

``````(ns armstrong-numbers
(:require [cljs.test :refer-macros [deftest testing is run-tests]]))

(defn armstrong? [n]
)

(deftest armstrong-number-5
(testing "Single digit numbers are Armstrong numbers"
(is (armstrong? 5))))

(deftest not-armstrong-number-10
(testing "There are no 2 digit Armstrong numbers"
(is (not (armstrong? 10)))))

(deftest armstrong-number-153
(testing "Three digit number that is an Armstrong number"
(is (armstrong? 153))))

(deftest not-armstrong-number-100
(testing "Three digit number that is not an Armstrong number"
(is (not (armstrong? 100)))))

(deftest armstrong-number-9474
(testing "Four digit number that is an Armstrong number"
(is (armstrong? 9474))))

(deftest not-armstrong-number-9475
(testing "Four digit number that is not an Armstrong number"
(is (not (armstrong? 9476)))))

(deftest armstrong-number-9926315
(testing "Seven digit number that is an Armstrong number"
(is (armstrong? 9926315))))

(deftest not-armstrong-number-9926314
(testing "Seven digit number that is not an Armstrong number"
(is (not (armstrong? 9926314)))))

(run-tests)
``````

This was my first iteration.

Note: The code on this page is modified slightly for Clojurescript. `js/parseInt` is JavaScript interop and will not work in Clojure. Instead, use `Character/digit` or `Integer/parseInt`. Or better yet - see below for a way to do it with math.

``````(defn digits [n]
(map #(js/parseInt (str %))  (seq (str n))))

(defn exp [x n]
(reduce * (repeat n x)))

(defn numdigits [n]
(count (digits n)))

(defn multiplier [n]
(map #(exp % (numdigits n)) (digits n)))

(reduce + (multiplier n)))

(defn armstrong? [n]

(run-tests)
``````

I tried to tackle the problem in multiple stages, defining functions that each get us one step closer to the solution. It worked, but my mentor encouraged me to try a more idiomatic approach. So I basically took the functions and squashed them together:

``````(defn digits [n]
(map #(js/parseInt (str %))
(seq (str n))))

(defn armstrong [n]
(reduce + (map #(Math/pow % (count (digits n)))
(digits n))))

(defn armstrong? [n]
(== (armstrong n) n))

(run-tests)
``````

Also by using Java's `Math/pow` I got to eliminate the exponent function. I decided to take this and run with it, however we still could do better:

``````(defn armstrong? [n]
(let [digits (->> n str (map #(js/parseInt % 10)))]
(->> digits
(map #(Math/pow % (count digits)))
(apply +)
(== n))))

(run-tests)
``````

The difference is mostly stylistic, but readability ought to be a strong priority. By using the threading macros, it is much easier to discern the order of operations.

Here's how to get the digits of a number without turning it into a string or using interop:

``````(defn digits [n]
(if (>= n 10)
(conj (digits (quot n 10))
(rem n 10))
[n]))

(digits 1234)
``````