Skip to content

Instantly share code, notes, and snippets.

@abscondment
Created December 20, 2011 00:58
Show Gist options
  • Save abscondment/1499697 to your computer and use it in GitHub Desktop.
Save abscondment/1499697 to your computer and use it in GitHub Desktop.
Monkeying around with numbers.
(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))))))))
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