Reputation: 153
I am supposed to write a function of 2 arguments, that converts the first number from base 10
to base b
. The returned value should be a collection.
I tried using format but I don't know how to use it if b
is 2,9,0
etc..
(defn f[x y]
(cond
(= y 8)(format "octal %o" x)
(= y 16)(format "hex %x" x)
(= y 10)(format "decimal %d" x)
:else 0))
Upvotes: 2
Views: 4441
Reputation: 1681
Here is mine pure Clojure solution:
(def charset "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
(def num->char
(into {} (map-indexed vector charset)))
(def char->num
(into {} (map-indexed (comp vec reverse vector) charset)))
(def base (count charset))
(def divmod (juxt quot rem))
(defn exp [x n]
(loop [acc 1 n n]
(if (zero? n) acc
(recur (* x acc) (dec n)))))
(defn encode [n]
(loop [n n a ""]
(let [[div mod] (divmod n base)]
(if (zero? div)
(str (get num->char mod) a)
(recur div (str (get num->char mod) a))))))
(defn decode-pair [idx chr]
(* (get char->num chr)
(exp base idx)))
(def sum (partial reduce +))
(defn decode [s]
(sum (map-indexed decode-pair (reverse s))))
Usage:
(encode 1000000000)
15FTGg
(decode "15FTGg")
1000000000
(-> 1000 encode decode (= 1000))
true
Upvotes: 3
Reputation: 6956
The following functions will do the conversion, casting to java's BigInteger so it will also work for integer values over Integer/MAX_VALUE
(2147483647)
(defn to-radix
[int r]
(.toString (biginteger int) r))
(to-radix 255 2)
=> "11111111"
(defn from-radix
[str r]
(BigInteger. str r)
(from-radix "11111111" 2)
=> 255
Strings can be considered a collection of characters. Map, filter, reduce etc. will call seq
to traverse it. In other cases you can just call seq
yourself.
(seq (to-radix 255 2))
=> (\1 \1 \1 \1 \1 \1 \1 \1)
Upvotes: 2
Reputation: 685
Given that this is not some kind of exercise where you have to
do the conversion manually, you can use Java's Integer.toString
e.g.
user> (Integer/toString 123456 13) ;; 123456 in base 13
"44268"
As for the sequence part you can just (seq (Integer/toString numb base)
However, this will return the chars (0-9 and a-z). You'll probably
want a lookup function in order to get the numbers.
Also check toString documentation for allowed radices.
If on the other hand the requirement is that you convert manually then this MO article is probably a good start.
Upvotes: 8
Reputation: 9276
(defn to-digits
[n b]
(loop [n n
digits ()]
(if (pos? n)
(recur (quot n b)
(conj digits (mod n b)))
digits)))
Upvotes: 2