Class: Set

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(data = nil) ⇒ Set

Returns a new instance of Set.



14
15
16
17
18
19
# File 'lib/setfu.rb', line 14

def initialize(data=nil)
  @bits = 0
  @entropy = 0
  add!(data) unless data.nil?
  self
end

Instance Attribute Details

#entropyObject

Returns the value of attribute entropy.



4
5
6
# File 'lib/setfu.rb', line 4

def entropy
  @entropy
end

Instance Method Details

#!=(item) ⇒ Object



138
139
140
141
142
143
144
145
# File 'lib/setfu.rb', line 138

def !=(item)
  if(item.class==Set)
    rtn = item.to_i != self.to_i
  else
    rtn = Set.new(item).to_i != self.to_i
  end
  rtn
end

#&(item) ⇒ Object



93
94
95
96
97
98
99
100
101
102
# File 'lib/setfu.rb', line 93

def &(item)
  rtn = self.dup
  if(item.class==Set)
    rtn.set_bits!(rtn.to_i & item.to_i)
  else
    rtn = Set.new(item)
    rtn.set_bits!(@bits & rtn.to_i)
  end
  rtn
end

#**(item) ⇒ Object

intersection test



122
123
124
125
126
# File 'lib/setfu.rb', line 122

def **(item)  # intersection test
  set_item = Set.new(item)
  return false if (self & set_item).empty?
  return true
end

#-(item) ⇒ Object



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/setfu.rb', line 104

def -(item)
  rtn = Set.new
  rtn.entropy = self.entropy
  a = self.to_i
  if(item.class==Set)
    b = item.to_i
    rtn.entropy = item.entropy
  else
    b = Set.new(item)
    rtn.entropy = b.entropy
    b = b.to_i
  end
  c = a & b
  d = c ^ a
  rtn.set_bits!(d)
  rtn
end

#<(item) ⇒ Object



180
181
182
183
184
# File 'lib/setfu.rb', line 180

def <(item)
  si = Set.new item
  return false if (si == self)  # not a 'proper' subset
  return si.include?(self)
end

#<=(item) ⇒ Object



175
176
177
178
# File 'lib/setfu.rb', line 175

def <=(item)
  si = Set.new item
  return si.include?(self)
end

#==(item) ⇒ Object

comparison operators:



129
130
131
132
133
134
135
136
# File 'lib/setfu.rb', line 129

def ==(item)
  if(item.class==Set)
    rtn = item.to_i == self.to_i
  else
    rtn = Set.new(item).to_i == self.to_i
  end
  rtn
end

#===(item) ⇒ Object



152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/setfu.rb', line 152

def ===(item)
  # self ... when clause  ... 
  # item ... case clause  ... case(item)
  # Note: coerce does not work in this context ...
  
  md = item.to_set.mode || @mode
  
  case md
    when :mode_intersection
      return item ** self
    when :mode_sub
      return item <= self
    when :mode_proper
      return item < self
    when :mode_super
      return self <= item
    when :mode_superproper
      return self < item
    else
      return self == item  
  end
end

#[](pos) ⇒ Object



298
299
300
301
302
303
304
305
306
# File 'lib/setfu.rb', line 298

def [](pos)
  idx = pos.ord if pos.class==String
  idx = pos.to_i 
  raise "Negative indexes are illegal for Set" if idx < 0
  self.entropy = idx+1
  y = @bits & (1<<idx)
  return true if y > 0
  false    
end

#[]=(pos, value) ⇒ Object



308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
# File 'lib/setfu.rb', line 308

def []=(pos,value)
  idx = pos.ord if pos.class==String
  idx = pos.to_i 
  raise "Negative indexes are illegal for Set" if idx < 0
  state = value ? true : false
  self.entropy = idx+1
  if state # set bit
    @bits |= 1 << idx
  else     # clear bit
    mask = 1 << idx
    @bits |= mask
    @bits ^= mask
  end
  return state
end

#^(item) ⇒ Object



70
71
72
73
74
75
76
77
78
79
# File 'lib/setfu.rb', line 70

def ^(item)
  rtn = self.dup
  if(item.class==Set)
    rtn.set_bits!(rtn.to_i ^ item.to_i)
  else
    rtn = Set.new(item)
    rtn.set_bits!(@bits ^ rtn.to_i)
  end
  rtn
end

#add!(items) ⇒ Object



186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'lib/setfu.rb', line 186

def add!(items)
  if(items.class==Set)
    @bits |= items.to_i
    entropy = items.entropy
  elsif(items.class==Range)
    f=items.first.ord
    l=items.last.ord
    f,l = l,f if f>l
    t = (l-f)+1
    t = (1 << t)-1
    @bits |= t << f
    self.entropy = l+1
  elsif(items.respond_to? :each_char)
    items.each_char do |item|
      @bits |= 1 << item.ord
      self.entropy = item.ord+1
    end
  elsif(items.respond_to? :each)
    items.each do |item|
      add! item
    end
  else #assume number
    raise "negative numbers are not allowed" if items < 0
    pos = 1 << items
    @bits |= pos
    self.entropy = items+1
  end
  self
end

#add_parse_chars!Object



53
54
55
56
# File 'lib/setfu.rb', line 53

def add_parse_chars!
  add [0..47, 58..64, 91..96, 123..126]
  self
end

#coerce(other) ⇒ Object

this only works on integer … String, Array, Range does not implement: &, |, ^



59
60
61
62
# File 'lib/setfu.rb', line 59

def coerce(other)
  #puts "TESTING ... coerce called!"
  return [self, other]   # does not seem to get called ...
end

#countObject



262
263
264
265
266
267
268
# File 'lib/setfu.rb', line 262

def count
  cnt = 0
  each_member do |toss|
    cnt += 1
  end 
  cnt    
end

#dupObject



64
65
66
67
68
# File 'lib/setfu.rb', line 64

def dup
  rtn = Set.new
  rtn.set_bits!(@bits)
  rtn
end

#each_memberObject



247
248
249
250
251
252
253
254
255
256
# File 'lib/setfu.rb', line 247

def each_member
  bits = @bits
  pos = 0
  while bits > 0
    yield pos if ((bits & 1) == 1)
    pos += 1
    bits >>= 1
  end  
  self
end

#empty?Boolean

Returns:

  • (Boolean)


216
217
218
# File 'lib/setfu.rb', line 216

def empty?
  @bits == 0
end

#include?(items) ⇒ Boolean

Returns:

  • (Boolean)


220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
# File 'lib/setfu.rb', line 220

def include?(items)
  if(items.class==Set)
    return (@bits & items.to_i) == items.to_i
  elsif(items.class==Range)
    f=items.first.ord
    l=items.last.ord
    f,l = l,f if f>l
    t = (l-f)+1
    t = (1 << t)-1
    t = t << f
    return (@bits & t) == t
  elsif(items.respond_to? :each_char)
    items.each_char do |item|
      t = 1 << item.ord
      return false if 0 == (t & @bits)
    end
  elsif(items.respond_to? :each)
    items.each do |item|
      return false if false==include?(item)
    end
  else #assume number
    t = 1 << items.abs
    return false if 0 == (t & @bits)
  end
  return true
end

#maxObject

look from left



338
339
340
341
342
343
344
345
346
347
348
349
350
351
# File 'lib/setfu.rb', line 338

def max  #look from left
  #byebug
  return nil if empty?
  range = (self.entropy)..(0)
  while((range.first - range.last) >= 2) do
    mid = ((range.first - range.last) >> 1) + range.last
    top = (range.first)..(mid)
    bot = (mid)..(range.last)
    range = self ** top ? top : bot
  end
  #byebug
  return range.first if (self[range.first])
  range.last
end

#minObject



324
325
326
327
328
329
330
331
332
333
334
335
336
# File 'lib/setfu.rb', line 324

def min
  return nil if empty?
  range = (self.entropy)..(0)
  while((range.first - range.last) >= 2) do
    mid = ((range.first - range.last) >> 1) + range.last
    top = (range.first)..(mid)
    bot = (mid)..(range.last)
    range = self ** bot ? bot : top
  end
  #byebug
  return range.last if (self[range.last])
  range.first
end

#modeObject



10
11
12
# File 'lib/setfu.rb', line 10

def mode
  return @mode
end

#recalculate_entropy!Object



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/setfu.rb', line 27

def recalculate_entropy!
  @entropy = 0
  bits = @bits
  num = 1 << 8192
  while(bits > num)
    @entropy += 8192
    bits >>= 8192
  end
  num = 1 << 256
  while(bits > num)
    @entropy += 256
    bits >>= 256
  end
  num = 1 << 16
  while(bits > num)
    @entropy += 16
    bits >>= 16
  end
  while(bits > 0)
    @entropy += 1
    bits >>= 1
  end
  #@entropy += 1
  @entropy
end

#set_bits!(bits) ⇒ Object



286
287
288
289
# File 'lib/setfu.rb', line 286

def set_bits!(bits)
  raise "negative numbers are not allowed" if bits.to_i < 0
  @bits = bits.to_i
end

#set_case(mode = :mode_equal) ⇒ Object



147
148
149
150
# File 'lib/setfu.rb', line 147

def set_case(mode=:mode_equal)
  @mode = mode
  self
end

#to_aObject



278
279
280
281
282
283
284
# File 'lib/setfu.rb', line 278

def to_a
  rtn = []
  each_member do |num|
    rtn.push num
  end
  rtn
end

#to_iObject



258
259
260
# File 'lib/setfu.rb', line 258

def to_i
  return @bits
end

#to_sObject



270
271
272
273
274
275
276
# File 'lib/setfu.rb', line 270

def to_s
  rtn = ""
  each_member do |ch|
    rtn += ch.chr
  end
  rtn
end

#zap!Object



21
22
23
24
25
# File 'lib/setfu.rb', line 21

def zap!
  @bits = 0
  @entropy = 0
  self
end

#|(item) ⇒ Object



81
82
83
84
85
86
87
88
89
90
91
# File 'lib/setfu.rb', line 81

def |(item)
  rtn = self.dup
  if(item.class==Set)
    rtn.set_bits!(rtn.to_i | item.to_i)
    self.entropy=item.entropy
  else
    rtn = Set.new(item)
    rtn.set_bits!(@bits | rtn.to_i)
  end
  rtn
end

#~@Object



291
292
293
294
295
296
# File 'lib/setfu.rb', line 291

def ~@()
  rtn = dup
  mask = (1 << @entropy) - 1
  rtn.set_bits!(mask ^ @bits)
  rtn
end