Skip to content

Instantly share code, notes, and snippets.

@ericnormand ericnormand/00 Digits.md
Last active Mar 29, 2019

Embed
What would you like to do?

list of digits

Write a function that takes a number and returns a sequence of digits. Here's an example:

(digits 3452)
;=> [3 4 5 2]

For extra credit, let digit take another parameter, which is the base of the number in which to represent digits. The default will be 10, but it should work for any number >= 2.

(digits 3452 2) ;; 2 means binary
;=> [1 1 0 1 0 1 1 1 1 1 0 0]

Bonus points for clarity, interest, and efficiency.

(defn digits
([n]
(it-> n
(str it) ; convert to string base 10
(mapv str it) ; convert seq of chars to seq of len-1 strings
(mapv #(Integer/parseInt %) it)))
([n r]
(it-> n
(long n) ; coerce to primitive
(Long/toString it r) ; convert to string base r
(mapv str it) ; convert seq of chars to seq of len-1 strings
(mapv #(Integer/parseInt %) it))))
(dotest
(is= (digits 3452) [3 4 5 2])
(is= (digits 3452 2) [1 1 0 1 0 1 1 1 1 1 0 0])
)
(defn digits
([n]
(digits n 10))
([n base]
(loop [n n, acc '()]
(let [quotient (quot n base)]
(cond->> (cons (rem n base) acc)
(not (zero? quotient)) (recur quotient))))))
(require '[clojure.math.numeric-tower :as math])
(defn digits
([n]
(digits n 10))
([n base]
(let [negative? (neg? n)]
(loop [n (math/abs n), acc '()]
(let [quotient (quot n base)
acc (cons (rem n base) acc)]
(cond
(pos? quotient) (recur quotient acc)
negative? (update (vec acc) 0 -)
:else acc))))))
(digits -3452) ; -> [-3 4 5 2]
(digits -3452 2) ; -> [-1 1 0 1 0 1 1 1 1 1 0 0]
(defn digits
([n]
(digits n 10))
([n base]
(loop [n n
ds '()]
(if (< n base)
(into [] (conj ds n))
(recur (quot n base) (conj ds (mod n base)))))))
(defn digits
([n]
(digits n 10))
([n base]
(reduce #(conj %1 %2) [] (Integer/toString n base))))
(defn digits
([n] (digits n 10))
([n base]
(if (>= n base)
(conj (digits (quot n base) base) (mod n base))
[n])))
;; minimal
(defn digits [n] (map #(- (int %) 48) (str n)))
;; Extra credit - but leverages Java
(defn digits [n & [base]]
(map #(- (int %) 48) (Integer/toString n (or base 10))))
;; Pure Clojure
(defn digits [n & [base]]
(let [b (or base 10)]
(if (< n b)
[n]
(conj (digits (quot n b) b) (rem n b)))))
(defn digits
"Given a number, `n`, return a sequence of its digits. If a `base` is
provided, convert to that base, otherwise base 10 (decimal)."
([n] (digits n 10))
([n base]
(loop [acc '() x n]
(if (= 0 x)
acc
(recur (cons (rem x base) acc) (quot x base))))))
(defn digits
[n & [base]]
{:pre [(or (nil? base)
(and (<= 2 base 10)
(int? base)))]}
(into []
(for [d (Integer/toString n (or base 10))]
(Integer. (str d)))))
(defn digits [base n]
(loop [res ()
n n]
(if (zero? n)
res
(recur (conj res (mod n base))
(long (/ n base))))))
(defn digits
([x]
(digits x 10))
([x base]
(loop [digits [] x x]
(if (pos? x)
(recur (cons (mod x base) digits) (quot x base))
digits))))
(defn digits
([n] (digits n 10))
([n radix]
{:pre [(int? n) (int? radix) (not (neg? n)) (>= radix 2)]}
(loop [n n res ()]
(if (< n radix)
(conj res n)
(recur (quot n radix) (conj res (rem n radix)))))))
(defn digits
([number] (digits number 10))
([number base]
(if (pos? number)
(let [ones-place-value (mod number base)
number-shifted-right (/ (- number ones-place-value) base)]
(conj (digits number-shifted-right base) ones-place-value))
[])))
(defn digits
([n] (digits n 10))
([n radix]
(if (zero? n)
[0]
(->> n
(iterate #(quot % radix))
(take-while pos?)
(map #(rem % radix))
reverse
vec))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.