mgmg 1.4.0 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/mgmg/search.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  class String
2
- def smith_search(para, target, comp, smith_min=nil, smith_max=10000, left_associative: true, cut_exp: Float::INFINITY, min_smith: false)
2
+ def smith_search(para, target, comp, smith_min=nil, smith_max=10000, left_associative: true, cut_exp: Float::INFINITY, min_smith: false, irep: nil)
3
+ irep = ir(left_associative: left_associative) if irep.nil?
3
4
  if smith_min.nil?
4
5
  if min_smith
5
6
  smith_min = self.min_smith.min_smith
@@ -16,14 +17,14 @@ class String
16
17
  raise Mgmg::SearchCutException
17
18
  end
18
19
  end
19
- if target <= build(smith_min, comp, left_associative: left_associative).para_call(para)
20
+ if target <= irep.para_call(para, smith_min, comp)
20
21
  return smith_min
21
- elsif build(smith_max, comp, left_associative: left_associative).para_call(para) < target
22
+ elsif irep.para_call(para, smith_max, comp) < target
22
23
  raise Mgmg::SearchCutException
23
24
  end
24
25
  while 1 < smith_max - smith_min do
25
26
  smith = (smith_max - smith_min).div(2) + smith_min
26
- if build(smith, comp, left_associative: left_associative).para_call(para) < target
27
+ if irep.para_call(para, smith, comp) < target
27
28
  smith_min = smith
28
29
  else
29
30
  smith_max = smith
@@ -31,19 +32,20 @@ class String
31
32
  end
32
33
  smith_max
33
34
  end
34
- def comp_search(para, target, smith, comp_min=nil, comp_max=10000, left_associative: true)
35
+ def comp_search(para, target, smith, comp_min=nil, comp_max=10000, left_associative: true, irep: nil)
36
+ irep = ir(left_associative: left_associative) if irep.nil?
35
37
  comp_min = min_comp(left_associative: left_associative)
36
38
  if comp_max < comp_min
37
39
  raise ArgumentError, "comp_min <= comp_max is needed, (comp_min, comp_max) = (#{comp_min}, #{comp_max}) are given"
38
40
  end
39
- if target <= build(smith, comp_min, left_associative: left_associative).para_call(para)
41
+ if target <= irep.para_call(para, smith, comp_min)
40
42
  return comp_min
41
- elsif build(smith, comp_max, left_associative: left_associative).para_call(para) < target
43
+ elsif irep.para_call(para, smith, comp_max) < target
42
44
  raise Mgmg::SearchCutException
43
45
  end
44
46
  while 1 < comp_max - comp_min do
45
47
  comp = (comp_max - comp_min).div(2) + comp_min
46
- if build(smith, comp, left_associative: left_associative).para_call(para) < target
48
+ if irep.para_call(para, smith, comp) < target
47
49
  comp_min = comp
48
50
  else
49
51
  comp_max = comp
@@ -51,7 +53,8 @@ class String
51
53
  end
52
54
  comp_max
53
55
  end
54
- def search(para, target, smith_min=nil, comp_min=nil, smith_max=10000, comp_max=10000, left_associative: true, step: 1, cut_exp: Float::INFINITY, min_smith: false)
56
+ def search(para, target, smith_min=nil, comp_min=nil, smith_max=10000, comp_max=10000, left_associative: true, step: 1, cut_exp: Float::INFINITY, min_smith: false, irep: nil)
57
+ irep = ir(left_associative: left_associative) if irep.nil?
55
58
  if smith_min.nil?
56
59
  if min_smith
57
60
  smith_min = self.min_smith
@@ -60,11 +63,11 @@ class String
60
63
  end
61
64
  end
62
65
  comp_min = min_comp(left_associative: left_associative) if comp_min.nil?
63
- comp_min = comp_search(para, target, smith_max, comp_min, comp_max, left_associative: left_associative)
64
- smith_max = smith_search(para, target, comp_min, smith_min, smith_max, left_associative: left_associative)
65
- smith_min = smith_search(para, target, comp_max, smith_min, smith_max, left_associative: left_associative)
66
+ comp_min = comp_search(para, target, smith_max, comp_min, comp_max, left_associative: left_associative, irep: irep)
67
+ smith_max = smith_search(para, target, comp_min, smith_min, smith_max, left_associative: left_associative, irep: irep)
68
+ smith_min = smith_search(para, target, comp_max, smith_min, smith_max, left_associative: left_associative, irep: irep)
66
69
  raise Mgmg::SearchCutException if cut_exp < Mgmg.exp(smith_min, comp_min)
67
- comp_max = comp_search(para, target, smith_min, comp_min, comp_max, left_associative: left_associative)
70
+ comp_max = comp_search(para, target, smith_min, comp_min, comp_max, left_associative: left_associative, irep: irep)
68
71
  minex, ret = Mgmg.exp(smith_min, comp_max), [smith_min, comp_max]
69
72
  exp = Mgmg.exp(smith_max, comp_min)
70
73
  minex, ret = exp, [smith_max, comp_min] if exp < minex
@@ -75,7 +78,7 @@ class String
75
78
  if exp < minex
76
79
  minex, ret = exp, [smith, comp]
77
80
  elsif exp == minex
78
- if build(*ret).para_call(para) < build(smith, comp).para_call(para)
81
+ if irep.para_call(para, *ret) < irep.para_call(para, smith, comp)
79
82
  ret = [smith, comp]
80
83
  end
81
84
  end
@@ -86,7 +89,8 @@ class String
86
89
  end
87
90
  end
88
91
  module Enumerable
89
- def smith_search(para, target, armor, comp, smith_min=nil, smith_max=10000, left_associative: true, cut_exp: Float::INFINITY, min_smith: false)
92
+ def smith_search(para, target, armor, comp, smith_min=nil, smith_max=10000, left_associative: true, cut_exp: Float::INFINITY, min_smith: false, irep: nil)
93
+ irep = ir(left_associative: left_associative) if irep.nil?
90
94
  if smith_min.nil?
91
95
  if min_smith
92
96
  smith_min = self.min_smith[0]
@@ -103,14 +107,14 @@ module Enumerable
103
107
  raise Mgmg::SearchCutException
104
108
  end
105
109
  end
106
- if build(smith_max, armor, comp, left_associative: left_associative).para_call(para) < target
110
+ if irep.para_call(para, smith_max, armor, comp) < target
107
111
  raise Mgmg::SearchCutException
108
- elsif target <= build(smith_min, armor, comp, left_associative: left_associative).para_call(para)
112
+ elsif target <= irep.para_call(para, smith_min, armor, comp)
109
113
  return smith_min
110
114
  end
111
115
  while 1 < smith_max - smith_min do
112
116
  smith = (smith_max - smith_min).div(2) + smith_min
113
- if build(smith, armor, comp, left_associative: left_associative).para_call(para) < target
117
+ if irep.para_call(para, smith, armor, comp) < target
114
118
  smith_min = smith
115
119
  else
116
120
  smith_max = smith
@@ -118,7 +122,8 @@ module Enumerable
118
122
  end
119
123
  smith_max
120
124
  end
121
- def armor_search(para, target, smith, comp, armor_min=nil, armor_max=10000, left_associative: true, cut_exp: Float::INFINITY, min_smith: false)
125
+ def armor_search(para, target, smith, comp, armor_min=nil, armor_max=10000, left_associative: true, cut_exp: Float::INFINITY, min_smith: false, irep: nil)
126
+ irep = ir(left_associative: left_associative) if irep.nil?
122
127
  if armor_min.nil?
123
128
  if min_smith
124
129
  armor_min = self.min_smith[1]
@@ -135,14 +140,14 @@ module Enumerable
135
140
  raise Mgmg::SearchCutException
136
141
  end
137
142
  end
138
- if build(smith, armor_max, comp, left_associative: left_associative).para_call(para) < target
143
+ if irep.para_call(para, smith, armor_max, comp) < target
139
144
  raise Mgmg::SearchCutException
140
- elsif target <= build(smith, armor_min, comp, left_associative: left_associative).para_call(para)
145
+ elsif target <= irep.para_call(para, smith, armor_min, comp)
141
146
  return armor_min
142
147
  end
143
148
  while 1 < armor_max - armor_min do
144
149
  armor = (armor_max - armor_min).div(2) + armor_min
145
- if build(smith, armor, comp, left_associative: left_associative).para_call(para) < target
150
+ if irep.para_call(para, smith, armor, comp) < target
146
151
  armor_min = armor
147
152
  else
148
153
  armor_max = armor
@@ -150,7 +155,8 @@ module Enumerable
150
155
  end
151
156
  armor_max
152
157
  end
153
- def sa_search(para, target, comp, smith_min=nil, armor_min=nil, smith_max=10000, armor_max=10000, left_associative: true, cut_exp: Float::INFINITY, min_smith: false)
158
+ def sa_search(para, target, comp, smith_min=nil, armor_min=nil, smith_max=10000, armor_max=10000, left_associative: true, cut_exp: Float::INFINITY, min_smith: false, irep: nil)
159
+ irep = ir(left_associative: left_associative) if irep.nil?
154
160
  if min_smith
155
161
  s, a = self.min_smith
156
162
  else
@@ -158,23 +164,23 @@ module Enumerable
158
164
  end
159
165
  smith_min = s if smith_min.nil?
160
166
  armor_min = a if armor_min.nil?
161
- smith_min = smith_search(para, target, armor_max, comp, smith_min, smith_max, left_associative: true)
162
- armor_min = armor_search(para, target, smith_max, comp, armor_min, armor_max, left_associative: true)
167
+ smith_min = smith_search(para, target, armor_max, comp, smith_min, smith_max, left_associative: true, irep: irep)
168
+ armor_min = armor_search(para, target, smith_max, comp, armor_min, armor_max, left_associative: true, irep: irep)
163
169
  raise Mgmg::SearchCutException if cut_exp < Mgmg.exp(smith_min, armor_min, comp)
164
- smith_max = smith_search(para, target, armor_min, comp, smith_min, smith_max, left_associative: true)
165
- armor_max = armor_search(para, target, smith_min, comp, armor_min, armor_max, left_associative: true)
170
+ smith_max = smith_search(para, target, armor_min, comp, smith_min, smith_max, left_associative: true, irep: irep)
171
+ armor_max = armor_search(para, target, smith_min, comp, armor_min, armor_max, left_associative: true, irep: irep)
166
172
  minex, ret = Mgmg.exp(smith_min, armor_max, comp), [smith_min, armor_max]
167
173
  exp = Mgmg.exp(smith_max, armor_min, comp)
168
174
  if exp < minex
169
175
  minex, ret = exp, [smith_max, armor_min]
170
176
  (armor_min+1).upto(armor_max-1) do |armor|
171
177
  break if minex < Mgmg.exp(smith_min, armor, comp)
172
- smith = smith_search(para, target, armor, comp, smith_min, smith_max, left_associative: left_associative, cut_exp: [minex, cut_exp].min)
178
+ smith = smith_search(para, target, armor, comp, smith_min, smith_max, left_associative: left_associative, cut_exp: [minex, cut_exp].min, irep: irep)
173
179
  exp = Mgmg.exp(smith, armor, comp)
174
180
  if exp < minex
175
181
  minex, ret = exp, [smith, armor]
176
182
  elsif exp == minex
177
- if build(*ret, comp).para_call(para) < build(smith, armor, comp).para_call(para)
183
+ if irep.para_call(para, *ret, comp) < irep.para_call(para, smith, armor, comp)
178
184
  ret = [smith, armor]
179
185
  end
180
186
  end
@@ -183,12 +189,12 @@ module Enumerable
183
189
  else
184
190
  (smith_min+1).upto(smith_max-1) do |smith|
185
191
  break if minex < Mgmg.exp(smith, armor_min, comp)
186
- armor = armor_search(para, target, smith, comp, armor_min, armor_max, left_associative: left_associative, cut_exp: [minex, cut_exp].min)
192
+ armor = armor_search(para, target, smith, comp, armor_min, armor_max, left_associative: left_associative, cut_exp: [minex, cut_exp].min, irep: irep)
187
193
  exp = Mgmg.exp(smith, armor, comp)
188
194
  if exp < minex
189
195
  minex, ret = exp, [smith, armor]
190
196
  elsif exp == minex
191
- if build(*ret, comp).para_call(para) < build(smith, armor, comp).para_call(para)
197
+ if irep.para_call(para, *ret, comp) < irep.para_call(para, smith, armor, comp)
192
198
  ret = [smith, armor]
193
199
  end
194
200
  end
@@ -198,19 +204,20 @@ module Enumerable
198
204
  raise Mgmg::SearchCutException if cut_exp < minex
199
205
  ret
200
206
  end
201
- def comp_search(para, target, smith, armor, comp_min=nil, comp_max=10000, left_associative: true)
207
+ def comp_search(para, target, smith, armor, comp_min=nil, comp_max=10000, left_associative: true, irep: nil)
208
+ irep = ir(left_associative: left_associative) if irep.nil?
202
209
  comp_min = min_comp(left_associative: left_associative)
203
210
  if comp_max < comp_min
204
211
  raise ArgumentError, "comp_min <= comp_max is needed, (comp_min, comp_max) = (#{comp_min}, #{comp_max}) are given"
205
212
  end
206
- if target <= build(smith, armor, comp_min, left_associative: left_associative).para_call(para)
213
+ if target <= irep.para_call(para, smith, armor, comp_min)
207
214
  return comp_min
208
- elsif build(smith, armor, comp_max, left_associative: left_associative).para_call(para) < target
215
+ elsif irep.para_call(para, smith, armor, comp_max) < target
209
216
  raise ArgumentError, "given comp_max=#{comp_max} does not satisfies the target"
210
217
  end
211
218
  while 1 < comp_max - comp_min do
212
219
  comp = (comp_max - comp_min).div(2) + comp_min
213
- if build(smith, armor, comp, left_associative: left_associative).para_call(para) < target
220
+ if irep.para_call(para, smith, armor, comp) < target
214
221
  comp_min = comp
215
222
  else
216
223
  comp_max = comp
@@ -218,7 +225,8 @@ module Enumerable
218
225
  end
219
226
  comp_max
220
227
  end
221
- def search(para, target, smith_min=nil, armor_min=nil, comp_min=nil, smith_max=10000, armor_max=10000, comp_max=10000, left_associative: true, cut_exp: Float::INFINITY, min_smith: false)
228
+ def search(para, target, smith_min=nil, armor_min=nil, comp_min=nil, smith_max=10000, armor_max=10000, comp_max=10000, left_associative: true, cut_exp: Float::INFINITY, min_smith: false, irep: nil)
229
+ irep = ir(left_associative: left_associative) if irep.nil?
222
230
  if min_smith
223
231
  s, a = self.min_smith
224
232
  else
@@ -227,22 +235,22 @@ module Enumerable
227
235
  smith_min = s if smith_min.nil?
228
236
  armor_min = a if armor_min.nil?
229
237
  comp_min = min_comp(left_associative: left_associative) if comp_min.nil?
230
- comp_min = comp_search(para, target, smith_max, armor_max, comp_min, comp_max, left_associative: left_associative)
231
- smith_max, armor_max = sa_search(para, target, comp_min, smith_min, armor_min, smith_max, armor_max, left_associative: left_associative)
232
- smith_min, armor_min = sa_search(para, target, comp_max, smith_min, armor_min, smith_max, armor_max, left_associative: left_associative)
238
+ comp_min = comp_search(para, target, smith_max, armor_max, comp_min, comp_max, left_associative: left_associative, irep: irep)
239
+ smith_max, armor_max = sa_search(para, target, comp_min, smith_min, armor_min, smith_max, armor_max, left_associative: left_associative, irep: irep)
240
+ smith_min, armor_min = sa_search(para, target, comp_max, smith_min, armor_min, smith_max, armor_max, left_associative: left_associative, irep: irep)
233
241
  raise Mgmg::SearchCutException if cut_exp < Mgmg.exp(smith_min, armor_min, comp_min)
234
- comp_max = comp_search(para, target, smith_min, armor_min, comp_min, comp_max, left_associative: left_associative)
242
+ comp_max = comp_search(para, target, smith_min, armor_min, comp_min, comp_max, left_associative: left_associative, irep: irep)
235
243
  minex, ret = Mgmg.exp(smith_min, armor_min, comp_max), [smith_min, armor_min, comp_max]
236
244
  exp = Mgmg.exp(smith_max, armor_max, comp_min)
237
245
  minex, ret = exp, [smith_max, armor_max, comp_min] if exp < minex
238
246
  (comp_min+1).upto(comp_max-1) do |comp|
239
247
  break if minex < Mgmg.exp(smith_min, armor_min, comp)
240
- smith, armor = sa_search(para, target, comp, smith_min, armor_min, smith_max, armor_max, left_associative: left_associative, cut_exp: [minex, cut_exp].min)
248
+ smith, armor = sa_search(para, target, comp, smith_min, armor_min, smith_max, armor_max, left_associative: left_associative, cut_exp: [minex, cut_exp].min, irep: irep)
241
249
  exp = Mgmg.exp(smith, armor, comp)
242
250
  if exp < minex
243
251
  minex, ret = exp, [smith, armor, comp]
244
252
  elsif exp == minex
245
- if build(*ret).para_call(para) < build(smith, armor, comp).para_call(para)
253
+ if irep.para_call(para, *ret) < irep.para_call(para, smith, armor, comp)
246
254
  ret = [smith, armor, comp]
247
255
  end
248
256
  end
@@ -252,3 +260,106 @@ module Enumerable
252
260
  ret
253
261
  end
254
262
  end
263
+
264
+ module Mgmg
265
+ module_function def find_lowerbound(a, b, para, start, term, smith_min_a: nil, smith_min_b: nil, armor_min_a: nil, armor_min_b: nil, min_smith: false)
266
+ if term <= start
267
+ raise ArgumentError, "start < term is needed, (start, term) = (#{start}, #{term}) are given"
268
+ end
269
+ ira, irb = a.ir, b.ir
270
+ sca, scb = a.search(para, start, smith_min_a, armor_min_a, min_smith: min_smith, irep: ira), b.search(para, start, smith_min_b, armor_min_b, min_smith: min_smith, irep: irb)
271
+ ea, eb = Mgmg.exp(*sca), Mgmg.exp(*scb)
272
+ if eb < ea || ( ea == eb && ira.para_call(para, *sca) < irb.para_call(para, *scb) )
273
+ a, b, ira, irb, sca, scb, ea, eb = b, a, irb, ira, scb, sca, eb, ea
274
+ smith_min_a, smith_min_b, armor_min_a, armor_min_b = smith_min_b, smith_min_a, armor_min_b, armor_min_a
275
+ end
276
+ tag = ira.para_call(para, *sca) + 1
277
+ sca, scb = a.search(para, term, smith_min_a, armor_min_a, min_smith: min_smith, irep: ira), b.search(para, term, smith_min_b, armor_min_b, min_smith: min_smith, irep: irb)
278
+ ea, eb = Mgmg.exp(*sca), Mgmg.exp(*scb)
279
+ if ea < eb || ( ea == eb && irb.para_call(para, *scb) < ira.para_call(para, *sca) )
280
+ raise Mgmg::SearchCutException
281
+ end
282
+ while tag < term
283
+ sca, scb = a.search(para, tag, smith_min_a, armor_min_a, min_smith: min_smith, irep: ira), b.search(para, tag, smith_min_b, armor_min_b, min_smith: min_smith, irep: irb)
284
+ ea, eb = Mgmg.exp(*sca), Mgmg.exp(*scb)
285
+ pa, pb = ira.para_call(para, *sca), irb.para_call(para, *scb)
286
+ if eb < ea
287
+ return [tag-1, pb]
288
+ elsif ea == eb
289
+ if pa < pb
290
+ return [tag-1, pa]
291
+ else
292
+ tag = pb + 1
293
+ end
294
+ else
295
+ tag = pa + 1
296
+ end
297
+ end
298
+ raise UnexpectedError
299
+ end
300
+
301
+ module_function def find_upperbound(a, b, para, start, term, smith_min_a: nil, smith_min_b: nil, armor_min_a: nil, armor_min_b: nil, min_smith: false)
302
+ if start <= term
303
+ raise ArgumentError, "term < start is needed, (start, term) = (#{start}, #{term}) are given"
304
+ end
305
+ ira, irb = a.ir, b.ir
306
+ sca, scb = a.search(para, start, smith_min_a, armor_min_a, min_smith: min_smith, irep: ira), b.search(para, start, smith_min_b, armor_min_b, min_smith: min_smith, irep: irb)
307
+ ea, eb = Mgmg.exp(*sca), Mgmg.exp(*scb)
308
+ if ea < eb || ( ea == eb && irb.para_call(para, *scb) < ira.para_call(para, *sca) )
309
+ a, b, ira, irb, sca, scb, ea, eb = b, a, irb, ira, scb, sca, eb, ea
310
+ smith_min_a, smith_min_b, armor_min_a, armor_min_b = smith_min_b, smith_min_a, armor_min_b, armor_min_a
311
+ end
312
+ tagu = ira.para_call(para, *sca)
313
+ sca[-1] -= 2
314
+ tagl = ira.para_call(para, *sca)
315
+ sca, scb = a.search(para, term, smith_min_a, armor_min_a, min_smith: min_smith, irep: ira), b.search(para, term, smith_min_b, armor_min_b, min_smith: min_smith, irep: irb)
316
+ ea, eb = Mgmg.exp(*sca), Mgmg.exp(*scb)
317
+ if eb < ea || ( ea == eb && ira.para_call(para, *sca) < irb.para_call(para, *scb) )
318
+ raise Mgmg::SearchCutException
319
+ end
320
+ while term < tagu
321
+ ret = nil
322
+ sca = a.search(para, tagl, smith_min_a, armor_min_a, min_smith: min_smith, irep: ira)
323
+ next_tagu, next_sca = tagl, sca
324
+ scb = b.search(para, tagl, smith_min_b, armor_min_b, min_smith: min_smith, irep: irb)
325
+ while tagl < tagu
326
+ ea, eb = Mgmg.exp(*sca), Mgmg.exp(*scb)
327
+ pa, pb = ira.para_call(para, *sca), irb.para_call(para, *scb)
328
+ if ea < eb
329
+ ret = tagl
330
+ sca = a.search(para, pa + 1, smith_min_a, armor_min_a, min_smith: min_smith, irep: ira)
331
+ tagl = ira.para_call(para, *sca)
332
+ scb = b.search(para, tagl, smith_min_b, armor_min_b, min_smith: min_smith, irep: irb)
333
+ elsif ea == eb
334
+ if pb < pa
335
+ ret = tagl
336
+ sca = a.search(para, pa + 1, smith_min_a, armor_min_a, min_smith: min_smith, irep: ira)
337
+ tagl = ira.para_call(para, *sca)
338
+ scb = b.search(para, tagl, smith_min_b, armor_min_b, min_smith: min_smith, irep: irb)
339
+ else
340
+ scb = b.search(para, pb + 1, smith_min_b, armor_min_b, min_smith: min_smith, irep: irb)
341
+ tagl = irb.para_call(para, *scb)
342
+ sca = a.search(para, tagl, smith_min_a, armor_min_a, min_smith: min_smith, irep: ira)
343
+ end
344
+ else
345
+ sca = a.search(para, pa + 1, smith_min_a, armor_min_a, min_smith: min_smith, irep: ira)
346
+ tagl = ira.para_call(para, *sca)
347
+ scb = b.search(para, tagl, smith_min_b, armor_min_b, min_smith: min_smith, irep: irb)
348
+ end
349
+ end
350
+ if ret.nil?
351
+ tagu = next_tagu
352
+ next_sca[-1] -= 2
353
+ tagl = ira.para_call(para, *next_sca)
354
+ if tagl == tagu
355
+ tagl = term
356
+ end
357
+ else
358
+ pa = ira.para_call(para, *a.search(para, ret+1, smith_min_a, armor_min_a, min_smith: min_smith, irep: ira))
359
+ pb = irb.para_call(para, *b.search(para, ret+1, smith_min_b, armor_min_b, min_smith: min_smith, irep: irb))
360
+ return [ret, [pa, pb].min]
361
+ end
362
+ end
363
+ raise UnexpectedError
364
+ end
365
+ end
data/lib/mgmg/utils.rb CHANGED
@@ -47,6 +47,11 @@ module Mgmg
47
47
  attr_accessor :equip
48
48
  end
49
49
  class SearchCutException < StandardError; end
50
+ class UnexpectedError < StandardError
51
+ def initialize()
52
+ super("There is a bug in `mgmg' gem. Please report to https://github.com/cycloawaodorin/mgmg/issues .")
53
+ end
54
+ end
50
55
 
51
56
  module_function def exp(smith, armor, comp=armor.tap{armor=0})
52
57
  if armor <= 0
@@ -129,6 +134,15 @@ module Mgmg
129
134
  end
130
135
  str
131
136
  end
137
+
138
+ module_function def parse_material(str)
139
+ m = /\A.+?(\d+)\Z/.match(str)
140
+ mat = MaterialIndex[str.to_sym]
141
+ if m.nil? || mat.nil?
142
+ raise InvalidMaterialError.new(str)
143
+ end
144
+ [mat, m[1].to_i, mat<90 ? mat.div(10) : 9]
145
+ end
132
146
 
133
147
  class Vec < Array
134
148
  def add!(other)
data/lib/mgmg/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Mgmg
2
- VERSION = "1.4.0"
2
+ VERSION = "1.4.1"
3
3
  end
data/lib/mgmg.rb CHANGED
@@ -3,6 +3,7 @@ require_relative './mgmg/utils'
3
3
  require_relative './mgmg/const'
4
4
  require_relative './mgmg/equip'
5
5
  require_relative './mgmg/poly'
6
+ require_relative './mgmg/ir'
6
7
  require_relative './mgmg/system_equip'
7
8
  require_relative './mgmg/search'
8
9
  require_relative './mgmg/optimize'
@@ -11,8 +12,8 @@ class String
11
12
  def min_level(w=1)
12
13
  Mgmg::Equip.min_level(self, w)
13
14
  end
14
- def min_levels(left_associative: true)
15
- build(-1, -1, left_associative: left_associative).min_levels
15
+ def min_levels(w=1, left_associative: true)
16
+ build(-1, -1, left_associative: left_associative).min_levels(w)
16
17
  end
17
18
  def min_smith(left_associative: true)
18
19
  Mgmg::Equip.min_smith(self, left_associative: left_associative)
@@ -23,6 +24,9 @@ class String
23
24
  def build(smith=-1, comp=smith, left_associative: true)
24
25
  Mgmg::Equip.build(self, smith, comp, left_associative: left_associative)
25
26
  end
27
+ def ir(left_associative: true)
28
+ Mgmg::IR.build(self, left_associative: left_associative)
29
+ end
26
30
  def poly(para=:cost, left_associative: true)
27
31
  la = left_associative
28
32
  case para
@@ -93,6 +97,11 @@ module Enumerable
93
97
  end
94
98
  end.sum
95
99
  end
100
+ def ir(left_associative: true)
101
+ self.map do |str|
102
+ str.ir(left_associative: left_associative)
103
+ end.sum
104
+ end
96
105
  def show(smith=-1, armor=smith, comp=armor.tap{armor=smith}, left_associative: true, para: :power)
97
106
  built = self.build(smith, armor, comp, left_associative: left_associative)
98
107
  pstr = '%.3f' % built.para_call(para)
@@ -102,12 +111,12 @@ module Enumerable
102
111
  puts "with levels (#{smith}, #{armor}, #{comp}) yields (#{pstr}, #{built.total_cost})"
103
112
  puts " #{built}"
104
113
  end
105
- def min_levels(left_associative: true)
106
- build(-1, -1, -1, left_associative: left_associative).min_levels
114
+ def min_levels(w=1, left_associative: true)
115
+ build(-1, -1, -1, left_associative: left_associative).min_levels(w)
107
116
  end
108
- def min_level(left_associative: true)
117
+ def min_level(w=1, left_associative: true)
109
118
  ret = [0, 0]
110
- build(-1, -1, -1, left_associative: left_associative).min_levels.each do |str, level|
119
+ build(-1, -1, -1, left_associative: left_associative).min_levels(w).each do |str, level|
111
120
  m = /\A\[*([^\+]+)/.match(str)
112
121
  if Mgmg::EquipPosition[m[1].build(0).kind] == 0
113
122
  ret[0] = [ret[0], level].max