Class: MoreMath::StringNumeral

Inherits:
Object
  • Object
show all
Includes:
NumberifyStringFunction
Defined in:
lib/more_math/string_numeral.rb

Overview

StringNumeral provides a way to treat strings as numbers using a base-N system where N is the size of the alphabet. This allows for arithmetic operations on strings, converting them to numeric representations and back.

The implementation uses the Cantor pairing function approach for encoding strings into integers and vice versa, making it suitable for applications requiring ordered string enumeration or Gödel numbering.

Examples:

Basic usage

include MoreMath

# Convert a string to its numeric representation
str_num = "abc".to_string_numeral
puts str_num.number  # => 731  (assuming 'a'..'z' alphabet)

# Convert back to string
puts 731.to_string_numeral.string  # => "abc"

Arithmetic operations

a = "hello".to_string_numeral
b = "world".to_string_numeral

# Addition
sum = a + b
puts sum.string  # => "hello" + "world" (in numeric sense)

With custom alphabet

custom_alphabet = ['a', 'b', 'c']
str_num = StringNumeral.from("abc", custom_alphabet)
puts str_num.number  # => 18 (base-3 representation)

Defined Under Namespace

Modules: Functions

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from NumberifyStringFunction

#compute_size, compute_size, #convert_alphabet, convert_alphabet, #numberify_string, numberify_string, #stringify_number, stringify_number

Methods included from Functions

#beta, beta, #beta_regularized, beta_regularized, #cantor_pairing, cantor_pairing, #cantor_pairing_inv, cantor_pairing_inv, #erf, #erfc, #gamma, gamma, #gammaP_regularized, gammaP_regularized, #gammaQ_regularized, gammaQ_regularized, #log_beta, log_beta, #log_ceil, log_ceil, #log_floor, log_floor, #log_gamma, #logb, logb, #numberify_string, numberify_string, #stringify_number, stringify_number

Constructor Details

#initialize(string, number, alphabet) ⇒ StringNumeral

Initializes a StringNumeral instance.

This private constructor handles the internal state setup for either string-to-number or number-to-string conversion.

Parameters:

  • string (String, nil)

    The string representation (if converting from string)

  • number (Integer, nil)

    The numeric representation (if converting from number)

  • alphabet (Array<String>, Range<String>)

    The alphabet to use

Raises:

  • (ArgumentError)

    If the string contains characters not in the alphabet



86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/more_math/string_numeral.rb', line 86

def initialize(string, number, alphabet)
  @alphabet = NumberifyStringFunction.convert_alphabet(alphabet).freeze
  if string
    @string = string.to_s
    string.each_char.each do |c|
      @alphabet.include?(c) or raise ArgumentError,
        "illegal character #{c.inspect} in #{@string.inspect} for alphabet #{@alphabet.inspect}"
    end
  elsif number
    @number = number.to_i
  end
end

Instance Attribute Details

#alphabetArray<String> (readonly)

Returns the alphabet used by this StringNumeral.

Returns:

  • (Array<String>)

    The alphabet array



135
136
137
# File 'lib/more_math/string_numeral.rb', line 135

def alphabet
  @alphabet
end

Class Method Details

.from(object, alphabet = 'a'..'z') ⇒ StringNumeral

Creates a StringNumeral instance from an object.

This is the primary factory method that handles conversion from various input types:

  • Symbol: converts to string first

  • String: uses directly as string representation

  • Integer: converts to numeric representation

  • Other objects: calls to_str or to_int as appropriate

Parameters:

  • object (Object)

    The input object to convert

  • alphabet (Array<String>, Range<String>) (defaults to: 'a'..'z')

    The alphabet to use for conversion

Returns:



47
48
49
50
51
52
53
54
55
56
57
# File 'lib/more_math/string_numeral.rb', line 47

def self.from(object, alphabet = 'a'..'z')
  if Symbol === object
    StringNumeral.from_string(object.to_s, alphabet)
  elsif object.respond_to?(:to_str)
    StringNumeral.from_string(object.to_str, alphabet)
  elsif object.respond_to?(:to_int)
    StringNumeral.from_number(object.to_int, alphabet)
  else
    StringNumeral.from_string(object.to_s, alphabet)
  end
end

.from_number(number, alphabet) ⇒ StringNumeral

Creates a StringNumeral instance from a number.

Parameters:

  • number (Integer)

    The number to convert

  • alphabet (Array<String>, Range<String>)

    The alphabet to use

Returns:



73
74
75
# File 'lib/more_math/string_numeral.rb', line 73

def self.from_number(number, alphabet)
  new nil, number, alphabet
end

.from_string(string, alphabet) ⇒ StringNumeral

Creates a StringNumeral instance from a string.

Parameters:

  • string (String)

    The string to convert

  • alphabet (Array<String>, Range<String>)

    The alphabet to use

Returns:



64
65
66
# File 'lib/more_math/string_numeral.rb', line 64

def self.from_string(string, alphabet)
  new string, nil, alphabet
end

Instance Method Details

#%(other) ⇒ StringNumeral

Performs modulo operation with another StringNumeral or numeric value.

Parameters:

Returns:

  • (StringNumeral)

    A new StringNumeral instance representing the remainder



183
184
185
# File 'lib/more_math/string_numeral.rb', line 183

def %(other)
  self.class.from_number((number % naturalize(other)), @alphabet)
end

#&(other) ⇒ StringNumeral

Performs bitwise AND with another numeric value.

Parameters:

  • other (Integer)

    The value to AND with

Returns:

  • (StringNumeral)

    A new StringNumeral instance representing the result



223
224
225
# File 'lib/more_math/string_numeral.rb', line 223

def &(other)
  self.class.from_number(number & naturalize(other), @alphabet)
end

#*(other) ⇒ StringNumeral

Performs multiplication with another StringNumeral or numeric value.

Parameters:

Returns:

  • (StringNumeral)

    A new StringNumeral instance representing the product



159
160
161
# File 'lib/more_math/string_numeral.rb', line 159

def *(other)
  self.class.from_number(number * naturalize(other), @alphabet)
end

#**(other) ⇒ StringNumeral

Performs exponentiation with another StringNumeral or numeric value.

Parameters:

Returns:

  • (StringNumeral)

    A new StringNumeral instance representing the power



191
192
193
# File 'lib/more_math/string_numeral.rb', line 191

def **(other)
  self.class.from_number(number ** naturalize(other), @alphabet)
end

#+(other) ⇒ StringNumeral

Performs addition with another StringNumeral or numeric value.

Parameters:

Returns:

  • (StringNumeral)

    A new StringNumeral instance representing the sum



151
152
153
# File 'lib/more_math/string_numeral.rb', line 151

def +(other)
  self.class.from_number(number + naturalize(other), @alphabet)
end

#-(other) ⇒ StringNumeral

Performs subtraction with another StringNumeral or numeric value.

Parameters:

Returns:

  • (StringNumeral)

    A new StringNumeral instance representing the difference



167
168
169
# File 'lib/more_math/string_numeral.rb', line 167

def -(other)
  self.class.from_number(naturalize(number - other), @alphabet)
end

#/(other) ⇒ StringNumeral

Performs division with another StringNumeral or numeric value.

Parameters:

Returns:

  • (StringNumeral)

    A new StringNumeral instance representing the quotient



175
176
177
# File 'lib/more_math/string_numeral.rb', line 175

def /(other)
  self.class.from_number((number / naturalize(other)), @alphabet)
end

#<<(other) ⇒ StringNumeral

Performs left bit shift with another numeric value.

Parameters:

  • other (Integer)

    The number of bits to shift

Returns:

  • (StringNumeral)

    A new StringNumeral instance representing the shifted value



199
200
201
# File 'lib/more_math/string_numeral.rb', line 199

def <<(other)
  self.class.from_number(number << naturalize(other), @alphabet)
end

#>>(other) ⇒ StringNumeral

Performs right bit shift with another numeric value.

Parameters:

  • other (Integer)

    The number of bits to shift

Returns:

  • (StringNumeral)

    A new StringNumeral instance representing the shifted value



207
208
209
# File 'lib/more_math/string_numeral.rb', line 207

def >>(other)
  self.class.from_number(number >> naturalize(other), @alphabet)
end

#[](other) ⇒ StringNumeral

Performs indexing operation on the numeric value.

Parameters:

  • other (Integer)

    The index to access

Returns:

  • (StringNumeral)

    A new StringNumeral instance representing the indexed result



239
240
241
# File 'lib/more_math/string_numeral.rb', line 239

def [](other)
  self.class.from_number(number[other.to_i], @alphabet)
end

#^(other) ⇒ StringNumeral

Performs bitwise XOR with another numeric value.

Parameters:

  • other (Integer)

    The value to XOR with

Returns:

  • (StringNumeral)

    A new StringNumeral instance representing the result



215
216
217
# File 'lib/more_math/string_numeral.rb', line 215

def ^(other)
  self.class.from_number(number ^ naturalize(other), @alphabet)
end

#coerce(other) ⇒ Array<Integer>

Converts another object to a numeric value for arithmetic operations.

This method is used in Ruby’s coercion protocol to enable mixed-type arithmetic.

Parameters:

  • other (Object)

    The other operand

Returns:

  • (Array<Integer>)

    Array containing the naturalized values



143
144
145
# File 'lib/more_math/string_numeral.rb', line 143

def coerce(other)
  [ naturalize(other), number ]
end

#eql?(other) ⇒ Boolean Also known as: ==

Checks equality with another object.

Parameters:

  • other (Object)

    The object to compare with

Returns:

  • (Boolean)

    true if equal, false otherwise



279
280
281
282
283
284
285
# File 'lib/more_math/string_numeral.rb', line 279

def eql?(other)
  if other.respond_to?(:to_int)
    to_int == other.to_int
  elsif other.respond_to?(:to_str)
    to_str == other.to_str
  end
end

#hashInteger

Returns a hash value for this StringNumeral.

Returns:

  • (Integer)

    The hash value



292
293
294
# File 'lib/more_math/string_numeral.rb', line 292

def hash
  number.hash
end

#inspectString

Returns a string representation for debugging.

Returns:

  • (String)

    A debug-friendly representation of this instance



128
129
130
# File 'lib/more_math/string_numeral.rb', line 128

def inspect
  "#<#{self.class}: #{string.inspect} #{number.inspect}>"
end

#naturalize(number) ⇒ Integer (private)

Ensures a value is treated as a non-negative integer.

Parameters:

  • number (Object)

    The number to normalize

Returns:

  • (Integer)

    The normalized non-negative integer



302
303
304
305
# File 'lib/more_math/string_numeral.rb', line 302

def naturalize(number)
  number = number.to_i
  number < 0 ? 0 : number
end

#numberInteger Also known as: to_i, to_int

Returns the numeric representation of this StringNumeral.

This method converts the internal string representation to its numeric value using the specified alphabet. The conversion follows a positional numeral system where each character position represents a power of the alphabet size.

Returns:

  • (Integer)

    The numeric representation



107
108
109
# File 'lib/more_math/string_numeral.rb', line 107

def number
  @number ||= numberify_string(@string, @alphabet)
end

#predStringNumeral

Returns the predecessor of this StringNumeral.

Returns:

  • (StringNumeral)

    A new StringNumeral with number decremented by 1



262
263
264
# File 'lib/more_math/string_numeral.rb', line 262

def pred
  self.class.from_number(naturalize(number - 1), @alphabet)
end

#pred!self

Decrements this StringNumeral in place.

Returns:

  • (self)

    Returns self after decrementing



269
270
271
272
273
# File 'lib/more_math/string_numeral.rb', line 269

def pred!
  @number = naturalize(@number - 1)
  @string = nil
  self
end

#stringString Also known as: to_s, to_str

Returns the string representation of this StringNumeral.

This method converts the internal numeric representation back to its string form using the specified alphabet. It’s the inverse operation of #number.

Returns:

  • (String)

    The string representation



119
120
121
# File 'lib/more_math/string_numeral.rb', line 119

def string
  @string ||= stringify_number(@number, @alphabet).freeze
end

#succStringNumeral

Returns the successor of this StringNumeral.

Returns:

  • (StringNumeral)

    A new StringNumeral with number incremented by 1



246
247
248
# File 'lib/more_math/string_numeral.rb', line 246

def succ
  self.class.from_number(number + 1, @alphabet)
end

#succ!self

Increments this StringNumeral in place.

Returns:

  • (self)

    Returns self after incrementing



253
254
255
256
257
# File 'lib/more_math/string_numeral.rb', line 253

def succ!
  @number += 1
  @string = nil
  self
end

#|(other) ⇒ StringNumeral

Performs bitwise OR with another numeric value.

Parameters:

  • other (Integer)

    The value to OR with

Returns:

  • (StringNumeral)

    A new StringNumeral instance representing the result



231
232
233
# File 'lib/more_math/string_numeral.rb', line 231

def |(other)
  self.class.from_number(number | naturalize(other), @alphabet)
end