Class: EightCorner::StringMapper

Inherits:
Object
  • Object
show all
Defined in:
lib/eight_corner/string_mapper.rb

Overview

StringMapper provides various methods for converting strings to percentage/potential values, which can then be mapped to (x,y) points.

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ StringMapper

Returns a new instance of StringMapper.



7
8
9
10
11
12
13
14
15
16
17
18
19
20
# File 'lib/eight_corner/string_mapper.rb', line 7

def initialize(options={})
  defaults = {
    group_count: 7,
    min_group_size: 3
  }
  Base.validate_options!(options, defaults)
  options = defaults.merge(options)

  @group_count = options[:group_count]
  @group_max_idx = @group_count - 1
  @min_group_size = options[:min_group_size]

  @frequencies = {"E"=>0.103202, "A"=>0.095238, "R"=>0.092638, "N"=>0.087925, "O"=>0.075898, "S"=>0.065659, "L"=>0.064196, "I"=>0.046481, "T"=>0.040793, "H"=>0.03868, "C"=>0.038193, "D"=>0.03413, "M"=>0.033317, "B"=>0.023891, "G"=>0.023566, "Y"=>0.022103, "U"=>0.021615, "W"=>0.019178, "K"=>0.016252, "P"=>0.015602, "F"=>0.011539, "V"=>0.010889, "Z"=>0.010076, "J"=>0.003738, " "=>0.00195, "X"=>0.00195, "Q"=>0.000975}
end

Instance Method Details

#group1(str, idx) ⇒ Object

sequential series of characters extracted from string. loops back to beginning for short strings



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/eight_corner/string_mapper.rb', line 54

def group1(str, idx)
  range = 0..@group_max_idx
  return ArgumentError, "argument must be in #{range}" if ! range.include?(idx)

  str_size = str.size
  g_size = group_size str

  out = ""

  start_idx = (idx * g_size)
  end_idx = start_idx + g_size

  (start_idx...end_idx).each do |x|
    out += str[x % str_size]
  end

  out
end

#group2(str, idx) ⇒ Object

builds a group from every nth character in the string.



74
75
76
77
78
79
80
81
82
# File 'lib/eight_corner/string_mapper.rb', line 74

def group2(str, idx)
  str_size = str.size

  out = ''
  group_size(str).times do |i|
    out += str[(i * @group_count + idx) % str_size]
  end
  out
end

#group_size(str) ⇒ Object

how many characters should be in each group?



85
86
87
88
89
90
# File 'lib/eight_corner/string_mapper.rb', line 85

def group_size(str)
  [
    str.size / @group_count,
    @min_group_size
  ].max
end

#groups(str, method) ⇒ Object

split a string into groups, via :method

Raises:

  • (ArgumentError)


42
43
44
45
46
47
48
49
50
# File 'lib/eight_corner/string_mapper.rb', line 42

def groups(str, method)
  raise ArgumentError, "Invalid method #{arg}" if ! respond_to?(method)

  out = []
  @group_count.times do |i|
    out << send(method, str, i)
  end
  out
end

#percentize_frequency(str) ⇒ Object

turn a string into a float 0..1 a string with common letters should be near 0.5. a string with uncommon letters should be near 0 or 1.



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/eight_corner/string_mapper.rb', line 104

def percentize_frequency(str)
  # letters aren't evenly distributed.
  # a string that has every letter once would add up to 1.

  # totally common: sum would be E*3

  common = @frequencies.first[1] * str.size

  sum = 0
  str.upcase.each_char {|c| sum += @frequencies[c].to_f }

  distance = common - sum # distance from common.

  # add or subtract from 0.5?
  # all letters are positive/negative based on order in frequency distribution.
  m = 1
  @frequencies.keys.each do |i|
    m *= -1
    break if str[0].upcase == i
  end

  interp = Interpolate::Points.new({0=>0, common=>0.5})
  pct_distance = interp.at(distance)
  # interpolate (0 .. common) => (0 .. 0.5)
  # multiply by m and add to 0.5

  pct_distance * m + 0.5
end

#percentize_modulus(str) ⇒ Object



92
93
94
95
# File 'lib/eight_corner/string_mapper.rb', line 92

def percentize_modulus(str)
  # i+memo just to add some order-dependency. "alex" != "xela"
  (str.each_byte.inject(0){|memo,i| memo += i + memo; memo} % 100)/100.to_f
end

#percentize_modulus_exp(str) ⇒ Object



97
98
99
# File 'lib/eight_corner/string_mapper.rb', line 97

def percentize_modulus_exp(str)
  (str.each_byte.inject(0){|memo,i| memo += i^2 + memo; memo} % 100)/100.to_f
end

#potentials(groups, percentizeA, percentizeB) ⇒ Object

return an array of 2-float arrays. provide method symbols for and percentizing method for constructing the 2 array elements.



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/eight_corner/string_mapper.rb', line 24

def potentials(groups, percentizeA, percentizeB)
  [percentizeA, percentizeB].each do |arg|
    raise ArgumentError, "Invalid method #{arg}" if ! respond_to?(arg)
  end

  out = []
  groups.each do |i|
    # puts send(groupA, str, i)
    out << [
      send(percentizeA, i),
      send(percentizeB, i),
    ]
  end

  out
end