class Factoradic

Constants

DEFAULT_OPTIONS
VERSION

Attributes

options[RW]

Public Class Methods

autoconvert(str) click to toggle source
# File lib/factoradic.rb, line 65
def autoconvert(str)
  if string_is_factoradic?(str)
    convert_factoradic_to_decimal(str)
  else
    convert_decimal_to_factoradic(str)
  end
end
basic_factorial(n) click to toggle source
# File lib/factoradic.rb, line 99
def basic_factorial(n)
  (1..n).reduce(1, :*)
end
convert_decimal_to_factoradic(decimal) click to toggle source
# File lib/factoradic.rb, line 79
def convert_decimal_to_factoradic(decimal)
  f = parse_decimal(decimal)
  f.to_s
end
Also aliased as: d2f
convert_factoradic_to_decimal(str) click to toggle source
# File lib/factoradic.rb, line 73
def convert_factoradic_to_decimal(str)
  f = parse_factoradic(str)
  f.to_i.to_s(10)
end
Also aliased as: f2d
d2f(decimal)
f2d(str)
factorial(n) click to toggle source
# File lib/factoradic.rb, line 103
def factorial(n)
  if options.memoize_factorial_values
    memoized_factorial(n)
  else
    basic_factorial(n)
  end
end
memoized_factorial(n) click to toggle source
# File lib/factoradic.rb, line 91
def memoized_factorial(n)
  if @factorial_sequence.length > n
    @factorial_sequence[n]
  else
    @factorial_sequence[n] = n * memoized_factorial(n - 1)
  end
end
new() click to toggle source
# File lib/factoradic.rb, line 112
def initialize
  @value = 0
  @digits = [0]
end
nonstandard_separator?() click to toggle source
# File lib/factoradic.rb, line 23
def nonstandard_separator?
  options.separator != DEFAULT_OPTIONS[:separator]
end
parse(str) click to toggle source
# File lib/factoradic.rb, line 57
def parse(str)
  if string_is_factoradic?(str)
    [parse_factoradic(str), :factorial]
  else
    [parse_decimal(str), :decimal]
  end
end
parse_decimal(decimal) click to toggle source
# File lib/factoradic.rb, line 42
def parse_decimal(decimal)
  intvalue = case decimal
             when Integer
               decimal
             when String
               decimal.to_i(10)
             else
               raise ArgumentError, "Expected an Integer or String{"
             end

  new.tap do |f|
    f.value = intvalue
  end
end
parse_factoradic(str) click to toggle source
# File lib/factoradic.rb, line 36
def parse_factoradic(str)
  new.tap do |f|
    f.parse_factoradic(str)
  end
end
string_is_factoradic?(str) click to toggle source
# File lib/factoradic.rb, line 27
def string_is_factoradic?(str)
  re = if nonstandard_separator?
         /\A\d+([#{options.separator}]\d+)+\Z/
       else
         /\A\d+([,:]\d+)+\Z/
       end
  !!(str =~ re)
end
valid_factoradic_digits?(digit_list) click to toggle source
# File lib/factoradic.rb, line 85
def valid_factoradic_digits?(digit_list)
  digit_list.reverse.map.with_index do |digit, idx|
    (digit >= 0) && (digit <= idx)
  end.all?(true)
end

Public Instance Methods

[](i) click to toggle source
# File lib/factoradic.rb, line 141
def [](i)
  @digits[i]
end
[]=(i, rvalue) click to toggle source
# File lib/factoradic.rb, line 145
def []=(i, rvalue)
  new_places = @digits.dup
  new_places[i] = rvalue.to_i
  self.digits = new_digits
end
digits=(new_digits) click to toggle source
# File lib/factoradic.rb, line 161
def digits=(new_digits)
  new_digits = new_digits.map do |x|
    if x.nil?
      0
    else
      x
    end
  end

  unless Factoradic.valid_factoradic_digits?(new_digits)
    raise ArgumentError, "Invalid factoradic digits: #{new_digits.inspect}"
  end

  @digits = new_digits
  recompute_value!
end
inspect() click to toggle source
# File lib/factoradic.rb, line 191
def inspect
  "#<Factoradic #{to_s}>"
end
options() click to toggle source
# File lib/factoradic.rb, line 117
def options
  self.class.options
end
parse_factoradic(str) click to toggle source
# File lib/factoradic.rb, line 151
def parse_factoradic(str)
  sep = if Factoradic.nonstandard_separator?
          /[#{Factoradic.options.separator}]/
        else
          /[,:]/
        end

  self.digits = str.split(sep).map{ |x| x.to_i }
end
recompute_digits!() click to toggle source
# File lib/factoradic.rb, line 121
def recompute_digits!
  x = @value
  divisor = 2
  @digits = [0]

  while x > 0
    x, r = x.divmod(divisor)
    @digits.push(r)
    divisor += 1
  end

  @digits.reverse!
end
recompute_value!() click to toggle source
# File lib/factoradic.rb, line 135
def recompute_value!
  @value = @digits.reverse.map.with_index do |digit, idx|
    digit * Factoradic.factorial(idx)
  end.reduce(&:+)
end
to_i() click to toggle source
# File lib/factoradic.rb, line 187
def to_i
  @value
end
to_s(separator = options.separator) click to toggle source
# File lib/factoradic.rb, line 183
def to_s(separator = options.separator)
  @digits.join(separator)
end
value=(new_value) click to toggle source
# File lib/factoradic.rb, line 178
def value=(new_value)
  @value = new_value.to_i
  recompute_digits!
end