Skip to content

Instantly share code, notes, and snippets.

@ericnormand
Last active March 29, 2019 14:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ericnormand/7c6fd057b4675da1bf5079864d3c3ff6 to your computer and use it in GitHub Desktop.
Save ericnormand/7c6fd057b4675da1bf5079864d3c3ff6 to your computer and use it in GitHub Desktop.

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