Created
December 20, 2011 00:58
-
-
Save abscondment/1499697 to your computer and use it in GitHub Desktop.
Monkeying around with numbers.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns alphanumerics) | |
(use 'clojure.math.numeric-tower) | |
(defn to-alphabet [number alphabet-str] | |
(let [alpha (vec alphabet-str) | |
base (count alpha)] | |
(loop [result (list) | |
quotient number] | |
(if (zero? quotient) | |
(if (empty? result) "0" | |
(apply str result)) | |
(recur | |
;; Find the remainder and add the character | |
;; at the corresponding index. | |
(cons (nth alpha (rem quotient base)) | |
result) | |
;; Divide by the base again. | |
(quot quotient base)))))) | |
(defn from-alphabet [number-str alphabet-str] | |
(let [alphabet-map (apply hash-map | |
(interleave | |
(distinct (seq alphabet-str)) | |
(iterate inc 0))) | |
base (-> alphabet-map keys count)] | |
(loop [chars (reverse (seq number-str)) | |
pos 0 | |
result 0] | |
(if (empty? chars) result | |
(recur (rest chars) | |
(inc pos) | |
(+ result | |
(* (get alphabet-map (first chars)) | |
(expt base pos)))))))) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Alphanumerics | |
private | |
# Takes an alphabet and returns an Array of distinct characters. | |
def normalize_alphabet(a) | |
a = a.split(//) unless a.is_a?(Enumerable) | |
a.uniq! | |
return a | |
end | |
# Normalizes and alphabet and return a mapping to translated int values. | |
def alphabet_to_map(a) | |
a = normalize_alphabet(a) | |
a.inject(Hash.new{|h,k| h[k] = h.keys.length}){|h,v| h[v]; h}.freeze | |
end | |
end | |
class Integer | |
include Alphanumerics | |
# Returns this Integer as represented by the given alphabet. | |
def to_alphabet(alpha) | |
q = self | |
raise ArgumentError.new('You may only call this on a positive integer.') if q < 0 | |
alpha = normalize_alphabet(alpha) | |
base = alpha.length | |
result = '' | |
while q != 0 | |
q, r = q.divmod(base) | |
result.prepend alpha[r] | |
end | |
result.empty? ? '0' : result | |
end | |
end | |
class String | |
include Alphanumerics | |
# Decodes the Integer represented by this string using the given alphabet. | |
def to_i_from_alphabet(alpha) | |
parts = self.split(//) | |
alpha = alphabet_to_map(alpha) | |
base = alpha.length | |
total = 0 | |
pos = 0 | |
while x = parts.pop | |
total += alpha[x] * (base ** pos) | |
pos += 1 | |
end | |
total | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment