mgmg 1.3.2 → 1.4.2
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +21 -0
- data/README.md +42 -244
- data/lib/mgmg/const.rb +2 -1
- data/lib/mgmg/cuisine.rb +140 -0
- data/lib/mgmg/equip.rb +45 -46
- data/lib/mgmg/ir.rb +407 -0
- data/lib/mgmg/poly.rb +11 -2
- data/lib/mgmg/reinforce.rb +70 -0
- data/lib/mgmg/search.rb +154 -43
- data/lib/mgmg/utils.rb +39 -0
- data/lib/mgmg/version.rb +1 -1
- data/lib/mgmg.rb +54 -16
- data/reference.md +374 -0
- metadata +7 -3
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, reinforcement: [])
|
3
|
+
irep = ir(left_associative: left_associative, reinforcement: reinforcement) 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 <=
|
20
|
+
if target <= irep.para_call(para, smith_min, comp)
|
20
21
|
return smith_min
|
21
|
-
elsif
|
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
|
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, reinforcement: [])
|
36
|
+
irep = ir(left_associative: left_associative, reinforcement: reinforcement) 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 <=
|
41
|
+
if target <= irep.para_call(para, smith, comp_min)
|
40
42
|
return comp_min
|
41
|
-
elsif
|
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
|
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, reinforcement: [])
|
57
|
+
irep = ir(left_associative: left_associative, reinforcement: reinforcement) if irep.nil?
|
55
58
|
if smith_min.nil?
|
56
59
|
if min_smith
|
57
60
|
smith_min = self.min_smith
|
@@ -60,22 +63,22 @@ 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
|
71
74
|
(comp_min+step).step(comp_max-1, step) do |comp|
|
72
75
|
break if minex < Mgmg.exp(smith_min, comp)
|
73
|
-
smith = smith_search(para, target, comp, smith_min, smith_max, left_associative: left_associative, cut_exp: [minex, cut_exp].min)
|
76
|
+
smith = smith_search(para, target, comp, smith_min, smith_max, left_associative: left_associative, cut_exp: [minex, cut_exp].min, irep: irep)
|
74
77
|
exp = Mgmg.exp(smith, comp)
|
75
78
|
if exp < minex
|
76
79
|
minex, ret = exp, [smith, comp]
|
77
80
|
elsif exp == minex
|
78
|
-
if
|
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, reinforcement: [])
|
93
|
+
irep = ir(left_associative: left_associative, reinforcement: reinforcement) 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
|
110
|
+
if irep.para_call(para, smith_max, armor, comp) < target
|
107
111
|
raise Mgmg::SearchCutException
|
108
|
-
elsif target <=
|
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
|
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, reinforcement: [])
|
126
|
+
irep = ir(left_associative: left_associative, reinforcement: reinforcement) 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
|
143
|
+
if irep.para_call(para, smith, armor_max, comp) < target
|
139
144
|
raise Mgmg::SearchCutException
|
140
|
-
elsif target <=
|
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
|
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, reinforcement: [])
|
159
|
+
irep = ir(left_associative: left_associative, reinforcement: reinforcement) 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
|
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
|
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, reinforcement: [])
|
208
|
+
irep = ir(left_associative: left_associative, reinforcement: reinforcement) 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 <=
|
213
|
+
if target <= irep.para_call(para, smith, armor, comp_min)
|
207
214
|
return comp_min
|
208
|
-
elsif
|
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
|
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, reinforcement: [])
|
229
|
+
irep = ir(left_associative: left_associative, reinforcement: reinforcement) 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
|
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, reinforcement: [])
|
266
|
+
if term <= start
|
267
|
+
raise ArgumentError, "start < term is needed, (start, term) = (#{start}, #{term}) are given"
|
268
|
+
end
|
269
|
+
ira, irb = a.ir(reinforcement: reinforcement), b.ir(reinforcement: reinforcement)
|
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, reinforcement: [])
|
302
|
+
if start <= term
|
303
|
+
raise ArgumentError, "term < start is needed, (start, term) = (#{start}, #{term}) are given"
|
304
|
+
end
|
305
|
+
ira, irb = a.ir(reinforcement: reinforcement), b.ir(reinforcement: reinforcement)
|
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
@@ -14,6 +14,31 @@ module Mgmg
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
end
|
17
|
+
refine Float do
|
18
|
+
alias :cdiv :quo # Floatの場合は普通の割り算
|
19
|
+
def comma3
|
20
|
+
s = self.to_s
|
21
|
+
case s
|
22
|
+
when %r|e|
|
23
|
+
s
|
24
|
+
when %r|\.|
|
25
|
+
ary = s.split('.')
|
26
|
+
ary[0].gsub(/(\d)(?=(\d{3})+(?!\d))/, '\1,') + '.' + ary[1]
|
27
|
+
else
|
28
|
+
s
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
refine Rational do
|
33
|
+
alias :cdiv :quo # Rationalの場合は普通の割り算
|
34
|
+
def comma3
|
35
|
+
if self.denominator == 1
|
36
|
+
self.numerator.comma3
|
37
|
+
else
|
38
|
+
self.to_f.comma3
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
17
42
|
end
|
18
43
|
using Refiner
|
19
44
|
|
@@ -47,6 +72,11 @@ module Mgmg
|
|
47
72
|
attr_accessor :equip
|
48
73
|
end
|
49
74
|
class SearchCutException < StandardError; end
|
75
|
+
class UnexpectedError < StandardError
|
76
|
+
def initialize()
|
77
|
+
super("There is a bug in `mgmg' gem. Please report to https://github.com/cycloawaodorin/mgmg/issues .")
|
78
|
+
end
|
79
|
+
end
|
50
80
|
|
51
81
|
module_function def exp(smith, armor, comp=armor.tap{armor=0})
|
52
82
|
if armor <= 0
|
@@ -129,6 +159,15 @@ module Mgmg
|
|
129
159
|
end
|
130
160
|
str
|
131
161
|
end
|
162
|
+
|
163
|
+
module_function def parse_material(str)
|
164
|
+
m = /\A.+?(\d+)\Z/.match(str)
|
165
|
+
mat = MaterialIndex[str.to_sym]
|
166
|
+
if m.nil? || mat.nil?
|
167
|
+
raise InvalidMaterialError.new(str)
|
168
|
+
end
|
169
|
+
[mat, m[1].to_i, mat<90 ? mat.div(10) : 9]
|
170
|
+
end
|
132
171
|
|
133
172
|
class Vec < Array
|
134
173
|
def add!(other)
|
data/lib/mgmg/version.rb
CHANGED
data/lib/mgmg.rb
CHANGED
@@ -3,7 +3,10 @@ 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'
|
8
|
+
require_relative './mgmg/cuisine'
|
9
|
+
require_relative './mgmg/reinforce'
|
7
10
|
require_relative './mgmg/search'
|
8
11
|
require_relative './mgmg/optimize'
|
9
12
|
|
@@ -11,8 +14,8 @@ class String
|
|
11
14
|
def min_level(w=1)
|
12
15
|
Mgmg::Equip.min_level(self, w)
|
13
16
|
end
|
14
|
-
def min_levels(left_associative: true)
|
15
|
-
build(-1, -1, left_associative: left_associative).min_levels
|
17
|
+
def min_levels(w=1, left_associative: true)
|
18
|
+
build(-1, -1, left_associative: left_associative).min_levels(w)
|
16
19
|
end
|
17
20
|
def min_smith(left_associative: true)
|
18
21
|
Mgmg::Equip.min_smith(self, left_associative: left_associative)
|
@@ -23,19 +26,26 @@ class String
|
|
23
26
|
def build(smith=-1, comp=smith, left_associative: true)
|
24
27
|
Mgmg::Equip.build(self, smith, comp, left_associative: left_associative)
|
25
28
|
end
|
29
|
+
def ir(left_associative: true, reinforcement: [])
|
30
|
+
Mgmg::IR.build(self, left_associative: left_associative, reinforcement: reinforcement)
|
31
|
+
end
|
26
32
|
def poly(para=:cost, left_associative: true)
|
27
33
|
la = left_associative
|
28
34
|
case para
|
29
35
|
when :atkstr
|
30
36
|
self.poly(:attack, left_associative: la) + self.poly(:str, left_associative: la)
|
31
37
|
when :atk_sd
|
32
|
-
self.poly(:attack) + self.poly(:str, left_associative: la).quo(2) + self.poly(:dex, left_associative: la).quo(2)
|
38
|
+
self.poly(:attack, left_associative: la) + self.poly(:str, left_associative: la).quo(2) + self.poly(:dex, left_associative: la).quo(2)
|
33
39
|
when :dex_as
|
34
|
-
self.poly(:dex) + self.poly(:attack, left_associative: la).quo(2) + self.poly(:str, left_associative: la).quo(2)
|
40
|
+
self.poly(:dex, left_associative: la) + self.poly(:attack, left_associative: la).quo(2) + self.poly(:str, left_associative: la).quo(2)
|
35
41
|
when :mag_das
|
36
|
-
self.poly(:magic) + self.poly(:dex_as, left_associative: la).quo(2)
|
42
|
+
self.poly(:magic, left_associative: la) + self.poly(:dex_as, left_associative: la).quo(2)
|
37
43
|
when :magmag
|
38
|
-
self.poly(:magdef) + self.poly(:magic, left_associative: la).quo(2)
|
44
|
+
self.poly(:magdef, left_associative: la) + self.poly(:magic, left_associative: la).quo(2)
|
45
|
+
when :pmdef
|
46
|
+
pd = self.poly(:phydef, left_associative: la)
|
47
|
+
md = self.poly(:magmag, left_associative: la)
|
48
|
+
pd <= md ? pd : md
|
39
49
|
when :cost
|
40
50
|
if Mgmg::SystemEquip.keys.include?(self)
|
41
51
|
return Mgmg::TPolynomial.new(Mgmg::Mat.new(1, 1, 0.quo(1)), 28, 0, 12, 12)
|
@@ -62,13 +72,20 @@ class String
|
|
62
72
|
def peff(para, smith, comp=smith, left_associative: true)
|
63
73
|
poly(para, left_associative: left_associative).eff(smith, comp)
|
64
74
|
end
|
65
|
-
def show(smith=-1, comp=smith, left_associative: true)
|
66
|
-
|
67
|
-
|
75
|
+
def show(smith=-1, comp=smith, left_associative: true, para: :power, reinforcement: [])
|
76
|
+
rein = case reinforcement
|
77
|
+
when Array
|
78
|
+
reinforcement.map{|r| Mgmg::Reinforcement.compile(r)}
|
79
|
+
else
|
80
|
+
[Mgmg::Reinforcement.compile(reinforcement)]
|
81
|
+
end
|
82
|
+
built = self.build(smith, comp, left_associative: left_associative).reinforce(*rein)
|
83
|
+
pstr = '%.3f' % built.para_call(para)
|
68
84
|
pstr.sub!(/\.?0+\Z/, '')
|
69
85
|
puts "Building"
|
70
86
|
puts " #{self}"
|
71
|
-
|
87
|
+
rein = rein.empty? ? '' : " reinforced by {#{rein.join(',')}}"
|
88
|
+
puts "with levels (#{smith}, #{comp})#{rein} yields (#{pstr}, #{built.total_cost})"
|
72
89
|
puts " #{built}"
|
73
90
|
end
|
74
91
|
def phydef_optimize(smith=nil, comp=smith, left_associative: true, magdef_maximize: true)
|
@@ -80,21 +97,42 @@ class String
|
|
80
97
|
end
|
81
98
|
module Enumerable
|
82
99
|
def build(smith=-1, armor=smith, comp=armor.tap{armor=smith}, left_associative: true)
|
83
|
-
self.
|
100
|
+
self.sum do |str|
|
84
101
|
m = /\A\[*([^\+]+)/.match(str)
|
85
102
|
if Mgmg::EquipPosition[m[1].build(0).kind] == 0
|
86
103
|
str.build(smith, comp, left_associative: left_associative)
|
87
104
|
else
|
88
105
|
str.build(armor, comp, left_associative: left_associative)
|
89
106
|
end
|
90
|
-
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
def ir(left_associative: true, reinforcement: [])
|
110
|
+
self.sum do |str|
|
111
|
+
str.ir(left_associative: left_associative)
|
112
|
+
end.add_reinforcement(reinforcement)
|
113
|
+
end
|
114
|
+
def show(smith=-1, armor=smith, comp=armor.tap{armor=smith}, left_associative: true, para: :power, reinforcement: [])
|
115
|
+
rein = case reinforcement
|
116
|
+
when Array
|
117
|
+
reinforcement.map{|r| Mgmg::Reinforcement.compile(r)}
|
118
|
+
else
|
119
|
+
[Mgmg::Reinforcement.compile(reinforcement)]
|
120
|
+
end
|
121
|
+
built = self.build(smith, armor, comp, left_associative: left_associative).reinforce(*rein)
|
122
|
+
pstr = '%.3f' % built.para_call(para)
|
123
|
+
pstr.sub!(/\.?0+\Z/, '')
|
124
|
+
puts "Building"
|
125
|
+
puts " #{self.join(', ')}"
|
126
|
+
rein = rein.empty? ? '' : " reinforced by {#{rein.join(',')}}"
|
127
|
+
puts "with levels (#{smith}, #{armor}, #{comp})#{rein} yields (#{pstr}, #{built.total_cost})"
|
128
|
+
puts " #{built}"
|
91
129
|
end
|
92
|
-
def min_levels(left_associative: true)
|
93
|
-
build(-1, -1, -1, left_associative: left_associative).min_levels
|
130
|
+
def min_levels(w=1, left_associative: true)
|
131
|
+
build(-1, -1, -1, left_associative: left_associative).min_levels(w)
|
94
132
|
end
|
95
|
-
def min_level(left_associative: true)
|
133
|
+
def min_level(w=1, left_associative: true)
|
96
134
|
ret = [0, 0]
|
97
|
-
build(-1, -1, -1, left_associative: left_associative).min_levels.each do |str, level|
|
135
|
+
build(-1, -1, -1, left_associative: left_associative).min_levels(w).each do |str, level|
|
98
136
|
m = /\A\[*([^\+]+)/.match(str)
|
99
137
|
if Mgmg::EquipPosition[m[1].build(0).kind] == 0
|
100
138
|
ret[0] = [ret[0], level].max
|