1 /*
2  *  cTaskLib.cc
3  *  Avida
4  *
5  *  Called "task_lib.cc" prior to 12/5/05.
6  *  Copyright 1999-2011 Michigan State University. All rights reserved.
7  *  Copyright 1993-2003 California Institute of Technology.
8  *
9  *
10  *  This file is part of Avida.
11  *
12  *  Avida is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License
13  *  as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
14  *
15  *  Avida is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
17  *
18  *  You should have received a copy of the GNU Lesser General Public License along with Avida.
19  *  If not, see <http://www.gnu.org/licenses/>.
20  *
21  */
22 
23 #include "cTaskLib.h"
24 
25 #include "apto/platform.h"
26 
27 #include "cArgSchema.h"
28 #include "cDeme.h"
29 #include "cEnvironment.h"
30 #include "cEnvReqs.h"
31 #include "cTaskState.h"
32 #include "cPopulation.h"
33 #include "cPopulationCell.h"
34 #include "cOrgMessagePredicate.h"
35 #include "cOrgMovementPredicate.h"
36 #include "cStateGrid.h"
37 #include "cUserFeedback.h"
38 #include "tArrayUtils.h"
39 #include "tHashMap.h"
40 
41 #include <cstdlib>
42 #include <cmath>
43 #include <climits>
44 #include <iomanip>
45 
46 // Various workarounds for Visual Studio shortcomings
47 #if APTO_PLATFORM_WINDOWS
48 # define llabs(x) _abs64(x)
49 # define log2(x) (log(x)/log(2.0))
50 #endif
51 
52 // Various workarounds for FreeBSD
53 #if APTO_PLATFORM(FREEBSD)
54 # define log2(x) (log(x)/log(2.0))
55 #endif
56 
57 static const double dCastPrecision = 100000.0;
58 
59 
~cTaskLib()60 cTaskLib::~cTaskLib()
61 {
62   for (int i = 0; i < task_array.GetSize(); i++) delete task_array[i];
63 }
64 
FractionalReward(unsigned int supplied,unsigned int correct)65 inline double cTaskLib::FractionalReward(unsigned int supplied, unsigned int correct)
66 {
67   const unsigned int variance = supplied ^ correct;
68   const unsigned int w = variance - ((variance >> 1) & 0x55555555);
69   const unsigned int x = (w & 0x33333333) + ((w >> 2) & 0x33333333);
70   const unsigned int bit_diff = ((x + (x >> 4) & 0xF0F0F0F) * 0x1010101) >> 24;
71   return static_cast<double>(32 - bit_diff) / 32.0;
72 }
73 
AddTask(const cString & name,const cString & info,cEnvReqs & envreqs,Feedback & feedback)74 cTaskEntry* cTaskLib::AddTask(const cString& name, const cString& info, cEnvReqs& envreqs, Feedback& feedback)
75 {
76   // Determine if this task is already in the active library.
77   for (int i = 0; i < task_array.GetSize(); i++) {
78     assert(task_array[i] != NULL);
79     if (task_array[i]->GetName() == name && !task_array[i]->HasArguments()) return task_array[i];
80   }
81 
82   // Match up this name to its corresponding task
83   const int start_size = task_array.GetSize();
84 
85   // The following if blocks are grouped based on class of task.  Chaining too
86   // many if block causes problems block nesting depth in Visual Studio.net 2003.
87 
88   if (name == "echo")      NewTask(name, "Echo", &cTaskLib::Task_Echo);
89   else if (name == "echo_dup")  NewTask(name, "Echo_dup",  &cTaskLib::Task_Echo);
90   else if (name == "add")  NewTask(name, "Add",  &cTaskLib::Task_Add);
91   else if (name == "add3")  NewTask(name, "Add3",  &cTaskLib::Task_Add3);
92   else if (name == "sub")  NewTask(name, "Sub",  &cTaskLib::Task_Sub);
93   // @WRE DontCare task always succeeds.
94   else if (name == "dontcare")  NewTask(name, "DontCare", &cTaskLib::Task_DontCare);
95 
96   // All 1- and 2-Input Logic Functions
97   if (name == "not") NewTask(name, "Not", &cTaskLib::Task_Not);
98   else if (name == "not_dup") NewTask(name, "Not_dup", &cTaskLib::Task_Not);
99   else if (name == "nand") NewTask(name, "Nand", &cTaskLib::Task_Nand);
100   else if (name == "nand_dup") NewTask(name, "Nand_dup", &cTaskLib::Task_Nand);
101   else if (name == "and") NewTask(name, "And", &cTaskLib::Task_And);
102   else if (name == "and_dup") NewTask(name, "And_dup", &cTaskLib::Task_And);
103   else if (name == "orn") NewTask(name, "OrNot", &cTaskLib::Task_OrNot);
104   else if (name == "orn_dup") NewTask(name, "OrNot_dup", &cTaskLib::Task_OrNot);
105   else if (name == "or") NewTask(name, "Or", &cTaskLib::Task_Or);
106   else if (name == "or_dup") NewTask(name, "Or_dup", &cTaskLib::Task_Or);
107   else if (name == "andn") NewTask(name, "AndNot", &cTaskLib::Task_AndNot);
108   else if (name == "andn_dup") NewTask(name, "AndNot_dup", &cTaskLib::Task_AndNot);
109   else if (name == "nor") NewTask(name, "Nor", &cTaskLib::Task_Nor);
110   else if (name == "nor_dup") NewTask(name, "Nor_dup", &cTaskLib::Task_Nor);
111   else if (name == "xor") NewTask(name, "Xor", &cTaskLib::Task_Xor);
112   else if (name == "xor_dup") NewTask(name, "Xor_dup", &cTaskLib::Task_Xor);
113   else if (name == "equ") NewTask(name, "Equals", &cTaskLib::Task_Equ);
114   else if (name == "equ_dup") NewTask(name, "Equals_dup", &cTaskLib::Task_Equ);
115 
116 	// resoruce dependent version
117   else if (name == "nand-resourceDependent") NewTask(name, "Nand-resourceDependent", &cTaskLib::Task_Nand_ResourceDependent);
118   else if (name == "nor-resourceDependent") NewTask(name, "Nor-resourceDependent", &cTaskLib::Task_Nor_ResourceDependent);
119 
120   // All 3-Input Logic Functions
121   if (name == "logic_3AA")      NewTask(name, "Logic 3AA (A+B+C == 0)", &cTaskLib::Task_Logic3in_AA);
122   else if (name == "logic_3AB") NewTask(name, "Logic 3AB (A+B+C == 1)", &cTaskLib::Task_Logic3in_AB);
123   else if (name == "logic_3AC") NewTask(name, "Logic 3AC (A+B+C <= 1)", &cTaskLib::Task_Logic3in_AC);
124   else if (name == "logic_3AD") NewTask(name, "Logic 3AD (A+B+C == 2)", &cTaskLib::Task_Logic3in_AD);
125   else if (name == "logic_3AE") NewTask(name, "Logic 3AE (A+B+C == 0,2)", &cTaskLib::Task_Logic3in_AE);
126   else if (name == "logic_3AF") NewTask(name, "Logic 3AF (A+B+C == 1,2)", &cTaskLib::Task_Logic3in_AF);
127   else if (name == "logic_3AG") NewTask(name, "Logic 3AG (A+B+C <= 2)", &cTaskLib::Task_Logic3in_AG);
128   else if (name == "logic_3AH") NewTask(name, "Logic 3AH (A+B+C == 3)", &cTaskLib::Task_Logic3in_AH);
129   else if (name == "logic_3AI") NewTask(name, "Logic 3AI (A+B+C == 0,3)", &cTaskLib::Task_Logic3in_AI);
130   else if (name == "logic_3AJ") NewTask(name, "Logic 3AJ (A+B+C == 1,3) XOR", &cTaskLib::Task_Logic3in_AJ);
131   else if (name == "logic_3AK") NewTask(name, "Logic 3AK (A+B+C != 2)", &cTaskLib::Task_Logic3in_AK);
132   else if (name == "logic_3AL") NewTask(name, "Logic 3AL (A+B+C >= 2)", &cTaskLib::Task_Logic3in_AL);
133   else if (name == "logic_3AM") NewTask(name, "Logic 3AM (A+B+C != 1)", &cTaskLib::Task_Logic3in_AM);
134   else if (name == "logic_3AN") NewTask(name, "Logic 3AN (A+B+C != 0)", &cTaskLib::Task_Logic3in_AN);
135   else if (name == "logic_3AO") NewTask(name, "Logic 3AO (A & ~B & ~C) [3]", &cTaskLib::Task_Logic3in_AO);
136   else if (name == "logic_3AP") NewTask(name, "Logic 3AP (A^B & ~C)  [3]", &cTaskLib::Task_Logic3in_AP);
137   else if (name == "logic_3AQ") NewTask(name, "Logic 3AQ (A==B & ~C) [3]", &cTaskLib::Task_Logic3in_AQ);
138   else if (name == "logic_3AR") NewTask(name, "Logic 3AR (A & B & ~C) [3]", &cTaskLib::Task_Logic3in_AR);
139   else if (name == "logic_3AS") NewTask(name, "Logic 3AS", &cTaskLib::Task_Logic3in_AS);
140   else if (name == "logic_3AT") NewTask(name, "Logic 3AT", &cTaskLib::Task_Logic3in_AT);
141   else if (name == "logic_3AU") NewTask(name, "Logic 3AU", &cTaskLib::Task_Logic3in_AU);
142   else if (name == "logic_3AV") NewTask(name, "Logic 3AV", &cTaskLib::Task_Logic3in_AV);
143   else if (name == "logic_3AW") NewTask(name, "Logic 3AW", &cTaskLib::Task_Logic3in_AW);
144   else if (name == "logic_3AX") NewTask(name, "Logic 3AX", &cTaskLib::Task_Logic3in_AX);
145   else if (name == "logic_3AY") NewTask(name, "Logic 3AY", &cTaskLib::Task_Logic3in_AY);
146   else if (name == "logic_3AZ") NewTask(name, "Logic 3AZ", &cTaskLib::Task_Logic3in_AZ);
147   else if (name == "logic_3BA") NewTask(name, "Logic 3BA", &cTaskLib::Task_Logic3in_BA);
148   else if (name == "logic_3BB") NewTask(name, "Logic 3BB", &cTaskLib::Task_Logic3in_BB);
149   else if (name == "logic_3BC") NewTask(name, "Logic 3BC", &cTaskLib::Task_Logic3in_BC);
150   else if (name == "logic_3BD") NewTask(name, "Logic 3BD", &cTaskLib::Task_Logic3in_BD);
151   else if (name == "logic_3BE") NewTask(name, "Logic 3BE", &cTaskLib::Task_Logic3in_BE);
152   else if (name == "logic_3BF") NewTask(name, "Logic 3BF", &cTaskLib::Task_Logic3in_BF);
153   else if (name == "logic_3BG") NewTask(name, "Logic 3BG", &cTaskLib::Task_Logic3in_BG);
154   else if (name == "logic_3BH") NewTask(name, "Logic 3BH", &cTaskLib::Task_Logic3in_BH);
155   else if (name == "logic_3BI") NewTask(name, "Logic 3BI", &cTaskLib::Task_Logic3in_BI);
156   else if (name == "logic_3BJ") NewTask(name, "Logic 3BJ", &cTaskLib::Task_Logic3in_BJ);
157   else if (name == "logic_3BK") NewTask(name, "Logic 3BK", &cTaskLib::Task_Logic3in_BK);
158   else if (name == "logic_3BL") NewTask(name, "Logic 3BL", &cTaskLib::Task_Logic3in_BL);
159   else if (name == "logic_3BM") NewTask(name, "Logic 3BM", &cTaskLib::Task_Logic3in_BM);
160   else if (name == "logic_3BN") NewTask(name, "Logic 3BN", &cTaskLib::Task_Logic3in_BN);
161   else if (name == "logic_3BO") NewTask(name, "Logic 3BO", &cTaskLib::Task_Logic3in_BO);
162   else if (name == "logic_3BP") NewTask(name, "Logic 3BP", &cTaskLib::Task_Logic3in_BP);
163   else if (name == "logic_3BQ") NewTask(name, "Logic 3BQ", &cTaskLib::Task_Logic3in_BQ);
164   else if (name == "logic_3BR") NewTask(name, "Logic 3BR", &cTaskLib::Task_Logic3in_BR);
165   else if (name == "logic_3BS") NewTask(name, "Logic 3BS", &cTaskLib::Task_Logic3in_BS);
166   else if (name == "logic_3BT") NewTask(name, "Logic 3BT", &cTaskLib::Task_Logic3in_BT);
167   else if (name == "logic_3BU") NewTask(name, "Logic 3BU", &cTaskLib::Task_Logic3in_BU);
168   else if (name == "logic_3BV") NewTask(name, "Logic 3BV", &cTaskLib::Task_Logic3in_BV);
169   else if (name == "logic_3BW") NewTask(name, "Logic 3BW", &cTaskLib::Task_Logic3in_BW);
170   else if (name == "logic_3BX") NewTask(name, "Logic 3BX", &cTaskLib::Task_Logic3in_BX);
171   else if (name == "logic_3BY") NewTask(name, "Logic 3BY", &cTaskLib::Task_Logic3in_BY);
172   else if (name == "logic_3BZ") NewTask(name, "Logic 3BZ", &cTaskLib::Task_Logic3in_BZ);
173   else if (name == "logic_3CA") NewTask(name, "Logic 3CA", &cTaskLib::Task_Logic3in_CA);
174   else if (name == "logic_3CB") NewTask(name, "Logic 3CB", &cTaskLib::Task_Logic3in_CB);
175   else if (name == "logic_3CC") NewTask(name, "Logic 3CC", &cTaskLib::Task_Logic3in_CC);
176   else if (name == "logic_3CD") NewTask(name, "Logic 3CD", &cTaskLib::Task_Logic3in_CD);
177   else if (name == "logic_3CE") NewTask(name, "Logic 3CE", &cTaskLib::Task_Logic3in_CE);
178   else if (name == "logic_3CF") NewTask(name, "Logic 3CF", &cTaskLib::Task_Logic3in_CF);
179   else if (name == "logic_3CG") NewTask(name, "Logic 3CG", &cTaskLib::Task_Logic3in_CG);
180   else if (name == "logic_3CH") NewTask(name, "Logic 3CH", &cTaskLib::Task_Logic3in_CH);
181   else if (name == "logic_3CI") NewTask(name, "Logic 3CI", &cTaskLib::Task_Logic3in_CI);
182   else if (name == "logic_3CJ") NewTask(name, "Logic 3CJ", &cTaskLib::Task_Logic3in_CJ);
183   else if (name == "logic_3CK") NewTask(name, "Logic 3CK", &cTaskLib::Task_Logic3in_CK);
184   else if (name == "logic_3CL") NewTask(name, "Logic 3CL", &cTaskLib::Task_Logic3in_CL);
185   else if (name == "logic_3CM") NewTask(name, "Logic 3CM", &cTaskLib::Task_Logic3in_CM);
186   else if (name == "logic_3CN") NewTask(name, "Logic 3CN", &cTaskLib::Task_Logic3in_CN);
187   else if (name == "logic_3CO") NewTask(name, "Logic 3CO", &cTaskLib::Task_Logic3in_CO);
188   else if (name == "logic_3CP") NewTask(name, "Logic 3CP", &cTaskLib::Task_Logic3in_CP);
189 
190   // Arbitrary 1-Input Math Tasks
191   else if (name == "math_1AA") NewTask(name, "Math 1AA (2X)", &cTaskLib::Task_Math1in_AA);
192   else if (name == "math_1AB") NewTask(name, "Math 1AB (2X/3)", &cTaskLib::Task_Math1in_AB);
193   else if (name == "math_1AC") NewTask(name, "Math 1AC (5X/4)", &cTaskLib::Task_Math1in_AC);
194   else if (name == "math_1AD") NewTask(name, "Math 1AD (X^2)", &cTaskLib::Task_Math1in_AD);
195   else if (name == "math_1AE") NewTask(name, "Math 1AE (X^3)", &cTaskLib::Task_Math1in_AE);
196   else if (name == "math_1AF") NewTask(name, "Math 1AF (sqrt(X))", &cTaskLib::Task_Math1in_AF);
197   else if (name == "math_1AG") NewTask(name, "Math 1AG (log(X))", &cTaskLib::Task_Math1in_AG);
198   else if (name == "math_1AH") NewTask(name, "Math 1AH (X^2+X^3)", &cTaskLib::Task_Math1in_AH);
199   else if (name == "math_1AI") NewTask(name, "Math 1AI (X^2+sqrt(X))", &cTaskLib::Task_Math1in_AI);
200   else if (name == "math_1AJ") NewTask(name, "Math 1AJ (abs(X))", &cTaskLib::Task_Math1in_AJ);
201   else if (name == "math_1AK") NewTask(name, "Math 1AK (X-5)", &cTaskLib::Task_Math1in_AK);
202   else if (name == "math_1AL") NewTask(name, "Math 1AL (-X)", &cTaskLib::Task_Math1in_AL);
203   else if (name == "math_1AM") NewTask(name, "Math 1AM (5X)", &cTaskLib::Task_Math1in_AM);
204   else if (name == "math_1AN") NewTask(name, "Math 1AN (X/4)", &cTaskLib::Task_Math1in_AN);
205   else if (name == "math_1AO") NewTask(name, "Math 1AO (X-6)", &cTaskLib::Task_Math1in_AO);
206   else if (name == "math_1AP") NewTask(name, "Math 1AP (X-7)", &cTaskLib::Task_Math1in_AP);
207 
208   // Arbitrary 2-Input Math Tasks
209   if (name == "math_2AA") NewTask(name, "Math 2AA (sqrt(X+Y))", &cTaskLib::Task_Math2in_AA);
210   else if (name == "math_2AB") NewTask(name, "Math 2AB ((X+Y)^2)", &cTaskLib::Task_Math2in_AB);
211   else if (name == "math_2AC") NewTask(name, "Math 2AC (X%Y)", &cTaskLib::Task_Math2in_AC);
212   else if (name == "math_2AD") NewTask(name, "Math 2AD (3X/2+5Y/4)", &cTaskLib::Task_Math2in_AD);
213   else if (name == "math_2AE") NewTask(name, "Math 2AE (abs(X-5)+abs(Y-6))", &cTaskLib::Task_Math2in_AE);
214   else if (name == "math_2AF") NewTask(name, "Math 2AF (XY-X/Y)", &cTaskLib::Task_Math2in_AF);
215   else if (name == "math_2AG") NewTask(name, "Math 2AG ((X-Y)^2)", &cTaskLib::Task_Math2in_AG);
216   else if (name == "math_2AH") NewTask(name, "Math 2AH (X^2+Y^2)", &cTaskLib::Task_Math2in_AH);
217   else if (name == "math_2AI") NewTask(name, "Math 2AI (X^2+Y^3)", &cTaskLib::Task_Math2in_AI);
218   else if (name == "math_2AJ") NewTask(name, "Math 2AJ ((sqrt(X)+Y)/(X-7))", &cTaskLib::Task_Math2in_AJ);
219   else if (name == "math_2AK") NewTask(name, "Math 2AK (log(|X/Y|))", &cTaskLib::Task_Math2in_AK);
220   else if (name == "math_2AL") NewTask(name, "Math 2AL (log(|X|)/Y)", &cTaskLib::Task_Math2in_AL);
221   else if (name == "math_2AM") NewTask(name, "Math 2AM (X/log(|Y|))", &cTaskLib::Task_Math2in_AM);
222   else if (name == "math_2AN") NewTask(name, "Math 2AN (X+Y)", &cTaskLib::Task_Math2in_AN);
223   else if (name == "math_2AO") NewTask(name, "Math 2AO (X-Y)", &cTaskLib::Task_Math2in_AO);
224   else if (name == "math_2AP") NewTask(name, "Math 2AP (X/Y)", &cTaskLib::Task_Math2in_AP);
225   else if (name == "math_2AQ") NewTask(name, "Math 2AQ (XY)", &cTaskLib::Task_Math2in_AQ);
226   else if (name == "math_2AR") NewTask(name, "Math 2AR (sqrt(X)+sqrt(Y))", &cTaskLib::Task_Math2in_AR);
227   else if (name == "math_2AS") NewTask(name, "Math 2AS (X+2Y)", &cTaskLib::Task_Math2in_AS);
228   else if (name == "math_2AT") NewTask(name, "Math 2AT (X+3Y)", &cTaskLib::Task_Math2in_AT);
229   else if (name == "math_2AU") NewTask(name, "Math 2AU (2X+3Y)", &cTaskLib::Task_Math2in_AU);
230   else if (name == "math_2AV") NewTask(name, "Math 2AV (XY^2)", &cTaskLib::Task_Math2in_AV);
231 
232   // Arbitrary 3-Input Math Tasks
233   if (name == "math_3AA")      NewTask(name, "Math 3AA (X^2+Y^2+Z^2)", &cTaskLib::Task_Math3in_AA);
234   else if (name == "math_3AB") NewTask(name, "Math 3AB (sqrt(X)+sqrt(Y)+sqrt(Z))", &cTaskLib::Task_Math3in_AB);
235   else if (name == "math_3AC") NewTask(name, "Math 3AC (X+2Y+3Z)", &cTaskLib::Task_Math3in_AC);
236   else if (name == "math_3AD") NewTask(name, "Math 3AD (XY^2+Z^3)", &cTaskLib::Task_Math3in_AD);
237   else if (name == "math_3AE") NewTask(name, "Math 3AE ((X%Y)*Z)", &cTaskLib::Task_Math3in_AE);
238   else if (name == "math_3AF") NewTask(name, "Math 3AF ((X+Y)^2+sqrt(Y+Z))", &cTaskLib::Task_Math3in_AF);
239   else if (name == "math_3AG") NewTask(name, "Math 3AG ((XY)%(YZ))", &cTaskLib::Task_Math3in_AG);
240   else if (name == "math_3AH") NewTask(name, "Math 3AH (X+Y+Z)", &cTaskLib::Task_Math3in_AH);
241   else if (name == "math_3AI") NewTask(name, "Math 3AI (-X-Y-Z)", &cTaskLib::Task_Math3in_AI);
242   else if (name == "math_3AJ") NewTask(name, "Math 3AJ ((X-Y)^2+(Y-Z)^2+(Z-X)^2)", &cTaskLib::Task_Math3in_AJ);
243   else if (name == "math_3AK") NewTask(name, "Math 3AK ((X+Y)^2+(Y+Z)^2+(Z+X)^2)", &cTaskLib::Task_Math3in_AK);
244   else if (name == "math_3AL") NewTask(name, "Math 3AL ((X-Y)^2+(X-Z)^2)", &cTaskLib::Task_Math3in_AL);
245   else if (name == "math_3AM") NewTask(name, "Math 3AM ((X+Y)^2+(Y+Z)^2)", &cTaskLib::Task_Math3in_AM);
246 
247   // Matching Tasks
248   if (name == "matchstr") Load_MatchStr(name, info, envreqs, feedback);
249   else if (name == "match_number") Load_MatchNumber(name, info, envreqs, feedback);
250   else if (name == "matchprodstr") Load_MatchProdStr(name, info, envreqs, feedback);
251 
252   // Sequence Tasks
253   if (name == "sort_inputs") Load_SortInputs(name, info, envreqs, feedback);
254   else if (name == "fibonacci_seq") Load_FibonacciSequence(name, info, envreqs, feedback);
255 
256   // Math Tasks
257   if (name == "mult")       Load_Mult(name, info, envreqs, feedback);
258   else if (name == "div")   Load_Div(name, info, envreqs, feedback);
259   else if (name == "log")   Load_Log(name, info, envreqs, feedback);
260   else if (name == "log2")  Load_Log2(name, info, envreqs, feedback);
261   else if (name == "log10") Load_Log10(name, info, envreqs, feedback);
262   else if (name == "sqrt")  Load_Sqrt(name, info, envreqs, feedback);
263   else if (name == "sine")  Load_Sine(name, info, envreqs, feedback);
264   else if (name == "cosine") Load_Cosine(name, info, envreqs, feedback);
265 
266 
267   // Optimization Tasks
268   if (name == "optimize") Load_Optimize(name, info, envreqs, feedback);
269 
270   // Communication Tasks
271   if (name == "comm_echo") {
272     NewTask(name, "Echo of Neighbor's Input", &cTaskLib::Task_CommEcho, REQ_NEIGHBOR_INPUT);
273   } else if (name == "comm_not") {
274     NewTask(name, "Not of Neighbor's Input", &cTaskLib::Task_CommNot, REQ_NEIGHBOR_INPUT);
275   }
276 
277   // Network Tasks
278   if (name == "net_send") NewTask(name, "Successfully Sent Network Message", &cTaskLib::Task_NetSend);
279   else if (name == "net_receive") NewTask(name, "Successfully Received Network Message", &cTaskLib::Task_NetReceive);
280 
281   // Movement Tasks
282   if (name == "move_up_gradient") NewTask(name, "Move up gradient", &cTaskLib::Task_MoveUpGradient);
283   else if (name == "move_neutral_gradient") NewTask(name, "Move neutral gradient", &cTaskLib::Task_MoveNeutralGradient);
284   else if (name == "move_down_gradient") NewTask(name, "Move down gradient", &cTaskLib::Task_MoveDownGradient);
285   else if (name == "move_not_up_gradient") NewTask(name, "Move not up gradient", &cTaskLib::Task_MoveNotUpGradient);
286   else if (name == "move_to_right_side") NewTask(name, "Move to right side", &cTaskLib::Task_MoveToRightSide);
287   else if (name == "move_to_left_side") NewTask(name, "Move to left side", &cTaskLib::Task_MoveToLeftSide);
288   // BDC Movement Tasks
289   else if (name == "move") NewTask(name, "Successfully Moved", &cTaskLib::Task_Move);
290   else if (name == "movetotarget") NewTask(name, "Move to a target area", &cTaskLib::Task_MoveToTarget);
291   else if (name == "movetoevent") NewTask(name, "Move to a target area", &cTaskLib::Task_MoveToMovementEvent);
292   else if (name == "movebetweenevent") NewTask(name, "Move to a target area", &cTaskLib::Task_MoveBetweenMovementEvent);
293 
294   // reputation based tasks
295   else if (name == "perfect_strings") NewTask(name, "Produce and store perfect strings", &cTaskLib::Task_CreatePerfectStrings);
296 
297   // event tasks
298   if (name == "move_to_event") NewTask(name, "Moved into cell containing event", &cTaskLib::Task_MoveToEvent);
299   else if (name == "event_killed") NewTask(name, "Killed event", &cTaskLib::Task_EventKilled);
300 
301   // Optimization Tasks
302   if (name == "sg_path_traversal") Load_SGPathTraversal(name, info, envreqs, feedback);
303   if (name == "form-group") Load_FormSpatialGroup(name, info, envreqs, feedback);
304   if (name == "form-group-id") Load_FormSpatialGroupWithID(name, info, envreqs, feedback);
305   if (name == "live-on-patch-id") Load_LiveOnPatchRes(name, info, envreqs, feedback);
306   if (name == "collect-odds") Load_CollectOdds(name, info, envreqs, feedback);
307 
308   // Feed Specific Tasks
309   if (name == "eat-target") Load_ConsumeTarget(name, info, envreqs, feedback);
310 
311   // String matching
312   if (name == "all-ones") Load_AllOnes(name, info, envreqs, feedback);
313   else if (name == "royal-road") Load_RoyalRoad(name, info, envreqs, feedback);
314   else if (name == "royal-road-wd") Load_RoyalRoadWithDitches(name, info, envreqs, feedback);
315 
316   // Division of labor
317   if (name == "opinion_is")  Load_OpinionIs(name, info, envreqs, feedback);
318 
319   // Make sure we have actually found a task
320   if (task_array.GetSize() == start_size) {
321     feedback.Error("unknown/unprocessed task entry '%s'", (const char*)name);
322     return NULL;
323   }
324 
325   // And return the found task.
326   return task_array[start_size];
327 }
328 
NewTask(const cString & name,const cString & desc,tTaskTest task_fun,int reqs,cArgContainer * args)329 void cTaskLib::NewTask(const cString& name, const cString& desc, tTaskTest task_fun, int reqs, cArgContainer* args)
330 {
331   if (reqs & REQ_NEIGHBOR_INPUT) use_neighbor_input = true;
332   if (reqs & REQ_NEIGHBOR_OUTPUT) use_neighbor_output = true;
333 
334   const int id = task_array.GetSize();
335   task_array.Resize(id + 1);
336   task_array[id] = new cTaskEntry(name, desc, id, task_fun, args);
337 }
338 
339 
SetupTests(cTaskContext & ctx) const340 void cTaskLib::SetupTests(cTaskContext& ctx) const
341 {
342   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
343   // Collect the inputs in a useful form.
344   const int num_inputs = input_buffer.GetNumStored();
345   int test_inputs[3];
346   for (int i = 0; i < 3; i++) {
347     test_inputs[i] = (num_inputs > i) ? input_buffer[i] : 0;
348   }
349 
350   int test_output = 0;
351   if (ctx.GetOutputBuffer().GetNumStored()) test_output = ctx.GetOutputBuffer()[0];
352 
353 
354   // Setup logic_out to test the output for each logical combination...
355   // Assuming each bit in logic out to be based on the inputs:
356   //
357   //  Logic ID Bit: 7 6 5 4 3 2 1 0
358   //       Input C: 1 1 1 1 0 0 0 0
359   //       Input B: 1 1 0 0 1 1 0 0
360   //       Input A: 1 0 1 0 1 0 1 0
361 
362   int logic_out[8];
363   for (int i = 0; i < 8; i++) logic_out[i] = -1;
364 
365   // Test all input combos!
366   bool func_OK = true;  // Have all outputs been consistant?
367   for (int test_pos = 0; test_pos < 32; test_pos++) {
368     int logic_pos = 0;
369     for (int i = 0; i < 3; i++)  logic_pos += (test_inputs[i] & 1) << i;
370 
371     if ( logic_out[logic_pos] != -1 &&
372         logic_out[logic_pos] != (test_output & 1) ) {
373       func_OK = false;
374       break;
375     }
376     else {
377       logic_out[logic_pos] = test_output & 1;
378     }
379 
380     test_output >>= 1;
381     for (int i = 0; i < 3; i++) test_inputs[i] >>= 1;
382   }
383 
384   // If there were any inconsistancies, deal with them.
385   if (func_OK == false) {
386     ctx.SetLogicId(-1);
387     return;
388   }
389 
390   // Determine the logic ID number of this task.
391   if (num_inputs < 1) {  // 000 -> 001
392     logic_out[1] = logic_out[0];
393   }
394   if (num_inputs < 2) { // 000 -> 010; 001 -> 011
395     logic_out[2] = logic_out[0];
396     logic_out[3] = logic_out[1];
397   }
398   if (num_inputs < 3) { // 000->100;  001->101;  010->110;  011->111
399     logic_out[4] = logic_out[0];
400     logic_out[5] = logic_out[1];
401     logic_out[6] = logic_out[2];
402     logic_out[7] = logic_out[3];
403   }
404 
405   // Lets just make sure we've gotten this correct...
406   assert(logic_out[0] >= 0 && logic_out[0] <= 1);
407   assert(logic_out[1] >= 0 && logic_out[1] <= 1);
408   assert(logic_out[2] >= 0 && logic_out[2] <= 1);
409   assert(logic_out[3] >= 0 && logic_out[3] <= 1);
410   assert(logic_out[4] >= 0 && logic_out[4] <= 1);
411   assert(logic_out[5] >= 0 && logic_out[5] <= 1);
412   assert(logic_out[6] >= 0 && logic_out[6] <= 1);
413   assert(logic_out[7] >= 0 && logic_out[7] <= 1);
414 
415   int logicid = 0;
416   for (int i = 0; i < 8; i++) logicid += logic_out[i] << i;
417 
418   ctx.SetLogicId(logicid);
419 }
420 
421 
Task_Echo(cTaskContext & ctx) const422 double cTaskLib::Task_Echo(cTaskContext& ctx) const
423 {
424   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
425   const int test_output = ctx.GetOutputBuffer()[0];
426   for (int i = 0; i < input_buffer.GetNumStored(); i++) {
427     if (input_buffer[i] == test_output) {
428       assert(ctx.GetLogicId() == 170 || ctx.GetLogicId() == 204 || ctx.GetLogicId() == 240);
429       return 1.0;
430     }
431   }
432   return 0.0;
433 }
434 
435 
Task_Add(cTaskContext & ctx) const436 double cTaskLib::Task_Add(cTaskContext& ctx) const
437 {
438   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
439   const int test_output = ctx.GetOutputBuffer()[0];
440   for (int i = 0; i < input_buffer.GetNumStored(); i++) {
441     for (int j = 0; j < i; j++) {
442       if (test_output == input_buffer[i] + input_buffer[j]) return 1.0;
443     }
444   }
445   return 0.0;
446 }
447 
448 
Task_Add3(cTaskContext & ctx) const449 double cTaskLib::Task_Add3(cTaskContext& ctx) const
450 {
451   const tBuffer<int>& input = ctx.GetInputBuffer();
452   const int output = ctx.GetOutputBuffer()[0];
453   for (int i=0; i<(input.GetNumStored()-2); ++i) {
454     if (output == (input[i] + input[i+1] + input[i+2])) {
455       return 1.0;
456     }
457   }
458   return 0.0;
459 }
460 
461 
Task_Sub(cTaskContext & ctx) const462 double cTaskLib::Task_Sub(cTaskContext& ctx) const
463 {
464   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
465   const int test_output = ctx.GetOutputBuffer()[0];
466   const int input_size = ctx.GetInputBuffer().GetNumStored();
467   for (int i = 0; i < input_size; i++) {
468     for (int j = 0; j < input_size; j++) {
469       if (i == j) continue;
470       if (test_output == input_buffer[i] - input_buffer[j]) return 1.0;
471     }
472   }
473   return 0.0;
474 }
475 
476 // @WRE DontCare task always succeeds.
Task_DontCare(cTaskContext & ctx) const477 double cTaskLib::Task_DontCare(cTaskContext& ctx) const
478 {
479   return 1.0;
480 }
481 
Task_Not(cTaskContext & ctx) const482 double cTaskLib::Task_Not(cTaskContext& ctx) const
483 {
484   const int logic_id = ctx.GetLogicId();
485   if (logic_id == 15 || logic_id == 51 || logic_id == 85) return 1.0;
486   return 0.0;
487 }
488 
Task_Nand(cTaskContext & ctx) const489 double cTaskLib::Task_Nand(cTaskContext& ctx) const
490 {
491   const int logic_id = ctx.GetLogicId();
492   if (logic_id == 63 || logic_id == 95 || logic_id == 119) return 1.0;
493   return 0.0;
494 }
495 
Task_And(cTaskContext & ctx) const496 double cTaskLib::Task_And(cTaskContext& ctx) const
497 {
498   const int logic_id = ctx.GetLogicId();
499   if (logic_id == 136 || logic_id == 160 || logic_id == 192) return 1.0;
500   return 0.0;
501 }
502 
Task_OrNot(cTaskContext & ctx) const503 double cTaskLib::Task_OrNot(cTaskContext& ctx) const
504 {
505   const int logic_id = ctx.GetLogicId();
506   if (logic_id == 175 || logic_id == 187 || logic_id == 207 ||
507       logic_id == 221 || logic_id == 243 || logic_id == 245) return 1.0;
508 
509   return 0.0;
510 }
511 
Task_Or(cTaskContext & ctx) const512 double cTaskLib::Task_Or(cTaskContext& ctx) const
513 {
514   const int logic_id = ctx.GetLogicId();
515   if (logic_id == 238 || logic_id == 250 || logic_id == 252) return 1.0;
516   return 0.0;
517 }
518 
Task_AndNot(cTaskContext & ctx) const519 double cTaskLib::Task_AndNot(cTaskContext& ctx) const
520 {
521   const int logic_id = ctx.GetLogicId();
522   if (logic_id == 10 || logic_id == 12 || logic_id == 34 ||
523       logic_id == 48 || logic_id == 68 || logic_id == 80) return 1.0;
524 
525   return 0.0;
526 }
527 
Task_Nor(cTaskContext & ctx) const528 double cTaskLib::Task_Nor(cTaskContext& ctx) const
529 {
530   const int logic_id = ctx.GetLogicId();
531   if (logic_id == 3 || logic_id == 5 || logic_id == 17) return 1.0;
532   return 0.0;
533 }
534 
Task_Xor(cTaskContext & ctx) const535 double cTaskLib::Task_Xor(cTaskContext& ctx) const
536 {
537   const int logic_id = ctx.GetLogicId();
538   if (logic_id == 60 || logic_id == 90 || logic_id == 102) return 1.0;
539   return 0.0;
540 }
541 
Task_Equ(cTaskContext & ctx) const542 double cTaskLib::Task_Equ(cTaskContext& ctx) const
543 {
544   const int logic_id = ctx.GetLogicId();
545   if (logic_id == 153 || logic_id == 165 || logic_id == 195) return 1.0;
546   return 0.0;
547 }
548 
549 
Task_Nand_ResourceDependent(cTaskContext & ctx) const550 double cTaskLib::Task_Nand_ResourceDependent(cTaskContext& ctx) const
551 {
552   const double resCrossoverLevel = 100;
553 
554   const int logic_id = ctx.GetLogicId();
555   if (!(logic_id == 63 || logic_id == 95 || logic_id == 119)) return 0.0;
556 
557   const cResourceLib& resLib = m_world->GetEnvironment().GetResourceLib();
558   const tArray<double>& resource_count_array = ctx.GetOrganism()->GetOrgInterface().GetResources(m_world->GetDefaultContext());
559   const cResourceCount& resource_count = m_world->GetPopulation().GetResourceCount();
560 
561   if (resource_count.GetSize() == 0) assert(false); // change to: return false;
562 
563   double pher_amount = 0;
564   cResource* res = resLib.GetResource("pheromone");
565 
566   if (strncmp(resource_count.GetResName(res->GetID()), "pheromone", 9) == 0) {
567     pher_amount += resource_count_array[res->GetID()];
568   }
569 
570   if (pher_amount < resCrossoverLevel) return 1.0;
571   return 0.0;
572 }
573 
574 
Task_Nor_ResourceDependent(cTaskContext & ctx) const575 double cTaskLib::Task_Nor_ResourceDependent(cTaskContext& ctx) const
576 {
577   const double resCrossoverLevel = 100;
578 
579   const int logic_id = ctx.GetLogicId();
580   if (!(logic_id == 3 || logic_id == 5 || logic_id == 17))  return 0.0;
581 
582   const cResourceLib& resLib = m_world->GetEnvironment().GetResourceLib();
583   const tArray<double>& resource_count_array = ctx.GetOrganism()->GetOrgInterface().GetResources(m_world->GetDefaultContext());
584   const cResourceCount& resource_count = m_world->GetPopulation().GetResourceCount();
585 
586   //if (resource_count.GetSize() == 0) assert(false); // change to: return false;
587   assert(resource_count.GetSize() != 0);
588 
589   double pher_amount = 0;
590   cResource* res = resLib.GetResource("pheromone");
591 
592   if (strncmp(resource_count.GetResName(res->GetID()), "pheromone", 9) == 0) {
593     pher_amount += resource_count_array[res->GetID()];
594   }
595 
596   if (pher_amount > resCrossoverLevel) return 1.0;
597   return 0.0;
598 }
599 
600 
Task_Logic3in_AA(cTaskContext & ctx) const601 double cTaskLib::Task_Logic3in_AA(cTaskContext& ctx) const
602 {
603   const int logic_id = ctx.GetLogicId();
604   if (logic_id == 1) return 1.0;
605   return 0.0;
606 }
607 
Task_Logic3in_AB(cTaskContext & ctx) const608 double cTaskLib::Task_Logic3in_AB(cTaskContext& ctx) const
609 {
610   const int logic_id = ctx.GetLogicId();
611   if (logic_id == 22) return 1.0;
612   return 0.0;
613 }
614 
Task_Logic3in_AC(cTaskContext & ctx) const615 double cTaskLib::Task_Logic3in_AC(cTaskContext& ctx) const
616 {
617   const int logic_id = ctx.GetLogicId();
618   if (logic_id == 23) return 1.0;
619   return 0.0;
620 }
621 
Task_Logic3in_AD(cTaskContext & ctx) const622 double cTaskLib::Task_Logic3in_AD(cTaskContext& ctx) const
623 {
624   const int logic_id = ctx.GetLogicId();
625   if (logic_id == 104) return 1.0;
626   return 0.0;
627 }
628 
Task_Logic3in_AE(cTaskContext & ctx) const629 double cTaskLib::Task_Logic3in_AE(cTaskContext& ctx) const
630 {
631   const int logic_id = ctx.GetLogicId();
632   if (logic_id == 105) return 1.0;
633   return 0.0;
634 }
635 
Task_Logic3in_AF(cTaskContext & ctx) const636 double cTaskLib::Task_Logic3in_AF(cTaskContext& ctx) const
637 {
638   const int logic_id = ctx.GetLogicId();
639   if (logic_id == 126) return 1.0;
640   return 0.0;
641 }
642 
Task_Logic3in_AG(cTaskContext & ctx) const643 double cTaskLib::Task_Logic3in_AG(cTaskContext& ctx) const
644 {
645   const int logic_id = ctx.GetLogicId();
646   if (logic_id == 127) return 1.0;
647   return 0.0;
648 }
649 
Task_Logic3in_AH(cTaskContext & ctx) const650 double cTaskLib::Task_Logic3in_AH(cTaskContext& ctx) const
651 {
652   const int logic_id = ctx.GetLogicId();
653   if (logic_id == 128) return 1.0;
654   return 0.0;
655 }
656 
Task_Logic3in_AI(cTaskContext & ctx) const657 double cTaskLib::Task_Logic3in_AI(cTaskContext& ctx) const
658 {
659   const int logic_id = ctx.GetLogicId();
660   if (logic_id == 129) return 1.0;
661   return 0.0;
662 }
663 
Task_Logic3in_AJ(cTaskContext & ctx) const664 double cTaskLib::Task_Logic3in_AJ(cTaskContext& ctx) const
665 {
666   const int logic_id = ctx.GetLogicId();
667   if (logic_id == 150) return 1.0;
668   return 0.0;
669 }
670 
Task_Logic3in_AK(cTaskContext & ctx) const671 double cTaskLib::Task_Logic3in_AK(cTaskContext& ctx) const
672 {
673   const int logic_id = ctx.GetLogicId();
674   if (logic_id == 151) return 1.0;
675   return 0.0;
676 }
677 
Task_Logic3in_AL(cTaskContext & ctx) const678 double cTaskLib::Task_Logic3in_AL(cTaskContext& ctx) const
679 {
680   const int logic_id = ctx.GetLogicId();
681   if (logic_id == 232) return 1.0;
682   return 0.0;
683 }
684 
Task_Logic3in_AM(cTaskContext & ctx) const685 double cTaskLib::Task_Logic3in_AM(cTaskContext& ctx) const
686 {
687   const int logic_id = ctx.GetLogicId();
688   if (logic_id == 233) return 1.0;
689   return 0.0;
690 }
691 
Task_Logic3in_AN(cTaskContext & ctx) const692 double cTaskLib::Task_Logic3in_AN(cTaskContext& ctx) const
693 {
694   const int logic_id = ctx.GetLogicId();
695   if (logic_id == 254) return 1.0;
696   return 0.0;
697 }
698 
Task_Logic3in_AO(cTaskContext & ctx) const699 double cTaskLib::Task_Logic3in_AO(cTaskContext& ctx) const
700 {
701   const int logic_id = ctx.GetLogicId();
702   if (logic_id == 2 || logic_id == 4 || logic_id == 16) return 1.0;
703   return 0.0;
704 }
705 
Task_Logic3in_AP(cTaskContext & ctx) const706 double cTaskLib::Task_Logic3in_AP(cTaskContext& ctx) const
707 {
708   const int logic_id = ctx.GetLogicId();
709   if (logic_id == 6 || logic_id == 18 || logic_id == 20) return 1.0;
710   return 0.0;
711 }
712 
Task_Logic3in_AQ(cTaskContext & ctx) const713 double cTaskLib::Task_Logic3in_AQ(cTaskContext& ctx) const
714 {
715   const int logic_id = ctx.GetLogicId();
716   if (logic_id == 7 || logic_id == 19 || logic_id == 21) return 1.0;
717   return 0.0;
718 }
719 
Task_Logic3in_AR(cTaskContext & ctx) const720 double cTaskLib::Task_Logic3in_AR(cTaskContext& ctx) const
721 {
722   const int logic_id = ctx.GetLogicId();
723   if (logic_id == 8 || logic_id == 32 || logic_id == 64) return 1.0;
724   return 0.0;
725 }
726 
Task_Logic3in_AS(cTaskContext & ctx) const727 double cTaskLib::Task_Logic3in_AS(cTaskContext& ctx) const
728 {
729   const int logic_id = ctx.GetLogicId();
730   if (logic_id == 9 || logic_id == 33 || logic_id == 65) return 1.0;
731   return 0.0;
732 }
733 
Task_Logic3in_AT(cTaskContext & ctx) const734 double cTaskLib::Task_Logic3in_AT(cTaskContext& ctx) const
735 {
736   const int logic_id = ctx.GetLogicId();
737   if (logic_id == 14 || logic_id == 50 || logic_id == 84) return 1.0;
738   return 0.0;
739 }
740 
Task_Logic3in_AU(cTaskContext & ctx) const741 double cTaskLib::Task_Logic3in_AU(cTaskContext& ctx) const
742 {
743   const int logic_id = ctx.GetLogicId();
744   if (logic_id == 24 || logic_id == 36 || logic_id == 66) return 1.0;
745   return 0.0;
746 }
747 
Task_Logic3in_AV(cTaskContext & ctx) const748 double cTaskLib::Task_Logic3in_AV(cTaskContext& ctx) const
749 {
750   const int logic_id = ctx.GetLogicId();
751   if (logic_id == 25 || logic_id == 37 || logic_id == 67) return 1.0;
752   return 0.0;
753 }
754 
Task_Logic3in_AW(cTaskContext & ctx) const755 double cTaskLib::Task_Logic3in_AW(cTaskContext& ctx) const
756 {
757   const int logic_id = ctx.GetLogicId();
758   if (logic_id == 30 || logic_id == 54 || logic_id == 86) return 1.0;
759   return 0.0;
760 }
761 
Task_Logic3in_AX(cTaskContext & ctx) const762 double cTaskLib::Task_Logic3in_AX(cTaskContext& ctx) const
763 {
764   const int logic_id = ctx.GetLogicId();
765   if (logic_id == 31 || logic_id == 55 || logic_id == 87) return 1.0;
766   return 0.0;
767 }
768 
Task_Logic3in_AY(cTaskContext & ctx) const769 double cTaskLib::Task_Logic3in_AY(cTaskContext& ctx) const
770 {
771   const int logic_id = ctx.GetLogicId();
772   if (logic_id == 40 || logic_id == 72 || logic_id == 96) return 1.0;
773   return 0.0;
774 }
775 
Task_Logic3in_AZ(cTaskContext & ctx) const776 double cTaskLib::Task_Logic3in_AZ(cTaskContext& ctx) const
777 {
778   const int logic_id = ctx.GetLogicId();
779   if (logic_id == 41 || logic_id == 73 || logic_id == 97) return 1.0;
780   return 0.0;
781 }
782 
Task_Logic3in_BA(cTaskContext & ctx) const783 double cTaskLib::Task_Logic3in_BA(cTaskContext& ctx) const
784 {
785   const int logic_id = ctx.GetLogicId();
786   if (logic_id == 42 || logic_id == 76 || logic_id == 112) return 1.0;
787   return 0.0;
788 }
789 
Task_Logic3in_BB(cTaskContext & ctx) const790 double cTaskLib::Task_Logic3in_BB(cTaskContext& ctx) const
791 {
792   const int logic_id = ctx.GetLogicId();
793   if (logic_id == 43 || logic_id == 77 || logic_id == 113) return 1.0;
794   return 0.0;
795 }
796 
Task_Logic3in_BC(cTaskContext & ctx) const797 double cTaskLib::Task_Logic3in_BC(cTaskContext& ctx) const
798 {
799   const int logic_id = ctx.GetLogicId();
800   if (logic_id == 61 || logic_id == 91 || logic_id == 103) return 1.0;
801   return 0.0;
802 }
803 
Task_Logic3in_BD(cTaskContext & ctx) const804 double cTaskLib::Task_Logic3in_BD(cTaskContext& ctx) const
805 {
806   const int logic_id = ctx.GetLogicId();
807   if (logic_id == 62 || logic_id == 94 || logic_id == 118) return 1.0;
808   return 0.0;
809 }
810 
Task_Logic3in_BE(cTaskContext & ctx) const811 double cTaskLib::Task_Logic3in_BE(cTaskContext& ctx) const
812 {
813   const int logic_id = ctx.GetLogicId();
814   if (logic_id == 106 || logic_id == 108 || logic_id == 120) return 1.0;
815   return 0.0;
816 }
817 
Task_Logic3in_BF(cTaskContext & ctx) const818 double cTaskLib::Task_Logic3in_BF(cTaskContext& ctx) const
819 {
820   const int logic_id = ctx.GetLogicId();
821   if (logic_id == 107 || logic_id == 109 || logic_id == 121) return 1.0;
822   return 0.0;
823 }
824 
Task_Logic3in_BG(cTaskContext & ctx) const825 double cTaskLib::Task_Logic3in_BG(cTaskContext& ctx) const
826 {
827   const int logic_id = ctx.GetLogicId();
828   if (logic_id == 110 || logic_id == 122 || logic_id == 124) return 1.0;
829   return 0.0;
830 }
831 
Task_Logic3in_BH(cTaskContext & ctx) const832 double cTaskLib::Task_Logic3in_BH(cTaskContext& ctx) const
833 {
834   const int logic_id = ctx.GetLogicId();
835   if (logic_id == 111 || logic_id == 123 || logic_id == 125) return 1.0;
836   return 0.0;
837 }
838 
Task_Logic3in_BI(cTaskContext & ctx) const839 double cTaskLib::Task_Logic3in_BI(cTaskContext& ctx) const
840 {
841   const int logic_id = ctx.GetLogicId();
842   if (logic_id == 130 || logic_id == 132 || logic_id == 144) return 1.0;
843   return 0.0;
844 }
845 
Task_Logic3in_BJ(cTaskContext & ctx) const846 double cTaskLib::Task_Logic3in_BJ(cTaskContext& ctx) const
847 {
848   const int logic_id = ctx.GetLogicId();
849   if (logic_id == 131 || logic_id == 133 || logic_id == 145) return 1.0;
850   return 0.0;
851 }
852 
Task_Logic3in_BK(cTaskContext & ctx) const853 double cTaskLib::Task_Logic3in_BK(cTaskContext& ctx) const
854 {
855   const int logic_id = ctx.GetLogicId();
856   if (logic_id == 134 || logic_id == 146 || logic_id == 148) return 1.0;
857   return 0.0;
858 }
859 
Task_Logic3in_BL(cTaskContext & ctx) const860 double cTaskLib::Task_Logic3in_BL(cTaskContext& ctx) const
861 {
862   const int logic_id = ctx.GetLogicId();
863   if (logic_id == 135 || logic_id == 147 || logic_id == 149) return 1.0;
864   return 0.0;
865 }
866 
Task_Logic3in_BM(cTaskContext & ctx) const867 double cTaskLib::Task_Logic3in_BM(cTaskContext& ctx) const
868 {
869   const int logic_id = ctx.GetLogicId();
870   if (logic_id == 137 || logic_id == 161 || logic_id == 193) return 1.0;
871   return 0.0;
872 }
873 
Task_Logic3in_BN(cTaskContext & ctx) const874 double cTaskLib::Task_Logic3in_BN(cTaskContext& ctx) const
875 {
876   const int logic_id = ctx.GetLogicId();
877   if (logic_id == 142 || logic_id == 178 || logic_id == 212) return 1.0;
878   return 0.0;
879 }
880 
Task_Logic3in_BO(cTaskContext & ctx) const881 double cTaskLib::Task_Logic3in_BO(cTaskContext& ctx) const
882 {
883   const int logic_id = ctx.GetLogicId();
884   if (logic_id == 143 || logic_id == 179 || logic_id == 213) return 1.0;
885   return 0.0;
886 }
887 
Task_Logic3in_BP(cTaskContext & ctx) const888 double cTaskLib::Task_Logic3in_BP(cTaskContext& ctx) const
889 {
890   const int logic_id = ctx.GetLogicId();
891   if (logic_id == 152 || logic_id == 164 || logic_id == 194) return 1.0;
892   return 0.0;
893 }
894 
Task_Logic3in_BQ(cTaskContext & ctx) const895 double cTaskLib::Task_Logic3in_BQ(cTaskContext& ctx) const
896 {
897   const int logic_id = ctx.GetLogicId();
898   if (logic_id == 158 || logic_id == 182 || logic_id == 214) return 1.0;
899   return 0.0;
900 }
901 
Task_Logic3in_BR(cTaskContext & ctx) const902 double cTaskLib::Task_Logic3in_BR(cTaskContext& ctx) const
903 {
904   const int logic_id = ctx.GetLogicId();
905   if (logic_id == 159 || logic_id == 183 || logic_id == 215) return 1.0;
906   return 0.0;
907 }
908 
Task_Logic3in_BS(cTaskContext & ctx) const909 double cTaskLib::Task_Logic3in_BS(cTaskContext& ctx) const
910 {
911   const int logic_id = ctx.GetLogicId();
912   if (logic_id == 168 || logic_id == 200 || logic_id == 224) return 1.0;
913   return 0.0;
914 }
915 
Task_Logic3in_BT(cTaskContext & ctx) const916 double cTaskLib::Task_Logic3in_BT(cTaskContext& ctx) const
917 {
918   const int logic_id = ctx.GetLogicId();
919   if (logic_id == 169 || logic_id == 201 || logic_id == 225) return 1.0;
920   return 0.0;
921 }
922 
Task_Logic3in_BU(cTaskContext & ctx) const923 double cTaskLib::Task_Logic3in_BU(cTaskContext& ctx) const
924 {
925   const int logic_id = ctx.GetLogicId();
926   if (logic_id == 171 || logic_id == 205 || logic_id == 241) return 1.0;
927   return 0.0;
928 }
929 
Task_Logic3in_BV(cTaskContext & ctx) const930 double cTaskLib::Task_Logic3in_BV(cTaskContext& ctx) const
931 {
932   const int logic_id = ctx.GetLogicId();
933   if (logic_id == 188 || logic_id == 218 || logic_id == 230) return 1.0;
934   return 0.0;
935 }
936 
Task_Logic3in_BW(cTaskContext & ctx) const937 double cTaskLib::Task_Logic3in_BW(cTaskContext& ctx) const
938 {
939   const int logic_id = ctx.GetLogicId();
940   if (logic_id == 189 || logic_id == 219 || logic_id == 231) return 1.0;
941   return 0.0;
942 }
943 
Task_Logic3in_BX(cTaskContext & ctx) const944 double cTaskLib::Task_Logic3in_BX(cTaskContext& ctx) const
945 {
946   const int logic_id = ctx.GetLogicId();
947   if (logic_id == 190 || logic_id == 222 || logic_id == 246) return 1.0;
948   return 0.0;
949 }
950 
Task_Logic3in_BY(cTaskContext & ctx) const951 double cTaskLib::Task_Logic3in_BY(cTaskContext& ctx) const
952 {
953   const int logic_id = ctx.GetLogicId();
954   if (logic_id == 191 || logic_id == 223 || logic_id == 247) return 1.0;
955   return 0.0;
956 }
957 
Task_Logic3in_BZ(cTaskContext & ctx) const958 double cTaskLib::Task_Logic3in_BZ(cTaskContext& ctx) const
959 {
960   const int logic_id = ctx.GetLogicId();
961   if (logic_id == 234 || logic_id == 236 || logic_id == 248) return 1.0;
962   return 0.0;
963 }
964 
Task_Logic3in_CA(cTaskContext & ctx) const965 double cTaskLib::Task_Logic3in_CA(cTaskContext& ctx) const
966 {
967   const int logic_id = ctx.GetLogicId();
968   if (logic_id == 235 || logic_id == 237 || logic_id == 249) return 1.0;
969   return 0.0;
970 }
971 
Task_Logic3in_CB(cTaskContext & ctx) const972 double cTaskLib::Task_Logic3in_CB(cTaskContext& ctx) const
973 {
974   const int logic_id = ctx.GetLogicId();
975   if (logic_id == 239 || logic_id == 251 || logic_id == 253) return 1.0;
976   return 0.0;
977 }
978 
Task_Logic3in_CC(cTaskContext & ctx) const979 double cTaskLib::Task_Logic3in_CC(cTaskContext& ctx) const
980 {
981   const int logic_id = ctx.GetLogicId();
982   if (logic_id == 11 || logic_id == 13 || logic_id == 35 ||
983       logic_id == 49 || logic_id == 69 || logic_id == 81) return 1.0;
984   return 0.0;
985 }
986 
Task_Logic3in_CD(cTaskContext & ctx) const987 double cTaskLib::Task_Logic3in_CD(cTaskContext& ctx) const
988 {
989   const int logic_id = ctx.GetLogicId();
990   if (logic_id == 26 || logic_id == 28 || logic_id == 38 ||
991       logic_id == 52 || logic_id == 70 || logic_id == 82) return 1.0;
992   return 0.0;
993 }
994 
Task_Logic3in_CE(cTaskContext & ctx) const995 double cTaskLib::Task_Logic3in_CE(cTaskContext& ctx) const
996 {
997   const int logic_id = ctx.GetLogicId();
998   if (logic_id == 27 || logic_id == 29 || logic_id == 39 ||
999       logic_id == 53 || logic_id == 71 || logic_id == 83) return 1.0;
1000   return 0.0;
1001 }
1002 
Task_Logic3in_CF(cTaskContext & ctx) const1003 double cTaskLib::Task_Logic3in_CF(cTaskContext& ctx) const
1004 {
1005   const int logic_id = ctx.GetLogicId();
1006   if (logic_id == 44 || logic_id == 56 || logic_id == 74 ||
1007       logic_id == 88 || logic_id == 98 || logic_id == 100) return 1.0;
1008   return 0.0;
1009 }
1010 
Task_Logic3in_CG(cTaskContext & ctx) const1011 double cTaskLib::Task_Logic3in_CG(cTaskContext& ctx) const
1012 {
1013   const int logic_id = ctx.GetLogicId();
1014   if (logic_id == 45 || logic_id == 57 || logic_id == 75 ||
1015       logic_id == 89 || logic_id == 99 || logic_id == 101) return 1.0;
1016   return 0.0;
1017 }
1018 
Task_Logic3in_CH(cTaskContext & ctx) const1019 double cTaskLib::Task_Logic3in_CH(cTaskContext& ctx) const
1020 {
1021   const int logic_id = ctx.GetLogicId();
1022   if (logic_id == 46 || logic_id == 58 || logic_id == 78 ||
1023       logic_id == 92 || logic_id == 114 || logic_id == 116) return 1.0;
1024   return 0.0;
1025 }
1026 
Task_Logic3in_CI(cTaskContext & ctx) const1027 double cTaskLib::Task_Logic3in_CI(cTaskContext& ctx) const
1028 {
1029   const int logic_id = ctx.GetLogicId();
1030   if (logic_id == 47 || logic_id == 59 || logic_id == 79 ||
1031       logic_id == 93 || logic_id == 115 || logic_id == 117) return 1.0;
1032   return 0.0;
1033 }
1034 
Task_Logic3in_CJ(cTaskContext & ctx) const1035 double cTaskLib::Task_Logic3in_CJ(cTaskContext& ctx) const
1036 {
1037   const int logic_id = ctx.GetLogicId();
1038   if (logic_id == 138 || logic_id == 140 || logic_id == 162 ||
1039       logic_id == 176 || logic_id == 196 || logic_id == 208) return 1.0;
1040   return 0.0;
1041 }
1042 
Task_Logic3in_CK(cTaskContext & ctx) const1043 double cTaskLib::Task_Logic3in_CK(cTaskContext& ctx) const
1044 {
1045   const int logic_id = ctx.GetLogicId();
1046   if (logic_id == 139 || logic_id == 141 || logic_id == 163 ||
1047       logic_id == 177 || logic_id == 197 || logic_id == 209) return 1.0;
1048   return 0.0;
1049 }
1050 
Task_Logic3in_CL(cTaskContext & ctx) const1051 double cTaskLib::Task_Logic3in_CL(cTaskContext& ctx) const
1052 {
1053   const int logic_id = ctx.GetLogicId();
1054   if (logic_id == 154 || logic_id == 156 || logic_id == 166 ||
1055       logic_id == 180 || logic_id == 198 || logic_id == 210) return 1.0;
1056   return 0.0;
1057 }
1058 
Task_Logic3in_CM(cTaskContext & ctx) const1059 double cTaskLib::Task_Logic3in_CM(cTaskContext& ctx) const
1060 {
1061   const int logic_id = ctx.GetLogicId();
1062   if (logic_id == 155 || logic_id == 157 || logic_id == 167 ||
1063       logic_id == 181 || logic_id == 199 || logic_id == 211) return 1.0;
1064   return 0.0;
1065 }
1066 
Task_Logic3in_CN(cTaskContext & ctx) const1067 double cTaskLib::Task_Logic3in_CN(cTaskContext& ctx) const
1068 {
1069   const int logic_id = ctx.GetLogicId();
1070   if (logic_id == 172 || logic_id == 184 || logic_id == 202 ||
1071       logic_id == 216 || logic_id == 226 || logic_id == 228) return 1.0;
1072   return 0.0;
1073 }
1074 
Task_Logic3in_CO(cTaskContext & ctx) const1075 double cTaskLib::Task_Logic3in_CO(cTaskContext& ctx) const
1076 {
1077   const int logic_id = ctx.GetLogicId();
1078   if (logic_id == 173 || logic_id == 185 || logic_id == 203 ||
1079       logic_id == 217 || logic_id == 227 || logic_id == 229) return 1.0;
1080   return 0.0;
1081 }
1082 
Task_Logic3in_CP(cTaskContext & ctx) const1083 double cTaskLib::Task_Logic3in_CP(cTaskContext& ctx) const
1084 {
1085   const int logic_id = ctx.GetLogicId();
1086   if (logic_id == 174 || logic_id == 186 || logic_id == 206 ||
1087       logic_id == 220 || logic_id == 242 || logic_id == 244) return 1.0;
1088   return 0.0;
1089 }
1090 
Task_Math1in_AA(cTaskContext & ctx) const1091 double cTaskLib::Task_Math1in_AA(cTaskContext& ctx) const //(2X)
1092 {
1093   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1094   const int test_output = ctx.GetOutputBuffer()[0];
1095   const int input_size = input_buffer.GetNumStored();
1096 
1097   for (int i = 0; i < input_size; i++) {
1098     if (test_output == 2 * input_buffer[i]) return 1.0;
1099   }
1100   return 0.0;
1101 }
1102 
Task_Math1in_AB(cTaskContext & ctx) const1103 double cTaskLib::Task_Math1in_AB(cTaskContext& ctx) const //(2X/3)
1104 {
1105   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1106   const int test_output = ctx.GetOutputBuffer()[0];
1107   const int input_size = input_buffer.GetNumStored();
1108 
1109   for (int i = 0; i < input_size; i ++) {
1110     if (test_output == 2 * input_buffer[i] / 3) return 1.0;
1111   }
1112   return 0.0;
1113 }
1114 
Task_Math1in_AC(cTaskContext & ctx) const1115 double cTaskLib::Task_Math1in_AC(cTaskContext& ctx) const //(5X/4)
1116 {
1117   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1118   const int test_output = ctx.GetOutputBuffer()[0];
1119   const int input_size = input_buffer.GetNumStored();
1120 
1121   for (int i = 0; i < input_size; i ++) {
1122     if (test_output == 5 * input_buffer[i] / 4) return 1.0;
1123   }
1124   return 0.0;
1125 }
1126 
Task_Math1in_AD(cTaskContext & ctx) const1127 double cTaskLib::Task_Math1in_AD(cTaskContext& ctx) const //(X^2)
1128 {
1129   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1130   const int test_output = ctx.GetOutputBuffer()[0];
1131   const int input_size = input_buffer.GetNumStored();
1132   for (int i = 0; i < input_size; i ++) {
1133     if (test_output == input_buffer[i] * input_buffer[i]) return 1.0;
1134   }
1135   return 0.0;
1136 }
1137 
Task_Math1in_AE(cTaskContext & ctx) const1138 double cTaskLib::Task_Math1in_AE(cTaskContext& ctx) const //(X^3)
1139 {
1140   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1141   const int test_output = ctx.GetOutputBuffer()[0];
1142   const int input_size = input_buffer.GetNumStored();
1143 
1144   for (int i = 0; i < input_size; i ++) {
1145     if (test_output == input_buffer[i] * input_buffer[i] * input_buffer[i])
1146       return 1.0;
1147   }
1148   return 0.0;
1149 }
1150 
Task_Math1in_AF(cTaskContext & ctx) const1151 double cTaskLib::Task_Math1in_AF(cTaskContext& ctx) const //(sqrt(X)
1152 {
1153   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1154   const int test_output = ctx.GetOutputBuffer()[0];
1155   const int input_size = input_buffer.GetNumStored();
1156   for (int i = 0; i < input_size; i ++) {
1157     if (test_output == (int) sqrt((double) abs(input_buffer[i]))) return 1.0;
1158   }
1159   return 0.0;
1160 }
1161 
Task_Math1in_AG(cTaskContext & ctx) const1162 double cTaskLib::Task_Math1in_AG(cTaskContext& ctx) const //(log(X))
1163 {
1164   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1165   const int test_output = ctx.GetOutputBuffer()[0];
1166   const int input_size = input_buffer.GetNumStored();
1167 
1168   for (int i = 0; i < input_size; i ++) {
1169     if (input_buffer[i] <= 0) continue;
1170     if (test_output == (int) log((double) input_buffer[i])) return 1.0;
1171   }
1172   return 0.0;
1173 }
1174 
Task_Math1in_AH(cTaskContext & ctx) const1175 double cTaskLib::Task_Math1in_AH(cTaskContext& ctx) const //(X^2+X^3)
1176 {
1177   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1178   const int test_output = ctx.GetOutputBuffer()[0];
1179   const int input_size = input_buffer.GetNumStored();
1180 
1181   for (int i = 0; i < input_size; i ++) {
1182     if (test_output == input_buffer[i] * input_buffer[i] + input_buffer[i] * input_buffer[i] * input_buffer[i])
1183       return 1.0;
1184   }
1185   return 0.0;
1186 }
1187 
Task_Math1in_AI(cTaskContext & ctx) const1188 double cTaskLib::Task_Math1in_AI(cTaskContext& ctx) const // (X^2 + sqrt(X))
1189 {
1190   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1191   const int test_output = ctx.GetOutputBuffer()[0];
1192   const int input_size = input_buffer.GetNumStored();
1193 
1194   for (int i = 0; i < input_size; i ++) {
1195     if (test_output == input_buffer[i] * input_buffer[i] + (int) sqrt((double) abs(input_buffer[i])))
1196       return 1.0;
1197   }
1198   return 0.0;
1199 }
1200 
Task_Math1in_AJ(cTaskContext & ctx) const1201 double cTaskLib::Task_Math1in_AJ(cTaskContext& ctx) const // abs(X)
1202 {
1203   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1204   const int test_output = ctx.GetOutputBuffer()[0];
1205   const int input_size = input_buffer.GetNumStored();
1206 
1207   for (int i = 0; i < input_size; i ++) {
1208     if (test_output == abs(input_buffer[i])) return 1.0;
1209   }
1210   return 0.0;
1211 }
1212 
Task_Math1in_AK(cTaskContext & ctx) const1213 double cTaskLib::Task_Math1in_AK(cTaskContext& ctx) const //(X-5)
1214 {
1215   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1216   const int test_output = ctx.GetOutputBuffer()[0];
1217   const int input_size = input_buffer.GetNumStored();
1218 
1219   for (int i = 0; i < input_size; i ++) {
1220     if (test_output == input_buffer[i] - 5) return 1.0;
1221   }
1222   return 0.0;
1223 }
1224 
Task_Math1in_AL(cTaskContext & ctx) const1225 double cTaskLib::Task_Math1in_AL(cTaskContext& ctx) const //(-X)
1226 {
1227   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1228   const int test_output = ctx.GetOutputBuffer()[0];
1229   const int input_size = input_buffer.GetNumStored();
1230 
1231   for (int i = 0; i < input_size; i ++) {
1232     if (test_output == 0 - input_buffer[i]) return 1.0;
1233   }
1234   return 0.0;
1235 }
1236 
Task_Math1in_AM(cTaskContext & ctx) const1237 double cTaskLib::Task_Math1in_AM(cTaskContext& ctx) const //(5X)
1238 {
1239   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1240   const int test_output = ctx.GetOutputBuffer()[0];
1241   const int input_size = input_buffer.GetNumStored();
1242 
1243   for (int i = 0; i < input_size; i ++) {
1244     if (test_output == 5 * input_buffer[i]) return 1.0;
1245   }
1246   return 0.0;
1247 }
1248 
Task_Math1in_AN(cTaskContext & ctx) const1249 double cTaskLib::Task_Math1in_AN(cTaskContext& ctx) const //(X/4)
1250 {
1251   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1252   const int test_output = ctx.GetOutputBuffer()[0];
1253   const int input_size = input_buffer.GetNumStored();
1254 
1255   for (int i = 0; i < input_size; i ++) {
1256     if (test_output == input_buffer[i] / 4) return 1.0;
1257   }
1258   return 0.0;
1259 }
1260 
Task_Math1in_AO(cTaskContext & ctx) const1261 double cTaskLib::Task_Math1in_AO(cTaskContext& ctx) const //(X-6)
1262 {
1263   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1264   const int test_output = ctx.GetOutputBuffer()[0];
1265   const int input_size = input_buffer.GetNumStored();
1266 
1267   for (int i = 0; i < input_size; i ++) {
1268     if (test_output == input_buffer[i] - 6) return 1.0;
1269   }
1270   return 0.0;
1271 }
1272 
Task_Math1in_AP(cTaskContext & ctx) const1273 double cTaskLib::Task_Math1in_AP(cTaskContext& ctx) const //(X-7)
1274 {
1275   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1276   const int test_output = ctx.GetOutputBuffer()[0];
1277   const int input_size = input_buffer.GetNumStored();
1278 
1279   for (int i = 0; i < input_size; i ++) {
1280     if (test_output == input_buffer[i] - 7) return 1.0;
1281   }
1282   return 0.0;
1283 }
1284 
Task_Math2in_AA(cTaskContext & ctx) const1285 double cTaskLib::Task_Math2in_AA(cTaskContext& ctx) const //(sqrt(X+Y))
1286 {
1287   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1288   const int test_output = ctx.GetOutputBuffer()[0];
1289   const int input_size = input_buffer.GetNumStored();
1290 
1291   for (int i = 0; i < input_size; i++) {
1292     for (int j = 0; j < input_size; j++) {
1293       if (i == j) continue;
1294       if (test_output == (int) sqrt((double) abs(input_buffer[i] + input_buffer[j])))
1295         return 1.0;
1296     }
1297   }
1298   return 0.0;
1299 }
1300 
Task_Math2in_AB(cTaskContext & ctx) const1301 double cTaskLib::Task_Math2in_AB(cTaskContext& ctx) const  //((X+Y)^2)
1302 {
1303   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1304   const int test_output = ctx.GetOutputBuffer()[0];
1305   const int input_size = input_buffer.GetNumStored();
1306 
1307   for (int i = 0; i < input_size; i++) {
1308     for (int j = 0; j < input_size; j++) {
1309       if (i == j) continue;
1310       if (test_output == (input_buffer[i] + input_buffer[j]) *
1311           (input_buffer[i] + input_buffer[j])) return 1.0;
1312     }
1313   }
1314   return 0.0;
1315 }
1316 
Task_Math2in_AC(cTaskContext & ctx) const1317 double cTaskLib::Task_Math2in_AC(cTaskContext& ctx) const //(X%Y)
1318 {
1319   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1320   const int test_output = ctx.GetOutputBuffer()[0];
1321   const int input_size = input_buffer.GetNumStored();
1322 
1323   for (int i = 0; i < input_size; i++) {
1324     for (int j = 0; j < input_size; j++) {
1325       if (i == j) continue;
1326       if (input_buffer[j] == 0) continue; // mod by zero
1327       if (test_output == input_buffer[i] % input_buffer[j]) return 1.0;
1328     }
1329   }
1330   return 0.0;
1331 }
1332 
Task_Math2in_AD(cTaskContext & ctx) const1333 double cTaskLib::Task_Math2in_AD(cTaskContext& ctx) const //(3X/2+5Y/4)
1334 {
1335   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1336   const int test_output = ctx.GetOutputBuffer()[0];
1337   const int input_size = input_buffer.GetNumStored();
1338 
1339   for (int i = 0; i < input_size; i++) {
1340     for (int j = 0; j < input_size; j++) {
1341       if (i == j) continue;
1342       if (test_output == 3 * input_buffer[i] / 2 + 5 * input_buffer[j] / 4)
1343         return 1.0;
1344     }
1345   }
1346   return 0.0;
1347 }
1348 
Task_Math2in_AE(cTaskContext & ctx) const1349 double cTaskLib::Task_Math2in_AE(cTaskContext& ctx) const //(abs(X-5)+abs(Y-6))
1350 {
1351   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1352   const int test_output = ctx.GetOutputBuffer()[0];
1353   const int input_size = input_buffer.GetNumStored();
1354 
1355   for (int i = 0; i < input_size; i++) {
1356     for (int j = 0; j < input_size; j++) {
1357       if (i == j) continue;
1358       if (test_output == abs(input_buffer[i] - 5) + abs(input_buffer[j] - 6))
1359         return 1.0;
1360     }
1361   }
1362   return 0.0;
1363 }
1364 
Task_Math2in_AF(cTaskContext & ctx) const1365 double cTaskLib::Task_Math2in_AF(cTaskContext& ctx) const //(XY-X/Y)
1366 {
1367   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1368   const int test_output = ctx.GetOutputBuffer()[0];
1369   const int input_size = input_buffer.GetNumStored();
1370 
1371   for (int i = 0; i < input_size; i++) {
1372     for (int j = 0; j < input_size; j++) {
1373       if (i == j) continue;
1374       if (input_buffer[j] == 0) continue;
1375       if (0-INT_MAX > input_buffer[i] && input_buffer[j] == -1) continue;
1376       if (test_output == input_buffer[i] * input_buffer[j] -
1377           input_buffer[i] / input_buffer[j]) return 1.0;
1378     }
1379   }
1380   return 0.0;
1381 }
1382 
Task_Math2in_AG(cTaskContext & ctx) const1383 double cTaskLib::Task_Math2in_AG(cTaskContext& ctx) const //((X-Y)^2)
1384 {
1385   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1386   const int test_output = ctx.GetOutputBuffer()[0];
1387   const int input_size = input_buffer.GetNumStored();
1388 
1389   for (int i = 0; i < input_size; i++) {
1390     for (int j = 0; j < input_size; j++) {
1391       if (i == j) continue;
1392       if (test_output == (input_buffer[i] - input_buffer[j]) *
1393           (input_buffer[i] - input_buffer[j])) return 1.0;
1394     }
1395   }
1396   return 0.0;
1397 }
1398 
Task_Math2in_AH(cTaskContext & ctx) const1399 double cTaskLib::Task_Math2in_AH(cTaskContext& ctx) const //(X^2+Y^2)
1400 {
1401   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1402   const int test_output = ctx.GetOutputBuffer()[0];
1403   const int input_size = input_buffer.GetNumStored();
1404 
1405   for (int i = 0; i < input_size; i++) {
1406     for (int j = 0; j < input_size; j++) {
1407       if (i == j) continue;
1408       if (test_output == input_buffer[i] * input_buffer[i] +
1409           input_buffer[j] * input_buffer[j]) return 1.0;
1410     }
1411   }
1412   return 0.0;
1413 }
1414 
Task_Math2in_AI(cTaskContext & ctx) const1415 double cTaskLib::Task_Math2in_AI(cTaskContext& ctx) const //(X^2+Y^3)
1416 {
1417   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1418   const int test_output = ctx.GetOutputBuffer()[0];
1419   const int input_size = input_buffer.GetNumStored();
1420 
1421   for (int i = 0; i < input_size; i++) {
1422     for (int j = 0; j < input_size; j++) {
1423       if (i == j) continue;
1424       if (test_output == input_buffer[i] * input_buffer[i] + input_buffer[j] * input_buffer[j] * input_buffer[j])
1425         return 1.0;
1426     }
1427   }
1428   return 0.0;
1429 }
1430 
Task_Math2in_AJ(cTaskContext & ctx) const1431 double cTaskLib::Task_Math2in_AJ(cTaskContext& ctx) const //((sqrt(X)+Y)/(X-7))
1432 {
1433   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1434   const int test_output = ctx.GetOutputBuffer()[0];
1435   const int input_size = input_buffer.GetNumStored();
1436 
1437   for (int i = 0; i < input_size; i++) {
1438     for (int j = 0; j < input_size; j++) {
1439       if (i == j) continue;
1440       if (input_buffer[i] - 7 == 0) continue;
1441       if (test_output == ((int) sqrt((double) abs(input_buffer[i])) + input_buffer[j]) / (input_buffer[i] - 7)) return 1.0;
1442     }
1443   }
1444   return 0.0;
1445 }
1446 
Task_Math2in_AK(cTaskContext & ctx) const1447 double cTaskLib::Task_Math2in_AK(cTaskContext& ctx) const //(log(|X/Y|))
1448 {
1449   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1450   const int test_output = ctx.GetOutputBuffer()[0];
1451   const int input_size = input_buffer.GetNumStored();
1452 
1453   for (int i = 0; i < input_size; i++) {
1454     for (int j = 0; j < input_size; j++) {
1455       if (i == j || input_buffer[j] == 0 ) continue;
1456       if (0-INT_MAX > input_buffer[i] && input_buffer[j] == -1) continue;
1457       if (input_buffer[i] / input_buffer[j] == 0) continue;
1458       if (test_output == (int) log((double) abs(input_buffer[i] / input_buffer[j])))
1459         return 1.0;
1460     }
1461   }
1462   return 0.0;
1463 }
1464 
Task_Math2in_AL(cTaskContext & ctx) const1465 double cTaskLib::Task_Math2in_AL(cTaskContext& ctx) const //(log(|X|)/Y)
1466 {
1467   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1468   const int test_output = ctx.GetOutputBuffer()[0];
1469   const int input_size = input_buffer.GetNumStored();
1470 
1471   for (int i = 0; i < input_size; i++) {
1472     for (int j = 0; j < input_size; j++) {
1473       if (i == j || input_buffer[j] == 0) continue;
1474       if (test_output == (int) log((double) abs(input_buffer[i])) / input_buffer[j])
1475         return 1.0;
1476     }
1477   }
1478   return 0.0;
1479 }
1480 
Task_Math2in_AM(cTaskContext & ctx) const1481 double cTaskLib::Task_Math2in_AM(cTaskContext& ctx) const //(X/log(|Y|))
1482 {
1483   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1484   const int test_output = ctx.GetOutputBuffer()[0];
1485   const int input_size = input_buffer.GetNumStored();
1486 
1487   for (int i = 0; i < input_size; i++) {
1488     for (int j = 0; j < input_size; j++) {
1489       if (i == j || log((double) abs(input_buffer[j])) == 0) continue;
1490       if (0-INT_MAX > input_buffer[i] && log((double) abs(input_buffer[j])) == -1) continue;
1491       if (test_output == input_buffer[i] / (int) log((double) abs(input_buffer[j])))
1492         return 1.0;
1493     }
1494   }
1495   return 0.0;
1496 }
1497 
Task_Math2in_AN(cTaskContext & ctx) const1498 double cTaskLib::Task_Math2in_AN(cTaskContext& ctx) const //(X+Y)
1499 {
1500   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1501   const int test_output = ctx.GetOutputBuffer()[0];
1502   const int input_size = input_buffer.GetNumStored();
1503 
1504   for (int i = 0; i < input_size; i++) {
1505     for (int j = 0; j < input_size; j++) {
1506       if (i == j) continue;
1507       if (test_output == input_buffer[i] + input_buffer[j])
1508         return 1.0;
1509     }
1510   }
1511   return 0.0;
1512 }
1513 
Task_Math2in_AO(cTaskContext & ctx) const1514 double cTaskLib::Task_Math2in_AO(cTaskContext& ctx) const //(X-Y)
1515 {
1516   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1517   const int test_output = ctx.GetOutputBuffer()[0];
1518   const int input_size = input_buffer.GetNumStored();
1519 
1520   for (int i = 0; i < input_size; i++) {
1521     for (int j = 0; j < input_size; j++) {
1522       if (i == j) continue;
1523       if (test_output == input_buffer[i] - input_buffer[j])
1524         return 1.0;
1525     }
1526   }
1527   return 0.0;
1528 }
1529 
Task_Math2in_AP(cTaskContext & ctx) const1530 double cTaskLib::Task_Math2in_AP(cTaskContext& ctx) const //(X/Y)
1531 {
1532   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1533   const int test_output = ctx.GetOutputBuffer()[0];
1534   const int input_size = input_buffer.GetNumStored();
1535 
1536   for (int i = 0; i < input_size; i++) {
1537     for (int j = 0; j < input_size; j++) {
1538       if (i == j || input_buffer[j] == 0) continue;
1539       if (0 - INT_MAX > input_buffer[i] && input_buffer[j] == -1) continue;
1540       if (test_output == input_buffer[i] / input_buffer[j])
1541         return 1.0;
1542     }
1543   }
1544   return 0.0;
1545 }
1546 
Task_Math2in_AQ(cTaskContext & ctx) const1547 double cTaskLib::Task_Math2in_AQ(cTaskContext& ctx) const //(XY)
1548 {
1549   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1550   const int test_output = ctx.GetOutputBuffer()[0];
1551   const int input_size = input_buffer.GetNumStored();
1552 
1553   for (int i = 0; i < input_size; i++) {
1554     for (int j = 0; j < input_size; j++) {
1555       if (i == j) continue;
1556       if (test_output == input_buffer[i] * input_buffer[j])
1557         return 1.0;
1558     }
1559   }
1560   return 0.0;
1561 }
1562 
Task_Math2in_AR(cTaskContext & ctx) const1563 double cTaskLib::Task_Math2in_AR(cTaskContext& ctx) const //(sqrt(X)+sqrt(Y))
1564 {
1565   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1566   const int test_output = ctx.GetOutputBuffer()[0];
1567   const int input_size = input_buffer.GetNumStored();
1568 
1569   for (int i = 0; i < input_size; i++) {
1570     for (int j = 0; j < input_size; j++) {
1571       if (i == j) continue;
1572       if (test_output == (int) sqrt((double) abs(input_buffer[i])) + (int) sqrt((double) abs(input_buffer[j])))
1573         return 1.0;
1574     }
1575   }
1576   return 0.0;
1577 }
1578 
Task_Math2in_AS(cTaskContext & ctx) const1579 double cTaskLib::Task_Math2in_AS(cTaskContext& ctx) const //(X+2Y)
1580 {
1581   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1582   const int test_output = ctx.GetOutputBuffer()[0];
1583   const int input_size = input_buffer.GetNumStored();
1584 
1585   for (int i = 0; i < input_size; i++) {
1586     for (int j = 0; j < input_size; j++) {
1587       if (i == j) continue;
1588       if (test_output == input_buffer[i] + 2 * input_buffer[j])
1589         return 1.0;
1590     }
1591   }
1592   return 0.0;
1593 }
1594 
Task_Math2in_AT(cTaskContext & ctx) const1595 double cTaskLib::Task_Math2in_AT(cTaskContext& ctx) const //(X+3Y)
1596 {
1597   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1598   const int test_output = ctx.GetOutputBuffer()[0];
1599   const int input_size = input_buffer.GetNumStored();
1600 
1601   for (int i = 0; i < input_size; i++) {
1602     for (int j = 0; j < input_size; j++) {
1603       if (i == j) continue;
1604       if (test_output == input_buffer[i] + 3 * input_buffer[j])
1605         return 1.0;
1606     }
1607   }
1608   return 0.0;
1609 }
1610 
Task_Math2in_AU(cTaskContext & ctx) const1611 double cTaskLib::Task_Math2in_AU(cTaskContext& ctx) const //(2X+3Y)
1612 {
1613   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1614   const int test_output = ctx.GetOutputBuffer()[0];
1615   const int input_size = input_buffer.GetNumStored();
1616 
1617   for (int i = 0; i < input_size; i++) {
1618     for (int j = 0; j < input_size; j++) {
1619       if (i == j) continue;
1620       if (test_output == 2 * input_buffer[i] + 3 * input_buffer[j])
1621         return 1.0;
1622     }
1623   }
1624   return 0.0;
1625 }
1626 
Task_Math2in_AV(cTaskContext & ctx) const1627 double cTaskLib::Task_Math2in_AV(cTaskContext& ctx) const //(XY^2)
1628 {
1629   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1630   const int test_output = ctx.GetOutputBuffer()[0];
1631   const int input_size = input_buffer.GetNumStored();
1632 
1633   for (int i = 0; i < input_size; i++) {
1634     for (int j = 0; j < input_size; j++) {
1635       if (i == j) continue;
1636       if (test_output == input_buffer[i] * input_buffer[j] * input_buffer[j])
1637         return 1.0;
1638     }
1639   }
1640   return 0.0;
1641 }
1642 
Task_Math3in_AA(cTaskContext & ctx) const1643 double cTaskLib::Task_Math3in_AA(cTaskContext& ctx) const //(X^2+Y^2+Z^2)
1644 {
1645   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1646   const int test_output = ctx.GetOutputBuffer()[0];
1647   const int input_size = input_buffer.GetNumStored();
1648 
1649   for (int i = 0; i < input_size; i ++) {
1650     for (int j = 0; j < input_size; j ++) {
1651       for (int k = 0; k < input_size; k ++) {
1652         if (i == j || j == k || i == k) continue;
1653         if (test_output == input_buffer[i] * input_buffer[i] +
1654             input_buffer[j] * input_buffer[j] +
1655             input_buffer[k] * input_buffer[k]) return 1.0;
1656       }
1657     }
1658   }
1659   return 0.0;
1660 }
1661 
Task_Math3in_AB(cTaskContext & ctx) const1662 double cTaskLib::Task_Math3in_AB(cTaskContext& ctx) const //(sqrt(X)+sqrt(Y)+sqrt(Z))
1663 {
1664   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1665   const int test_output = ctx.GetOutputBuffer()[0];
1666   const int input_size = input_buffer.GetNumStored();
1667 
1668   for (int i = 0; i < input_size; i ++) {
1669     for (int j = 0; j < input_size; j ++) {
1670       for (int k = 0; k < input_size; k ++) {
1671         if (i == j || j == k || i == k) continue;
1672         if (test_output == (int) sqrt((double) abs(input_buffer[i])) +
1673             (int) sqrt((double) abs(input_buffer[j])) + (int) sqrt((double) abs(input_buffer[k])))
1674           return 1.0;
1675       }
1676     }
1677   }
1678   return 0.0;
1679 }
1680 
Task_Math3in_AC(cTaskContext & ctx) const1681 double cTaskLib::Task_Math3in_AC(cTaskContext& ctx) const //(X+2Y+3Z)
1682 {
1683   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1684   const int test_output = ctx.GetOutputBuffer()[0];
1685   const int input_size = input_buffer.GetNumStored();
1686 
1687   for (int i = 0; i < input_size; i ++) {
1688     for (int j = 0; j < input_size; j ++) {
1689       for (int k = 0; k < input_size; k ++) {
1690         if (i == j || j == k || i == k) continue;
1691         if (test_output == input_buffer[i] + 2 * input_buffer[j] +
1692             3 * input_buffer[k]) return 1.0;
1693       }
1694     }
1695   }
1696   return 0.0;
1697 }
1698 
Task_Math3in_AD(cTaskContext & ctx) const1699 double cTaskLib::Task_Math3in_AD(cTaskContext& ctx) const //(XY^2+Z^3)
1700 {
1701   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1702   const int test_output = ctx.GetOutputBuffer()[0];
1703   const int input_size = input_buffer.GetNumStored();
1704 
1705   for (int i = 0; i < input_size; i ++) {
1706     for (int j = 0; j < input_size; j ++) {
1707       for (int k = 0; k < input_size; k ++) {
1708         if (i == j || j == k || i == k) continue;
1709         if (test_output == input_buffer[i] * input_buffer[j] * input_buffer[j] + input_buffer[k] * input_buffer[k] * input_buffer[k])
1710           return 1.0;
1711       }
1712     }
1713   }
1714   return 0.0;
1715 }
1716 
Task_Math3in_AE(cTaskContext & ctx) const1717 double cTaskLib::Task_Math3in_AE(cTaskContext& ctx) const //((X%Y)*Z)
1718 {
1719   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1720   const int test_output = ctx.GetOutputBuffer()[0];
1721   const int input_size = input_buffer.GetNumStored();
1722 
1723   for (int i = 0; i < input_size; i ++) {
1724     for (int j = 0; j < input_size; j ++) {
1725       for (int k = 0; k < input_size; k ++) {
1726         if (i == j || j == k || i == k) continue;
1727         if (input_buffer[j] == 0) continue; // mod by zero
1728         if (test_output == input_buffer[i] % input_buffer[j] * input_buffer[k])
1729           return 1.0;
1730       }
1731     }
1732   }
1733   return 0.0;
1734 }
1735 
Task_Math3in_AF(cTaskContext & ctx) const1736 double cTaskLib::Task_Math3in_AF(cTaskContext& ctx) const //((X+Y)^2+sqrt(Y+Z))
1737 {
1738   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1739   const int test_output = ctx.GetOutputBuffer()[0];
1740   const int input_size = input_buffer.GetNumStored();
1741 
1742   for (int i = 0; i < input_size; i ++) {
1743     for (int j = 0; j < input_size; j ++) {
1744       for (int k = 0; k < input_size; k ++) {
1745         if (i == j || j == k || i == k) continue;
1746         if (test_output == (input_buffer[i] + input_buffer[j]) *
1747             (input_buffer[i] + input_buffer[j]) +
1748             (int) sqrt((double) abs(input_buffer[j] + input_buffer[k])))
1749           return 1.0;
1750       }
1751     }
1752   }
1753   return 0.0;
1754 }
1755 
Task_Math3in_AG(cTaskContext & ctx) const1756 double cTaskLib::Task_Math3in_AG(cTaskContext& ctx) const //((XY)%(YZ))
1757 {
1758   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1759   const int test_output = ctx.GetOutputBuffer()[0];
1760   const int input_size = input_buffer.GetNumStored();
1761 
1762   for (int i = 0; i < input_size; i ++) {
1763     for (int j = 0; j < input_size; j ++) {
1764       for (int k = 0; k < input_size; k ++) {
1765         if (i == j || j == k || i == k) continue;
1766         int mod_base = input_buffer[j] * input_buffer[k];
1767         if (mod_base == 0) continue;
1768         if (test_output == (input_buffer[i] * input_buffer[j]) %
1769             mod_base) return 1.0;
1770       }
1771     }
1772   }
1773   return 0.0;
1774 }
1775 
Task_Math3in_AH(cTaskContext & ctx) const1776 double cTaskLib::Task_Math3in_AH(cTaskContext& ctx) const //(X+Y+Z)
1777 {
1778   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1779   const int test_output = ctx.GetOutputBuffer()[0];
1780   const int input_size = input_buffer.GetNumStored();
1781 
1782   for (int i = 0; i < input_size; i ++) {
1783     for (int j = 0; j < input_size; j ++) {
1784       for (int k = 0; k < input_size; k ++) {
1785         if (i == j || j == k || i == k) continue;
1786         if (test_output == input_buffer[i] + input_buffer[j] + input_buffer[k])
1787           return 1.0;
1788       }
1789     }
1790   }
1791   return 0.0;
1792 }
1793 
Task_Math3in_AI(cTaskContext & ctx) const1794 double cTaskLib::Task_Math3in_AI(cTaskContext& ctx) const //(-X-Y-Z)
1795 {
1796   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1797   const int test_output = ctx.GetOutputBuffer()[0];
1798   const int input_size = input_buffer.GetNumStored();
1799 
1800   for (int i = 0; i < input_size; i ++) {
1801     for (int j = 0; j < input_size; j ++) {
1802       for (int k = 0; k < input_size; k ++) {
1803         if (i == j || j == k || i == k) continue;
1804         if (test_output == 0 - input_buffer[i] - input_buffer[j] - input_buffer[k])
1805           return 1.0;
1806       }
1807     }
1808   }
1809   return 0.0;
1810 }
1811 
Task_Math3in_AJ(cTaskContext & ctx) const1812 double cTaskLib::Task_Math3in_AJ(cTaskContext& ctx) const //((X-Y)^2+(Y-Z)^2+(Z-X)^2)
1813 {
1814   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1815   const int test_output = ctx.GetOutputBuffer()[0];
1816   const int input_size = input_buffer.GetNumStored();
1817 
1818   for (int i = 0; i < input_size; i ++) {
1819     for (int j = 0; j < input_size; j ++) {
1820       for (int k = 0; k < input_size; k ++) {
1821         if (i == j || j == k || i == k) continue;
1822         if (test_output == (input_buffer[i] - input_buffer[j]) * (input_buffer[i] - input_buffer[j]) + (input_buffer[j] - input_buffer[k]) * (input_buffer[j] - input_buffer[k]) + (input_buffer[k] - input_buffer[i]) * (input_buffer[k] - input_buffer[i]))
1823           return 1.0;
1824       }
1825     }
1826   }
1827   return 0.0;
1828 }
1829 
Task_Math3in_AK(cTaskContext & ctx) const1830 double cTaskLib::Task_Math3in_AK(cTaskContext& ctx) const //((X+Y)^2+(Y+Z)^2+(Z+X)^2)
1831 {
1832   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1833   const int test_output = ctx.GetOutputBuffer()[0];
1834   const int input_size = input_buffer.GetNumStored();
1835 
1836   for (int i = 0; i < input_size; i ++) {
1837     for (int j = 0; j < input_size; j ++) {
1838       for (int k = 0; k < input_size; k ++) {
1839         if (i == j || j == k || i == k) continue;
1840         if (test_output == (input_buffer[i] + input_buffer[j]) * (input_buffer[i] + input_buffer[j]) + (input_buffer[j] + input_buffer[k]) * (input_buffer[j] + input_buffer[k]) + (input_buffer[k] + input_buffer[i]) * (input_buffer[k] + input_buffer[i]))
1841           return 1.0;
1842       }
1843     }
1844   }
1845   return 0.0;
1846 }
1847 
Task_Math3in_AL(cTaskContext & ctx) const1848 double cTaskLib::Task_Math3in_AL(cTaskContext& ctx) const //((X-Y)^2+(X-Z)^2)
1849 {
1850   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1851   const int test_output = ctx.GetOutputBuffer()[0];
1852   const int input_size = input_buffer.GetNumStored();
1853   for (int i = 0; i < input_size; i ++) {
1854     for (int j = 0; j < input_size; j ++) {
1855       for (int k = 0; k < input_size; k ++) {
1856         if (i == j || j == k || i == k) continue;
1857         if (test_output == (input_buffer[i] - input_buffer[j]) * (input_buffer[i] - input_buffer[j]) + (input_buffer[i] - input_buffer[k]) * (input_buffer[i] - input_buffer[k]))
1858           return 1.0;
1859       }
1860     }
1861   }
1862   return 0.0;
1863 }
1864 
Task_Math3in_AM(cTaskContext & ctx) const1865 double cTaskLib::Task_Math3in_AM(cTaskContext& ctx) const //((X+Y)^2+(Y+Z)^2)
1866 {
1867   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
1868   const int test_output = ctx.GetOutputBuffer()[0];
1869   const int input_size = input_buffer.GetNumStored();
1870   for (int i = 0; i < input_size; i ++) {
1871     for (int j = 0; j < input_size; j ++) {
1872       for (int k = 0; k < input_size; k ++) {
1873         if (i == j || j == k || i == k) continue;
1874         if (test_output == (input_buffer[i] + input_buffer[j]) * (input_buffer[i] + input_buffer[j]) + (input_buffer[i] + input_buffer[k]) * (input_buffer[i] + input_buffer[k]))
1875           return 1.0;
1876       }
1877     }
1878   }
1879   return 0.0;
1880 }
1881 
1882 
Load_MatchStr(const cString & name,const cString & argstr,cEnvReqs & envreqs,Feedback & feedback)1883 void cTaskLib::Load_MatchStr(const cString& name, const cString& argstr, cEnvReqs& envreqs, Feedback& feedback)
1884 {
1885   cArgSchema schema;
1886   schema.AddEntry("string", 0, cArgSchema::SCHEMA_STRING);
1887   schema.AddEntry("partial",0, 0);
1888   schema.AddEntry("binary",1,1);
1889   schema.AddEntry("pow",0,2.0);
1890   cArgContainer* args = cArgContainer::Load(argstr, schema, feedback);
1891   envreqs.SetMinOutputs(args->GetString(0).GetSize());
1892   if (args) NewTask(name, "MatchStr", &cTaskLib::Task_MatchStr, 0, args);
1893 }
1894 
Task_MatchStr(cTaskContext & ctx) const1895 double cTaskLib::Task_MatchStr(cTaskContext& ctx) const
1896 {
1897   tBuffer<int> temp_buf(ctx.GetOutputBuffer());
1898   //  if (temp_buf[0] != 357913941) return 0;
1899 
1900   //  temp_buf.Pop(); // pop the signal value off of the buffer
1901 
1902   const cString& string_to_match = ctx.GetTaskEntry()->GetArguments().GetString(0);
1903   int partial = ctx.GetTaskEntry()->GetArguments().GetInt(0);
1904   int binary = ctx.GetTaskEntry()->GetArguments().GetInt(1);
1905 //  double mypow = ctx.GetTaskEntry()->GetArguments().GetDouble(0);
1906   int string_index;
1907   int num_matched = 0;
1908   int test_output;
1909   int max_num_matched = 0;
1910   int num_real=0;
1911 
1912   if (!binary) {
1913     if (temp_buf.GetNumStored() > 0) {
1914       test_output = temp_buf[0];
1915 
1916       for (int j = 0; j < string_to_match.GetSize(); j++) {
1917 	string_index = string_to_match.GetSize() - j - 1; // start with last char in string
1918 	int k = 1 << j;
1919 	if ((string_to_match[string_index] == '0' && !(test_output & k)) ||
1920 	    (string_to_match[string_index] == '1' && (test_output & k))) num_matched++;
1921       }
1922       max_num_matched = num_matched;
1923     }
1924   }
1925   else {
1926     for (int j = 0; j < string_to_match.GetSize(); j++) {
1927       if (string_to_match[j] != '9') {
1928 	num_real++;
1929       }
1930       if (string_to_match[j] == '0' && temp_buf[j]==0 ||
1931 	  string_to_match[j] == '1' && temp_buf[j]==1) {
1932           num_matched++;
1933       }
1934     }
1935     max_num_matched = num_matched;
1936   }
1937 
1938   bool used_received = false;
1939   if (ctx.GetReceivedMessages()) {
1940     tBuffer<int> received(*(ctx.GetReceivedMessages()));
1941     for (int i = 0; i < received.GetNumStored(); i++) {
1942       test_output = received[i];
1943       num_matched = 0;
1944 
1945       for (int j = 0; j < string_to_match.GetSize(); j++) {
1946         string_index = string_to_match.GetSize() - j - 1; // start with last char in string
1947         int k = 1 << j;
1948         if ((string_to_match[string_index]=='0' && !(test_output & k)) ||
1949             (string_to_match[string_index]=='1' && (test_output & k))) {
1950 	  num_matched++;
1951 	}
1952       }
1953 
1954       if (num_matched > max_num_matched) {
1955         max_num_matched = num_matched;
1956         used_received = true;
1957       }
1958     }
1959   }
1960 
1961   double bonus = 0.0;
1962   // return value between 0 & 1 representing the percentage of string that was matched
1963   double base_bonus = static_cast<double>(max_num_matched) * 2.0 / static_cast<double>(string_to_match.GetSize()) - 1;
1964 
1965   if (partial) {
1966     base_bonus=double(max_num_matched)*2/double(num_real) -1;
1967   }
1968 
1969   if (base_bonus > 0.0) {
1970     bonus = pow(base_bonus, 2);
1971     if (used_received) m_world->GetStats().AddMarketItemUsed();
1972     else m_world->GetStats().AddMarketOwnItemUsed();
1973   }
1974   return bonus;
1975 }
1976 
GetMatchStrings()1977 vector<cString> cTaskLib::GetMatchStrings()
1978 {
1979   return m_strings;
1980 }
1981 
GetMatchString(int x)1982 cString cTaskLib::GetMatchString(int x)
1983 {
1984   cString s;
1985   if (x >= 0 && x < (int)m_strings.size()){
1986     s = m_strings[x];
1987   } else {
1988     s = cString("");
1989   }
1990 
1991   return s;
1992 }
1993 
1994 
Load_MatchProdStr(const cString & name,const cString & argstr,cEnvReqs & envreqs,Feedback & feedback)1995 void cTaskLib::Load_MatchProdStr(const cString& name, const cString& argstr, cEnvReqs& envreqs, Feedback& feedback)
1996 {
1997   cArgSchema schema;
1998   schema.AddEntry("string", 0, cArgSchema::SCHEMA_STRING);
1999   schema.AddEntry("partial",0, 0);
2000   schema.AddEntry("binary",1,1);
2001   schema.AddEntry("pow",0,2.0);
2002 	schema.AddEntry("tag",2,-1);
2003   cArgContainer* args = cArgContainer::Load(argstr, schema, feedback);
2004   envreqs.SetMinOutputs(args->GetString(0).GetSize());
2005 	m_strings.push_back(args->GetString(0));
2006   if (args) NewTask(name, "MatchProdStr", &cTaskLib::Task_MatchStr, 0, args);
2007 }
2008 
2009 
Task_MatchProdStr(cTaskContext & ctx) const2010 double cTaskLib::Task_MatchProdStr(cTaskContext& ctx) const
2011 {
2012   // These even out the stats tracking.
2013   m_world->GetStats().AddTag(ctx.GetTaskEntry()->GetArguments().GetInt(2), 0);
2014   m_world->GetStats().AddTag(-1, 0);
2015 
2016   tBuffer<int> temp_buf(ctx.GetOutputBuffer());
2017 
2018   const cString& string_to_match = ctx.GetTaskEntry()->GetArguments().GetString(0);
2019   int partial = ctx.GetTaskEntry()->GetArguments().GetInt(0);
2020   int binary = ctx.GetTaskEntry()->GetArguments().GetInt(1);
2021   double mypow = ctx.GetTaskEntry()->GetArguments().GetDouble(0);
2022   int string_index;
2023   int num_matched = 0;
2024   int test_output;
2025   int max_num_matched = 0;
2026   int num_real=0;
2027 
2028   if (!binary) {
2029     if (temp_buf.GetNumStored() > 0) {
2030       test_output = temp_buf[0];
2031 
2032       for (int j = 0; j < string_to_match.GetSize(); j++) {
2033 	string_index = string_to_match.GetSize() - j - 1; // start with last char in string
2034 	int k = 1 << j;
2035 	if ((string_to_match[string_index] == '0' && !(test_output & k)) ||
2036 	    (string_to_match[string_index] == '1' && (test_output & k))) num_matched++;
2037       }
2038       max_num_matched = num_matched;
2039     }
2040   }
2041   else {
2042     for (int j = 0; j < string_to_match.GetSize(); j++) {
2043       if (string_to_match[j]!='9') num_real++;
2044       if (string_to_match[j]=='0' && temp_buf[j]==0 ||
2045 	  string_to_match[j]=='1' && temp_buf[j]==1)
2046 	num_matched++;
2047     }
2048     max_num_matched = num_matched;
2049   }
2050 
2051   // Check if the organism already produced this string.
2052   // If so, it receives a perfect score for this task.
2053   int tag = ctx.GetTaskEntry()->GetArguments().GetInt(2);
2054 
2055   if (m_world->GetConfig().MATCH_ALREADY_PRODUCED.Get()) {
2056     int prod = ctx.GetOrganism()->GetNumberStringsProduced(tag);
2057     if (prod) max_num_matched = string_to_match.GetSize();
2058   }
2059 
2060 
2061   // Update the organism's tag.
2062   ctx.GetOrganism()->UpdateTag(tag, max_num_matched);
2063   if (ctx.GetOrganism()->GetTagLabel() == tag) {
2064     ctx.GetOrganism()->SetLineageLabel(ctx.GetTaskEntry()->GetArguments().GetInt(2));
2065   }
2066 
2067 
2068   // Update stats
2069   cString name;
2070   name = "[produced";
2071   name += string_to_match;
2072   name += "]";
2073   m_world->GetStats().AddStringBitsMatchedValue(name, max_num_matched);
2074 
2075   // if the organism hasn't donated, then zero out its reputation.
2076   if ((ctx.GetOrganism()->GetReputation() > 0) &&
2077       (ctx.GetOrganism()->GetNumberOfDonations() == 0)) {
2078     ctx.GetOrganism()->SetReputation(0);
2079   }
2080 
2081   double bonus = 0.0;
2082   double base_bonus = 0.0;
2083 
2084   base_bonus = static_cast<double>(max_num_matched) * 2.0 / static_cast<double>(string_to_match.GetSize()) - 1;
2085 
2086   if (partial) {
2087     base_bonus=double(max_num_matched)*2/double(num_real) -1;
2088   }
2089 
2090   if (base_bonus > 0.0) {
2091     bonus = pow(base_bonus,mypow);
2092   }
2093   return bonus;
2094 
2095 }
2096 
2097 
Load_MatchNumber(const cString & name,const cString & argstr,cEnvReqs & envreqs,Feedback & feedback)2098 void cTaskLib::Load_MatchNumber(const cString& name, const cString& argstr, cEnvReqs& envreqs, Feedback& feedback)
2099 {
2100   cArgSchema schema;
2101 
2102   // Integer Arguments
2103   schema.AddEntry("target", 0, cArgSchema::SCHEMA_INT);
2104   schema.AddEntry("threshold", 1, -1);
2105   // Double Arguments
2106   schema.AddEntry("halflife", 0, cArgSchema::SCHEMA_DOUBLE);
2107 
2108   cArgContainer* args = cArgContainer::Load(argstr, schema, feedback);
2109   if (args) NewTask(name, "Match Number", &cTaskLib::Task_MatchNumber, 0, args);
2110 }
2111 
Task_MatchNumber(cTaskContext & ctx) const2112 double cTaskLib::Task_MatchNumber(cTaskContext& ctx) const
2113 {
2114   double quality = 0.0;
2115   const cArgContainer& args = ctx.GetTaskEntry()->GetArguments();
2116 
2117   long long diff = ::llabs((long long)args.GetInt(0) - ctx.GetOutputBuffer()[0]);
2118   int threshold = args.GetInt(1);
2119 
2120   if (threshold < 0 || diff <= threshold) { // Negative threshold == infinite
2121     // If within threshold range, quality decays based on absolute difference
2122     double halflife = -1.0 * fabs(args.GetDouble(0));
2123     quality = pow(2.0, static_cast<double>(diff) / halflife);
2124   }
2125 
2126   return quality;
2127 }
2128 
2129 
Load_SortInputs(const cString & name,const cString & argstr,cEnvReqs & envreqs,Feedback & feedback)2130 void cTaskLib::Load_SortInputs(const cString& name, const cString& argstr, cEnvReqs& envreqs, Feedback& feedback)
2131 {
2132   cArgSchema schema;
2133 
2134   // Integer Arguments
2135   schema.AddEntry("size", 0, cArgSchema::SCHEMA_INT); // Number of items to sort
2136   schema.AddEntry("direction", 1, 0); // < 0 = Descending, Otherwise = Ascending
2137   schema.AddEntry("contiguous", 2, 1); // 0 = No, Otherwise = Yes
2138   // Double Arguments
2139   schema.AddEntry("halflife", 0, cArgSchema::SCHEMA_DOUBLE);
2140 
2141   cArgContainer* args = cArgContainer::Load(argstr, schema, feedback);
2142   if (args) {
2143     envreqs.SetMinInputs(args->GetInt(0));
2144     envreqs.SetMinOutputs(args->GetInt(0) * 2);
2145     envreqs.SetTrueRandInputs();
2146     NewTask(name, "Sort Inputs", &cTaskLib::Task_SortInputs, 0, args);
2147   }
2148 }
2149 
Task_SortInputs(cTaskContext & ctx) const2150 double cTaskLib::Task_SortInputs(cTaskContext& ctx) const
2151 {
2152   const cArgContainer& args = ctx.GetTaskEntry()->GetArguments();
2153   const tBuffer<int>& output = ctx.GetOutputBuffer();
2154   const int size = args.GetInt(0);
2155   const int stored = output.GetNumStored();
2156 
2157   // if less than half, can't possibly reach threshold
2158   if (stored <= (size / 2)) return 0.0;
2159 
2160   tHashMap<int, int> valmap;
2161   int score = 0;
2162   int maxscore = 0;
2163 
2164   // add all valid inputs into the value map
2165   for (int i = 0; i < size; i++) valmap.Set(ctx.GetOrganism()->GetInputAt(i), -1);
2166 
2167   int span_start = -1;
2168   int span_end = stored;
2169 
2170   if (args.GetInt(2)) { // Contiguous
2171     // scan for the largest contiguous span
2172     // - in the event of a tie, keep the first discovered
2173     for (int i = 0; i < stored; i++) {
2174       if (valmap.HasEntry(output[i])) {
2175         int t_start = i;
2176         while (++i < stored && valmap.HasEntry(output[i])) ;
2177         if (span_start == -1 || (i - t_start) > (span_end - span_start)) {
2178           span_start = t_start;
2179           span_end = i;
2180         }
2181       }
2182     }
2183 
2184     // no span was found
2185     if (span_start == -1) return 0.0;
2186   } else { // Scattered
2187     // search for first valid entry
2188     while (++span_start < stored && valmap.HasEntry(output[span_start])) ;
2189 
2190     // scanned past the end of the output, nothing to validate
2191     if (span_start >= stored) return 0.0;
2192   }
2193 
2194   // again, if span is less than half the size can't possibly reach threshold
2195   if ((span_end - span_start) <= (size / 2)) return 0.0;
2196 
2197   // insertion sort span
2198   // - count number of actual entries
2199   // - count moves required
2200   // - update valmap, tracking observed inputs
2201   tArray<int> sorted(size);
2202   const bool ascending = (args.GetInt(1) >= 0);
2203   int count = 1;
2204 
2205   // store first value
2206   valmap.Set(output[span_start], span_start);
2207   sorted[0] = output[span_start];
2208 
2209   // iterate over the remaining span (discovered for contiguous, full output for scattered)
2210   for (int i = span_start + 1; i < span_end; i++) {
2211     int value = output[i];
2212 
2213     // check for a dup or invalid output, skip it if so
2214     int idx;
2215     if (!valmap.Find(value, idx) || idx != -1) continue;
2216 
2217     maxscore += count; // count the maximum moves possible
2218     count++; // iterate the observed count
2219     valmap.Set(value,i); // save position, so that missing values can be determined later
2220 
2221     // sort value based on ascending for descending, counting moves
2222     int j = count - 2;
2223     while (j >= 0 && ((ascending && sorted[j] > value) || (!ascending && sorted[j] < value))) {
2224       sorted[j + 1] = sorted[j];
2225       j--;
2226       score++;
2227     }
2228     sorted[j + 1] = value;
2229   }
2230 
2231   // if not all of the inputs were observed
2232   if (count < size) {
2233     // iterate over all inputs
2234     for (int i = 0; i < size; i++) {
2235       int idx;
2236       // if input was not observed
2237       if (valmap.Find(ctx.GetOrganism()->GetInputAt(i), idx) && idx == -1) {
2238         maxscore += count; // add to the maximum move count
2239         score += count; // missing values, scored as maximally out of order
2240         count++; // increment observed count
2241       }
2242     }
2243   }
2244 
2245   double quality = 0.0;
2246 
2247   // score of 50% expected with random output
2248   // - only grant quality when less than 50% maximum moves are required
2249   if (static_cast<double>(score) / static_cast<double>(maxscore) < 0.5) {
2250     double halflife = -1.0 * fabs(args.GetDouble(0));
2251     quality = pow(2.0, static_cast<double>(score) / halflife);
2252   }
2253 
2254   return quality;
2255 }
2256 
2257 
2258 
2259 
2260 class cFibSeqState : public cTaskState {
2261 public:
2262   int seq[2];
2263   int count;
2264 
cFibSeqState()2265   cFibSeqState() : count(0) { seq[0] = 1; seq[1] = 0; }
2266 };
2267 
2268 
Load_FibonacciSequence(const cString & name,const cString & argstr,cEnvReqs & envreqs,Feedback & feedback)2269 void cTaskLib::Load_FibonacciSequence(const cString& name, const cString& argstr, cEnvReqs& envreqs, Feedback& feedback)
2270 {
2271   cArgSchema schema;
2272 
2273   // Integer Arguments
2274   schema.AddEntry("target", 0, cArgSchema::SCHEMA_INT);
2275   // Double Arguments
2276   schema.AddEntry("penalty", 0, 0.0);
2277 
2278   cArgContainer* args = cArgContainer::Load(argstr, schema, feedback);
2279 
2280   if (args) NewTask(name, "Fibonacci Sequence", &cTaskLib::Task_FibonacciSequence, 0, args);
2281 }
2282 
2283 
Task_FibonacciSequence(cTaskContext & ctx) const2284 double cTaskLib::Task_FibonacciSequence(cTaskContext& ctx) const
2285 {
2286   const cArgContainer& args = ctx.GetTaskEntry()->GetArguments();
2287   cFibSeqState* state = static_cast<cFibSeqState*>(ctx.GetTaskState());
2288   if (state == NULL) {
2289     state = new cFibSeqState();
2290     ctx.AddTaskState(state);
2291   }
2292 
2293   const int next = state->seq[0] + state->seq[1];
2294 
2295   // If output matches next in sequence
2296   if (ctx.GetOutputBuffer()[0] == next) {
2297     // Increment count and store next value
2298     state->count++;
2299     state->seq[state->count % 2] = next;
2300 
2301     // If past target sequence ending point, return the penalty setting
2302     if (state->count > args.GetInt(0)) return args.GetDouble(0);
2303 
2304     return 1.0;
2305   }
2306 
2307   return 0.0;
2308 }
2309 
2310 
Load_Optimize(const cString & name,const cString & argstr,cEnvReqs & envreqs,Feedback & feedback)2311 void cTaskLib::Load_Optimize(const cString& name, const cString& argstr, cEnvReqs& envreqs, Feedback& feedback)
2312 {
2313   cArgSchema schema;
2314 
2315   // Integer Arguments
2316   schema.AddEntry("function", 0, cArgSchema::SCHEMA_INT);
2317   schema.AddEntry("binary", 1, 0);
2318   schema.AddEntry("varlength", 2, 8);
2319   schema.AddEntry("numvars", 3, 2);
2320   // Double Arguments
2321   schema.AddEntry("basepow", 0, 2.0);
2322   schema.AddEntry("maxFx", 1, 1.0);
2323   schema.AddEntry("minFx", 2, 0.0);
2324   schema.AddEntry("thresh", 3, -1.0);
2325   schema.AddEntry("threshMax", 4, -1.0);
2326 
2327   cArgContainer* args = cArgContainer::Load(argstr, schema, feedback);
2328   if (args) {
2329     if (args->GetInt(1)) {
2330       envreqs.SetMinOutputs(args->GetInt(2)*args->GetInt(3));
2331     }
2332     else {
2333       // once have ability to change args should in each of these cases change the max/min
2334       // to the appropriate defaults for this function
2335       switch (args->GetInt(0)) {
2336       case 1:
2337 	envreqs.SetMinOutputs(1);
2338 	break;
2339       case 2:
2340 	envreqs.SetMinOutputs(2);
2341 	break;
2342       case 3:
2343 	envreqs.SetMinOutputs(2);
2344 	break;
2345       default:
2346 	envreqs.SetMinOutputs(2);
2347       };
2348     }
2349 
2350     NewTask(name, "Optimize", &cTaskLib::Task_Optimize, 0, args);
2351   }
2352 }
2353 
Task_Optimize(cTaskContext & ctx) const2354 double cTaskLib::Task_Optimize(cTaskContext& ctx) const
2355 {
2356   // if the org hasn't output yet enough numbers, just return without completing any tasks
2357   if (ctx.GetOutputBuffer().GetNumStored() < ctx.GetOutputBuffer().GetCapacity()) return 0;
2358 
2359   double quality = 0.0;
2360   const cArgContainer& args = ctx.GetTaskEntry()->GetArguments();
2361 
2362   // which function are we currently checking?
2363   const int function = args.GetInt(0);
2364 
2365   // get however many variables need, turn them into doubles between 0 and 1
2366   tArray<double> vars;
2367   vars.Resize(args.GetInt(3));
2368 
2369   double Fx = 0.0;
2370 
2371   // some of the problems don't need double variables but use the bit string as a bit string
2372   // string match, Fx=length - num_matched (0 best, length worst)
2373   if (function == 20) {
2374     const cString& string_to_match = args.GetString(0);
2375     int matched=0;
2376     for (int i=0; i<args.GetInt(2); i++) {
2377       if ((string_to_match[i] == '0' && ctx.GetOutputBuffer()[i]==0)  ||
2378 	  (string_to_match[i] == '1' && ctx.GetOutputBuffer()[i]==1))
2379 	matched++;
2380     }
2381     Fx=args.GetInt(2) - matched;
2382   }
2383 
2384   // string with all 1's at beginning until pattern 0101, reward for # 1's
2385   else if (function == 21) {
2386     int numOnes=0;
2387     int patFound=0;
2388     for (int i=0; i<args.GetInt(2)-3; i++) {
2389       if (ctx.GetOutputBuffer()[i]==1) numOnes++;
2390       else {
2391 	if (ctx.GetOutputBuffer()[i+1] == 1 &&
2392 	    ctx.GetOutputBuffer()[i+2]==0 && ctx.GetOutputBuffer()[i+3]==1) {
2393 	  patFound=1;
2394 	}
2395 	break;
2396       }
2397     }
2398     if (patFound) Fx=args.GetInt(2)-4-numOnes;
2399     else Fx=args.GetInt(2);
2400   }
2401 
2402   // simply rewared for number of 1's at beginning of string, maxFx=length of string
2403   else if (function == 22) {
2404     int numOnes=0;
2405     for (int i=0; i<args.GetInt(2); i++) {
2406       if (ctx.GetOutputBuffer()[i]==1) numOnes++;
2407       else break;
2408     }
2409     Fx=args.GetInt(2)-numOnes;
2410   }
2411 
2412   // simply reward for number 0's in string
2413   else if (function == 23) {
2414     int numZeros=0;
2415     for (int i=0; i<args.GetInt(2); i++) {
2416       if (ctx.GetOutputBuffer()[i]==0) numZeros++;
2417       else break;
2418     }
2419     Fx=args.GetInt(2)-numZeros;
2420   }
2421 
2422   else if (function == 18) {
2423     int tot=0;
2424     for (int i=0; i<30; i++) {
2425       tot+= ctx.GetOutputBuffer()[i];
2426     }
2427     Fx = 1+tot;
2428   }
2429 
2430   else if (function == 19) {
2431     tArray<double> tempVars;
2432     tempVars.Resize(args.GetInt(3));
2433     for (int i=0; i<args.GetInt(3); i++) {
2434       tempVars[i]=0;
2435     }
2436 
2437     for (int i=0; i<30; i++) {
2438       tempVars[0]+= ctx.GetOutputBuffer()[i];
2439     }
2440 
2441     int len = args.GetInt(2);
2442     for (int i = len - 1; i >= 0; i--) {
2443       for (int j=1; j<args.GetInt(3); j++) {
2444         tempVars[j-1] += ctx.GetOutputBuffer()[30+i + len*(args.GetInt(3)-j-1)];
2445       }
2446     }
2447 
2448     int Gx = 0;
2449     for (int i = 1; i < args.GetInt(3); i++) {
2450       if (tempVars[i] == 5) Gx += 1;
2451       else Gx += int(tempVars[i]) + 2;
2452     }
2453     Fx = Gx * (1 / (1 + tempVars[0]));
2454   }
2455 
2456   else {
2457     if (args.GetInt(1)) {
2458       int len = args.GetInt(2);
2459       double base_pow = args.GetDouble(0);
2460 
2461       tArray<double> tempVars;
2462       tempVars.Resize(args.GetInt(3));
2463       for (int i=0; i<args.GetInt(3); i++) tempVars[i] = 0;
2464 
2465       double tot = 0;
2466       for (int i = len - 1; i >= 0; i--) {
2467         for (int j=0; j<args.GetInt(3); j++) {
2468           tempVars[j] += ctx.GetOutputBuffer()[i + len*(args.GetInt(3)-j-1)] * pow(base_pow, (len - 1) - i);
2469         }
2470         tot += pow(base_pow, double(i));
2471       }
2472       for (int i=0; i<args.GetInt(3); i++) {
2473         vars[i] = tempVars[i] / tot;
2474       }
2475       //	cout << "x: " << vars[0] << " ";
2476     }
2477     else {
2478       for (int j=0; j<args.GetInt(3); j++) {
2479         vars[j] = double(ctx.GetOutputBuffer()[j]) / 0xffffffff;
2480       }
2481     }
2482 
2483     for (int j=0; j<args.GetInt(3); j++) {
2484       if (vars[j] < 0) vars[j] = 0;
2485       else if (vars[j] > 1) vars[j] = 1;
2486     }
2487 
2488     switch(function) {
2489     case 1:
2490       Fx = vars[0];		// F1
2491       //	  cout << "Fx1: " << Fx << " ";
2492       break;
2493 
2494     case 2:
2495       Fx = (1.0 + vars[1]) * (1.0 - sqrt(vars[0] / (1.0 + vars[1])));   // F2
2496       break;
2497 
2498     case 3:
2499       Fx = (1.0 + vars[1]) * (1.0 - pow(vars[0] / (1.0 + vars[1]), 2.0));  // F3
2500       break;
2501 
2502     case 4:
2503       Fx = (1.0 + vars[1]) * (1.0 - sqrt(vars[0] / (1.0 + vars[1])) - (vars[0] / (1.0 + vars[1])) * sin(3.14159 * vars[0] * 10.0));
2504       break;
2505 
2506     case 5:
2507       vars[0] = vars[0] * -2.0;
2508       Fx = vars[0]*vars[0] + vars[1]*vars[1];
2509       break;
2510 
2511     case 6:
2512       vars[0] = vars[0] * -2.0;
2513       Fx = (vars[0] + 2.0)*(vars[0] + 2.0) + vars[1]*vars[1];
2514       break;
2515 
2516     case 7:
2517       vars[0] = vars[0] * 4.0;
2518       Fx = sqrt(vars[0]) + vars[1];
2519       break;
2520 
2521     case 8:
2522       vars[0] = vars[0] * 4.0;
2523       Fx = sqrt(4.0 - vars[0]) + vars[1];
2524       break;
2525 
2526     case 9: {
2527       double sum = 0;
2528       //      cout << "9x: " << vars[0] << " ";
2529       for (int i=1; i<args.GetInt(3); i++)
2530 	sum += vars[i]/double(args.GetInt(3)-1);
2531       double Gx = 1+9*sum;
2532       Fx = Gx * (1.0 - sqrt(vars[0]/Gx));
2533       break;
2534     }
2535 
2536     case 10: {
2537       double sum = 0;
2538       for (int i=1; i<args.GetInt(3); i++)
2539 	sum += vars[i]/double(args.GetInt(3)-1);
2540       double Gx = 1+9*sum;
2541       Fx = Gx * (1.0 - pow(vars[0]/Gx, 2.0));
2542       break;
2543     }
2544 
2545     case 11: {
2546       double sum = 0;
2547       for (int i=1; i<args.GetInt(3); i++)
2548 	sum += vars[i]/double(args.GetInt(3)-1);
2549       double Gx = 1+9*sum;
2550       Fx = Gx * (1 - sqrt(vars[0]/Gx) - (vars[0]/Gx)*(sin(3.14159*vars[0]*10)));
2551       break;
2552     }
2553 
2554     case 12: {
2555       vars[0] = vars[0]*.9+.1;
2556       Fx = vars[0];
2557       break;
2558     }
2559 
2560     case 13: {
2561       vars[0] = vars[0]*.9+.1;
2562       vars[1] = vars[1]*5;
2563       Fx = (1+vars[1])/vars[0];
2564       break;
2565     }
2566 
2567     case 14: {
2568       vars[0] = vars[0]*6-3;
2569       vars[1] = vars[1]*6-3;
2570       Fx = .5*(vars[0]*vars[0]+vars[1]*vars[1]) + sin(vars[0]*vars[0]+vars[1]*vars[1]);
2571       break;
2572     }
2573 
2574     case 15: {
2575       vars[0] = vars[0]*6-3;
2576       vars[1] = vars[1]*6-3;
2577       Fx = pow((3*vars[0]-2*vars[1]+4),2)/8.0 + pow((vars[0]-vars[1]+1),2)/27.0 + 15;
2578       break;
2579     }
2580 
2581     case 16: {
2582       vars[0] = vars[0]*6-3;
2583       vars[1] = vars[1]*6-3;
2584       Fx = 1.0/(vars[0]*vars[0]+vars[1]*vars[1]+1) - 1.1*exp(-vars[0]*vars[0]-vars[1]*vars[1]);
2585       break;
2586     }
2587 
2588     case 17: {
2589       double sum = 0;
2590       for (int i=1; i<args.GetInt(3); i++)
2591 	sum += (pow((vars[i]*6-3),2)-10*cos(4*3.14159*(vars[i]*6-3)))/10.0;
2592       double Gx = 10+sum;
2593       Fx = Gx * (1.0 - sqrt(vars[0]/Gx));
2594       break;
2595     }
2596 
2597     default:
2598       quality = .001;
2599     }
2600   }
2601 
2602   ctx.SetTaskValue(Fx);
2603   if (args.GetDouble(3) < 0.0) {
2604     double q1 = (args.GetDouble(1) - Fx+.001);
2605     double q2 = (args.GetDouble(1) - args.GetDouble(2)+.001);
2606     assert(q1 > 0.0);
2607     assert(q2 > 0.0);
2608     quality = q1 / q2;
2609   }
2610   else {
2611     if (args.GetDouble(4) < 0.0) {
2612       if (Fx <= (args.GetDouble(1) - args.GetDouble(2))*args.GetDouble(3) + args.GetDouble(2)) {
2613         quality = 1.0;
2614       } else {
2615         quality = 0.0;
2616       }
2617     }
2618     else {
2619       if ( (Fx >= (args.GetDouble(1) - args.GetDouble(2))*args.GetDouble(3) + args.GetDouble(2)) &&
2620 	   (Fx <= (args.GetDouble(1) - args.GetDouble(2))*args.GetDouble(4) + args.GetDouble(2)) ){
2621         quality = 1.0;
2622       } else {
2623         quality = 0.0;
2624       }
2625     }
2626   }
2627 
2628   // because want org to only have 1 shot to use outputs for all functions at once, even if they
2629   // output numbers that give a quality of 0 on a function, still want to mark it as completed
2630   // so give it a very low quality instead of 0 (if using limited resources they still will get
2631   // no reward because set the minimum consumed to max*.001, meaning even if they get the max
2632   // possible fraction they'll be below minimum allowed consumed and will consume nothing
2633 
2634   if (quality > 1) {
2635     cout << "\n\nquality > 1!  quality= " << quality << "  Fx= " << Fx << endl;
2636   }
2637 
2638   if (quality < 0.001) return .001;
2639 
2640   return quality;
2641 }
2642 
2643 
Load_Mult(const cString & name,const cString & argstr,cEnvReqs & envreqs,Feedback & feedback)2644 void cTaskLib::Load_Mult(const cString& name, const cString& argstr, cEnvReqs& envreqs, Feedback& feedback)
2645 {
2646   cArgSchema schema;
2647 
2648   // Integer Arguments
2649   schema.AddEntry("threshold", 0, -1);
2650   // Double Arguments
2651   schema.AddEntry("halflife", 0, cArgSchema::SCHEMA_DOUBLE);
2652 
2653   cArgContainer* args = cArgContainer::Load(argstr, schema, feedback);
2654   if (args) NewTask(name, "Multiplication", &cTaskLib::Task_Mult, 0, args);
2655 }
2656 
2657 
Task_Mult(cTaskContext & ctx) const2658 double cTaskLib::Task_Mult(cTaskContext& ctx) const
2659 {
2660   double quality = 0.0;
2661   const cArgContainer& args = ctx.GetTaskEntry()->GetArguments();
2662 
2663   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
2664   const long long test_output = ctx.GetOutputBuffer()[0];
2665   const int input_size = input_buffer.GetNumStored();
2666 
2667   long long diff = ((long long)INT_MAX + 1) * 2;
2668 
2669   for (int i = 0; i < input_size; i ++) {
2670     for (int j = 0; j < input_size; j ++) {
2671       if (i == j) continue;
2672       long long cur_diff = ::llabs((long long)(input_buffer[i] * input_buffer[j]) - test_output);
2673       if (cur_diff < diff) diff = cur_diff;
2674     }
2675   }
2676 
2677   int threshold = args.GetInt(0);
2678 
2679   if (threshold < 0 || diff <= threshold) { // Negative threshold == infinite
2680     // If within threshold range, quality decays based on absolute difference
2681     double halflife = -1.0 * fabs(args.GetDouble(0));
2682     quality = pow(2.0, static_cast<double>(diff) / halflife);
2683   }
2684 
2685   return quality;
2686 }
2687 
2688 
Load_Div(const cString & name,const cString & argstr,cEnvReqs & envreqs,Feedback & feedback)2689 void cTaskLib::Load_Div(const cString& name, const cString& argstr, cEnvReqs& envreqs, Feedback& feedback)
2690 {
2691   cArgSchema schema;
2692 
2693   // Integer Arguments
2694   schema.AddEntry("threshold", 0, -1);
2695   // Double Arguments
2696   schema.AddEntry("halflife", 0, cArgSchema::SCHEMA_DOUBLE);
2697 
2698   cArgContainer* args = cArgContainer::Load(argstr, schema, feedback);
2699   if (args) NewTask(name, "Division", &cTaskLib::Task_Div, 0, args);
2700 }
2701 
2702 
Task_Div(cTaskContext & ctx) const2703 double cTaskLib::Task_Div(cTaskContext& ctx) const
2704 {
2705   double quality = 0.0;
2706   const cArgContainer& args = ctx.GetTaskEntry()->GetArguments();
2707 
2708   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
2709   const long long test_output = ctx.GetOutputBuffer()[0];
2710   const int input_size = input_buffer.GetNumStored();
2711 
2712   long long diff = ((long long)INT_MAX + 1) * 2;
2713 
2714   for (int i = 0; i < input_size; i ++) {
2715     for (int j = 0; j < input_size; j ++) {
2716       if (i == j || input_buffer[j] == 0) continue;
2717       long long cur_diff = ::llabs((long long)(input_buffer[i] / input_buffer[j]) - test_output);
2718       if (cur_diff < diff) diff = cur_diff;
2719     }
2720   }
2721 
2722   int threshold = args.GetInt(0);
2723 
2724   if (threshold < 0 || diff <= threshold) { // Negative threshold == infinite
2725     // If within threshold range, quality decays based on absolute difference
2726     double halflife = -1.0 * fabs(args.GetDouble(0));
2727     quality = pow(2.0, static_cast<double>(diff) / halflife);
2728   }
2729 
2730   return quality;
2731 }
2732 
2733 
Load_Log(const cString & name,const cString & argstr,cEnvReqs & envreqs,Feedback & feedback)2734 void cTaskLib::Load_Log(const cString& name, const cString& argstr, cEnvReqs& envreqs, Feedback& feedback)
2735 {
2736   cArgSchema schema;
2737 
2738   // Integer Arguments
2739   schema.AddEntry("threshold", 0, -1);
2740   // Double Arguments
2741   schema.AddEntry("halflife", 0, cArgSchema::SCHEMA_DOUBLE);
2742 
2743   cArgContainer* args = cArgContainer::Load(argstr, schema, feedback);
2744   if (args) NewTask(name, "Logarithm (natural)", &cTaskLib::Task_Log, 0, args);
2745 }
2746 
2747 
Task_Log(cTaskContext & ctx) const2748 double cTaskLib::Task_Log(cTaskContext& ctx) const
2749 {
2750   double quality = 0.0;
2751   const cArgContainer& args = ctx.GetTaskEntry()->GetArguments();
2752 
2753   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
2754   const long long test_output = ctx.GetOutputBuffer()[0];
2755   const int input_size = input_buffer.GetNumStored();
2756 
2757   long long diff = ((long long)INT_MAX + 1) * 2;
2758 
2759   for (int i = 0; i < input_size; i ++) {
2760     long long cur_diff = ::llabs((long long)(log(fabs(double(input_buffer[i] ? input_buffer[i] : 1)))) - test_output);
2761     if (cur_diff < diff) diff = cur_diff;
2762   }
2763 
2764   int threshold = args.GetInt(0);
2765 
2766   if (threshold < 0 || diff <= threshold) { // Negative threshold == infinite
2767     // If within threshold range, quality decays based on absolute difference
2768     double halflife = -1.0 * fabs(args.GetDouble(0));
2769     quality = pow(2.0, static_cast<double>(diff) / halflife);
2770   }
2771 
2772   return quality;
2773 }
2774 
2775 
Load_Log2(const cString & name,const cString & argstr,cEnvReqs & envreqs,Feedback & feedback)2776 void cTaskLib::Load_Log2(const cString& name, const cString& argstr, cEnvReqs& envreqs, Feedback& feedback)
2777 {
2778   cArgSchema schema;
2779 
2780   // Integer Arguments
2781   schema.AddEntry("threshold", 0, -1);
2782   // Double Arguments
2783   schema.AddEntry("halflife", 0, cArgSchema::SCHEMA_DOUBLE);
2784 
2785   cArgContainer* args = cArgContainer::Load(argstr, schema, feedback);
2786   if (args) NewTask(name, "Logarithm (base-2)", &cTaskLib::Task_Log2, 0, args);
2787 }
2788 
Task_Log2(cTaskContext & ctx) const2789 double cTaskLib::Task_Log2(cTaskContext& ctx) const
2790 {
2791   double quality = 0.0;
2792   const cArgContainer& args = ctx.GetTaskEntry()->GetArguments();
2793 
2794   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
2795   const long long test_output = ctx.GetOutputBuffer()[0];
2796   const int input_size = input_buffer.GetNumStored();
2797 
2798   long long diff = ((long long)INT_MAX + 1) * 2;
2799 
2800   for (int i = 0; i < input_size; i ++) {
2801     long long cur_diff = ::llabs((long long)(log2(fabs(double(input_buffer[i] ? input_buffer[i] : 1)))) - test_output);
2802     if (cur_diff < diff) diff = cur_diff;
2803   }
2804 
2805   int threshold = args.GetInt(0);
2806 
2807   if (threshold < 0 || diff <= threshold) { // Negative threshold == infinite
2808     // If within threshold range, quality decays based on absolute difference
2809     double halflife = -1.0 * fabs(args.GetDouble(0));
2810     quality = pow(2.0, static_cast<double>(diff) / halflife);
2811   }
2812 
2813   return quality;
2814 }
2815 
2816 
Load_Log10(const cString & name,const cString & argstr,cEnvReqs & envreqs,Feedback & feedback)2817 void cTaskLib::Load_Log10(const cString& name, const cString& argstr, cEnvReqs& envreqs, Feedback& feedback)
2818 {
2819   cArgSchema schema;
2820 
2821   // Integer Arguments
2822   schema.AddEntry("threshold", 0, -1);
2823   // Double Arguments
2824   schema.AddEntry("halflife", 0, cArgSchema::SCHEMA_DOUBLE);
2825 
2826   cArgContainer* args = cArgContainer::Load(argstr, schema, feedback);
2827   if (args) NewTask(name, "Logarithm (base-10)", &cTaskLib::Task_Log10, 0, args);
2828 }
2829 
2830 
Task_Log10(cTaskContext & ctx) const2831 double cTaskLib::Task_Log10(cTaskContext& ctx) const
2832 {
2833   double quality = 0.0;
2834   const cArgContainer& args = ctx.GetTaskEntry()->GetArguments();
2835 
2836   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
2837   const long long test_output = ctx.GetOutputBuffer()[0];
2838   const int input_size = input_buffer.GetNumStored();
2839 
2840   long long diff = ((long long)INT_MAX + 1) * 2;
2841 
2842   for (int i = 0; i < input_size; i ++) {
2843     long long cur_diff = ::llabs((long long)(log10(fabs(double(input_buffer[i] ? input_buffer[i] : 1)))) - test_output);
2844     if (cur_diff < diff) diff = cur_diff;
2845   }
2846 
2847   int threshold = args.GetInt(0);
2848 
2849   if (threshold < 0 || diff <= threshold) { // Negative threshold == infinite
2850     // If within threshold range, quality decays based on absolute difference
2851     double halflife = -1.0 * fabs(args.GetDouble(0));
2852     quality = pow(2.0, static_cast<double>(diff) / halflife);
2853   }
2854 
2855   return quality;
2856 }
2857 
2858 
Load_Sqrt(const cString & name,const cString & argstr,cEnvReqs & envreqs,Feedback & feedback)2859 void cTaskLib::Load_Sqrt(const cString& name, const cString& argstr, cEnvReqs& envreqs, Feedback& feedback)
2860 {
2861   cArgSchema schema;
2862 
2863   // Integer Arguments
2864   schema.AddEntry("threshold", 0, -1);
2865   // Double Arguments
2866   schema.AddEntry("halflife", 0, cArgSchema::SCHEMA_DOUBLE);
2867 
2868   cArgContainer* args = cArgContainer::Load(argstr, schema, feedback);
2869   if (args) NewTask(name, "Square Root", &cTaskLib::Task_Sqrt, 0, args);
2870 }
2871 
2872 
Task_Sqrt(cTaskContext & ctx) const2873 double cTaskLib::Task_Sqrt(cTaskContext& ctx) const
2874 {
2875   double quality = 0.0;
2876   const cArgContainer& args = ctx.GetTaskEntry()->GetArguments();
2877 
2878   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
2879   const long long test_output = ctx.GetOutputBuffer()[0];
2880   const int input_size = input_buffer.GetNumStored();
2881 
2882   long long diff = ((long long)INT_MAX + 1) * 2;
2883 
2884   for (int i = 0; i < input_size; i ++) {
2885     long long cur_diff = ::llabs((long long)(sqrt(fabs(double(input_buffer[i])))) - test_output);
2886     if (cur_diff < diff) diff = cur_diff;
2887   }
2888 
2889   int threshold = args.GetInt(0);
2890 
2891   if (threshold < 0 || diff <= threshold) { // Negative threshold == infinite
2892     // If within threshold range, quality decays based on absolute difference
2893     double halflife = -1.0 * fabs(args.GetDouble(0));
2894     quality = pow(2.0, static_cast<double>(diff) / halflife);
2895   }
2896 
2897   return quality;
2898 }
2899 
2900 
Load_Sine(const cString & name,const cString & argstr,cEnvReqs & envreqs,Feedback & feedback)2901 void cTaskLib::Load_Sine(const cString& name, const cString& argstr, cEnvReqs& envreqs, Feedback& feedback)
2902 {
2903   cArgSchema schema;
2904 
2905   // Integer Arguments
2906   schema.AddEntry("threshold", 0, -1);
2907   // Double Arguments
2908   schema.AddEntry("halflife", 0, cArgSchema::SCHEMA_DOUBLE);
2909 
2910   cArgContainer* args = cArgContainer::Load(argstr, schema, feedback);
2911   if (args) NewTask(name, "Sine", &cTaskLib::Task_Sine, 0, args);
2912 }
2913 
2914 
Task_Sine(cTaskContext & ctx) const2915 double cTaskLib::Task_Sine(cTaskContext& ctx) const
2916 {
2917   double quality = 0.0;
2918   const cArgContainer& args = ctx.GetTaskEntry()->GetArguments();
2919 
2920   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
2921   const long long test_output = ctx.GetOutputBuffer()[0];
2922   const int input_size = input_buffer.GetNumStored();
2923 
2924   long long diff = ((long long)INT_MAX + 1) * 2;
2925 
2926   for (int i = 0; i < input_size; i ++) {
2927     long long cur_diff = ::llabs((long long)(sin(double(input_buffer[i]) / dCastPrecision) * dCastPrecision) - test_output);
2928     if (cur_diff < diff) diff = cur_diff;
2929   }
2930 
2931   int threshold = args.GetInt(0);
2932 
2933   if (threshold < 0 || diff <= threshold) { // Negative threshold == infinite
2934     // If within threshold range, quality decays based on absolute difference
2935     double halflife = -1.0 * fabs(args.GetDouble(0));
2936     quality = pow(2.0, static_cast<double>(diff) / halflife);
2937   }
2938 
2939   return quality;
2940 }
2941 
2942 
Load_Cosine(const cString & name,const cString & argstr,cEnvReqs & envreqs,Feedback & feedback)2943 void cTaskLib::Load_Cosine(const cString& name, const cString& argstr, cEnvReqs& envreqs,
2944 			   Feedback& feedback)
2945 {
2946   cArgSchema schema;
2947 
2948   // Integer Arguments
2949   schema.AddEntry("threshold", 0, -1);
2950   // Double Arguments
2951   schema.AddEntry("halflife", 0, cArgSchema::SCHEMA_DOUBLE);
2952 
2953   cArgContainer* args = cArgContainer::Load(argstr, schema, feedback);
2954   if (args) NewTask(name, "Cosine", &cTaskLib::Task_Cosine, 0, args);
2955 }
2956 
2957 
Task_Cosine(cTaskContext & ctx) const2958 double cTaskLib::Task_Cosine(cTaskContext& ctx) const
2959 {
2960   double quality = 0.0;
2961   const cArgContainer& args = ctx.GetTaskEntry()->GetArguments();
2962 
2963   const tBuffer<int>& input_buffer = ctx.GetInputBuffer();
2964   const long long test_output = ctx.GetOutputBuffer()[0];
2965   const int input_size = input_buffer.GetNumStored();
2966 
2967   long long diff = ((long long)INT_MAX + 1) * 2;
2968 
2969   for (int i = 0; i < input_size; i ++) {
2970     long long cur_diff = ::llabs((long long)(cos(double(input_buffer[i]) / dCastPrecision) * dCastPrecision) - test_output);
2971     if (cur_diff < diff) diff = cur_diff;
2972   }
2973 
2974   int threshold = args.GetInt(0);
2975 
2976   if (threshold < 0 || diff <= threshold) { // Negative threshold == infinite
2977     // If within threshold range, quality decays based on absolute difference
2978     double halflife = -1.0 * fabs(args.GetDouble(0));
2979     quality = pow(2.0, static_cast<double>(diff) / halflife);
2980   }
2981 
2982   return quality;
2983 }
2984 
2985 
Task_CommEcho(cTaskContext & ctx) const2986 double cTaskLib::Task_CommEcho(cTaskContext& ctx) const
2987 {
2988   const int test_output = ctx.GetOutputBuffer()[0];
2989 
2990   tConstListIterator<tBuffer<int> > buff_it(ctx.GetNeighborhoodInputBuffers());
2991 
2992   while (buff_it.Next() != NULL) {
2993     const tBuffer<int>& cur_buff = *(buff_it.Get());
2994     const int buff_size = cur_buff.GetNumStored();
2995     for (int i = 0; i < buff_size; i++) {
2996       if (test_output == cur_buff[i]) return 1.0;
2997     }
2998   }
2999 
3000   return 0.0;
3001 }
3002 
3003 
Task_CommNot(cTaskContext & ctx) const3004 double cTaskLib::Task_CommNot(cTaskContext& ctx) const
3005 {
3006   const int test_output = ctx.GetOutputBuffer()[0];
3007 
3008   tConstListIterator<tBuffer<int> > buff_it(ctx.GetNeighborhoodInputBuffers());
3009 
3010   while (buff_it.Next() != NULL) {
3011     const tBuffer<int>& cur_buff = *(buff_it.Get());
3012     const int buff_size = cur_buff.GetNumStored();
3013     for (int i = 0; i < buff_size; i++) {
3014       if (test_output == (0-(cur_buff[i]+1))) return 1.0;
3015     }
3016   }
3017 
3018   return 0.0;
3019 }
3020 
3021 
Task_NetSend(cTaskContext & ctx) const3022 double cTaskLib::Task_NetSend(cTaskContext& ctx) const
3023 {
3024   return 1.0 * ctx.GetOrganism()->NetCompleted();
3025 }
3026 
3027 
Task_NetReceive(cTaskContext & ctx) const3028 double cTaskLib::Task_NetReceive(cTaskContext& ctx) const
3029 {
3030   if (ctx.GetOrganism()->NetIsValid()) return 1.0;
3031   return 0.0;
3032 }
3033 
3034 
3035 //TODO: add movement tasks here
3036 
Task_MoveUpGradient(cTaskContext & ctx) const3037 double cTaskLib::Task_MoveUpGradient(cTaskContext& ctx) const
3038 {
3039   if (ctx.GetOrganism()->GetGradientMovement() == 1.0) return 1.0;
3040   return 0.0;
3041 }
3042 
3043 
Task_MoveNeutralGradient(cTaskContext & ctx) const3044 double cTaskLib::Task_MoveNeutralGradient(cTaskContext& ctx) const
3045 {
3046   if (ctx.GetOrganism()->GetGradientMovement() == 0.0) return 1.0;
3047   return 0.0;
3048 }
3049 
3050 
Task_MoveDownGradient(cTaskContext & ctx) const3051 double cTaskLib::Task_MoveDownGradient(cTaskContext& ctx) const
3052 {
3053   if (ctx.GetOrganism()->GetGradientMovement() == -1.0) return 1.0;
3054   return 0.0;
3055 }
3056 
3057 
Task_MoveNotUpGradient(cTaskContext & ctx) const3058 double cTaskLib::Task_MoveNotUpGradient(cTaskContext& ctx) const
3059 {
3060   if (Task_MoveUpGradient(ctx)) return 0.0;
3061   return 1.0;
3062 }
3063 
3064 
Task_MoveToRightSide(cTaskContext & ctx) const3065 double cTaskLib::Task_MoveToRightSide(cTaskContext& ctx) const
3066 {
3067   cDeme* deme = ctx.GetOrganism()->GetDeme();
3068   std::pair<int, int> location = deme->GetCellPosition(ctx.GetOrganism()->GetCellID());
3069 
3070   if (location.first == m_world->GetConfig().WORLD_X.Get() - 1) return 1.0;
3071   return 0.0;
3072 }
3073 
3074 
Task_MoveToLeftSide(cTaskContext & ctx) const3075 double cTaskLib::Task_MoveToLeftSide(cTaskContext& ctx) const
3076 {
3077   cDeme* deme = ctx.GetOrganism()->GetDeme();
3078   std::pair<int, int> location = deme->GetCellPosition(ctx.GetOrganism()->GetCellID());
3079 
3080   if (location.first == 0) return 1.0;
3081   return 0.0;
3082 }
3083 
3084 
Task_Move(cTaskContext & ctx) const3085 double cTaskLib::Task_Move(cTaskContext& ctx) const
3086 {
3087   if (ctx.GetOrganism()->GetCellID() != ctx.GetOrganism()->GetPrevSeenCellID()) {
3088     ctx.GetOrganism()->SetPrevSeenCellID(ctx.GetOrganism()->GetCellID());
3089     return 1.0;
3090   }
3091 
3092   return 0.0;
3093 
3094 } //End cTaskLib::Task_Move()
3095 
3096 
Task_MoveToTarget(cTaskContext & ctx) const3097 double cTaskLib::Task_MoveToTarget(cTaskContext& ctx) const
3098 //Note - a generic version of this is now at - Task_MoveToMovementEvent
3099 {
3100   cOrganism* org = ctx.GetOrganism();
3101 
3102   if (org->GetCellID() == -1) return 0.0;
3103 
3104   cDeme* deme = org->GetDeme();
3105   assert(deme);
3106 
3107   int cell_data = org->GetCellData();
3108   if (cell_data <= 0) return 0.0;
3109 
3110   int current_cell = deme->GetRelativeCellID(org->GetCellID());
3111   int prev_target = deme->GetRelativeCellID(org->GetPrevTaskCellID());
3112 
3113   // If the organism is currently on a target cell, see which target cell it previously
3114   // visited.  Since we want them to move back and forth, only reward if we are on
3115   // a different target cell.
3116 
3117   if (cell_data > 1)
3118   {
3119     if (current_cell == prev_target) {
3120       // At some point, we may want to return a fraction
3121       return 0;
3122     } else {
3123       org->AddReachedTaskCell();
3124       org->SetPrevTaskCellID(current_cell);
3125       return 1.0;
3126     }
3127   }
3128 
3129   return 0;
3130 
3131 } //End cTaskLib::TaskMoveToTarget()
3132 
3133 
Task_MoveToMovementEvent(cTaskContext & ctx) const3134 double cTaskLib::Task_MoveToMovementEvent(cTaskContext& ctx) const
3135 {
3136   cOrganism* org = ctx.GetOrganism();
3137 
3138   if (org->GetCellID() == -1) return 0.0;
3139 
3140   cDeme* deme = org->GetDeme();
3141   assert(deme);
3142 
3143   int cell_data = org->GetCellData();
3144   if (cell_data <= 0) return 0.0;
3145 
3146   for (int i = 0; i < deme->GetNumMovementPredicates(); i++) {
3147     if (deme->GetMovPredicate(i)->GetEvent(0)->GetEventID() == cell_data) {
3148       org->AddReachedTaskCell();
3149       org->SetPrevTaskCellID(cell_data);
3150       return 1.0;
3151     }
3152   }
3153   return 0.0;
3154 }
3155 
3156 
Task_MoveBetweenMovementEvent(cTaskContext & ctx) const3157 double cTaskLib::Task_MoveBetweenMovementEvent(cTaskContext& ctx) const
3158 {
3159   cOrganism* org = ctx.GetOrganism();
3160 
3161   if (org->GetCellID() == -1) return 0.0;
3162 
3163   cDeme* deme = org->GetDeme();
3164   assert(deme);
3165 
3166   int cell_data = org->GetCellData();
3167 
3168   int prev_target = deme->GetRelativeCellID(org->GetPrevTaskCellID());
3169 
3170   // NOTE: as of now, orgs aren't rewarded if they touch a target more than
3171   //   once in a row.  Could be useful in the future to have fractional reward
3172   //   or something.
3173   if ( (cell_data <= 0) || (cell_data == prev_target) ) return 0.0;
3174 
3175   for (int i = 0; i < deme->GetNumMovementPredicates(); i++) {
3176     // NOTE: having problems with calling the GetNumEvents function for some reason.  FIXME
3177     //int num_events = deme.GetMovPredicate(i)->GetNumEvents;
3178     int num_events = 2;
3179 
3180     if (num_events == 1) {
3181       if ( (deme->GetMovPredicate(i)->GetEvent(0)->IsActive()) &&
3182           (deme->GetMovPredicate(i)->GetEvent(0)->GetEventID() == cell_data) ) {
3183         org->AddReachedTaskCell();
3184         org->SetPrevTaskCellID(cell_data);
3185         return 1.0;
3186       }
3187     } else {
3188       for (int j = 0; j < num_events; j++) {
3189         cDemeCellEvent* event = deme->GetMovPredicate(i)->GetEvent(j);
3190         if ( (event != NULL) && (event->IsActive()) && (event->GetEventID() == cell_data) ) {
3191           org->AddReachedTaskCell();
3192           org->SetPrevTaskCellID(cell_data);
3193           return 1.0;
3194         }
3195       }
3196     }
3197   }
3198   return 0.0;
3199 }
3200 
3201 
Task_MoveToEvent(cTaskContext & ctx) const3202 double cTaskLib::Task_MoveToEvent(cTaskContext& ctx) const
3203 {
3204   cOrganism* org = ctx.GetOrganism();
3205 
3206   if (org->GetCellID() == -1) return 0.0;
3207 
3208   cDeme* deme = org->GetDeme();
3209   assert(deme);
3210 
3211   int cell_data = org->GetCellData();
3212   if (cell_data <= 0) return 0.0;
3213 
3214   for (int i = 0; i < deme->GetNumEvents(); i++) {
3215     if (deme->GetCellEvent(i)->GetEventID() == cell_data) return 1.0;
3216   }
3217   return 0.0;
3218 }
3219 
3220 
Task_EventKilled(cTaskContext & ctx) const3221 double cTaskLib::Task_EventKilled(cTaskContext& ctx) const
3222 {
3223   if (ctx.GetOrganism()->GetEventKilled()) return 1.0;
3224   return 0.0;
3225 }
3226 
3227 
3228 
Load_SGPathTraversal(const cString & name,const cString & argstr,cEnvReqs & envreqs,Feedback & feedback)3229 void cTaskLib::Load_SGPathTraversal(const cString& name, const cString& argstr, cEnvReqs& envreqs, Feedback& feedback)
3230 {
3231   cArgSchema schema;
3232 
3233   // Integer Arguments
3234   schema.AddEntry("pathlen", 0, cArgSchema::SCHEMA_INT);
3235 
3236   // String Arguments
3237   schema.AddEntry("sgname", 0, cArgSchema::SCHEMA_STRING);
3238   schema.AddEntry("poison", 1, cArgSchema::SCHEMA_STRING);
3239 
3240   // Double Arguments
3241 //  schema.AddEntry("halflife", 0, cArgSchema::SCHEMA_DOUBLE);
3242 //  schema.AddEntry("base", 1, 2.0);
3243 
3244   cArgContainer* args = cArgContainer::Load(argstr, schema, feedback);
3245   if (args) NewTask(name, "State Grid Path Traversal", &cTaskLib::Task_SGPathTraversal, 0, args);
3246 }
3247 
3248 
Task_SGPathTraversal(cTaskContext & ctx) const3249 double cTaskLib::Task_SGPathTraversal(cTaskContext& ctx) const
3250 {
3251   const cArgContainer& args = ctx.GetTaskEntry()->GetArguments();
3252   const cStateGrid& sg = ctx.GetOrganism()->GetStateGrid();
3253 
3254   if (sg.GetName() != args.GetString(0)) return 0.0;
3255 
3256   int state = sg.GetStateID(args.GetString(1));
3257   if (state < 0) return 0.0;
3258 
3259   const tSmartArray<int>& ext_mem = ctx.GetExtendedMemory();
3260 
3261   // Build and sort history
3262   const int history_offset = 3 + sg.GetNumStates();
3263   tArray<int> history(ext_mem.GetSize() - history_offset);
3264   for (int i = 0; i < history.GetSize(); i++) history[i] = ext_mem[i + history_offset];
3265   tArrayUtils::QSort(history);
3266 
3267   // Calculate how many unique non-poison cells have been touched
3268   int traversed = 0;
3269   int last = -1;
3270   for (int i = 0; i < history.GetSize(); i++) {
3271     if (history[i] == last) continue;
3272     last = history[i];
3273     if (sg.GetStateAt(last) != state) traversed++;
3274   }
3275 
3276   traversed -= ext_mem[3 + state];
3277 
3278   double quality = 0.0;
3279 
3280 //  double halflife = -1.0 * fabs(args.GetDouble(0));
3281 //  quality = pow(args.GetDouble(1), (double)(args.GetInt(0) - ((traversed >= 0) ? traversed : 0)) / halflife);
3282   quality = (double)((traversed >= 0) ? traversed : 0) / (double)args.GetInt(0);
3283 
3284   return quality;
3285 }
3286 
3287 
3288 /* This task provides major points for perfect strings and some points for just
3289    storing stuff. */
Task_CreatePerfectStrings(cTaskContext & ctx) const3290 double cTaskLib::Task_CreatePerfectStrings(cTaskContext& ctx) const
3291 {
3292   double bonus = 0.0;
3293   int min = -1;
3294   int temp = 0;
3295   for (unsigned int i = 0; i<m_strings.size(); i++) {
3296     temp = ctx.GetOrganism()->GetNumberStringsOnHand(i);
3297 
3298     // Figure out what the minimum amount of a string is.
3299     if ((min == -1) || (temp < min)){
3300       min = temp;
3301     }
3302   }
3303 
3304   // Bonus for creating perfect strings!
3305   bonus = min;
3306 
3307   // Add in some value for just creating stuff
3308   for (unsigned int i = 0; i<m_strings.size(); i++) {
3309     temp = ctx.GetOrganism()->GetNumberStringsOnHand(i);
3310 
3311     if (temp > min) {
3312       bonus += (temp - min);
3313     }
3314   }
3315 
3316   // Update stats
3317   m_world->GetStats().IncPerfectMatch(min);
3318   if (min > 0) m_world->GetStats().IncPerfectMatchOrg();
3319 
3320   return bonus;
3321 }
3322 
3323 
Load_FormSpatialGroup(const cString & name,const cString & argstr,cEnvReqs & envreqs,Feedback & feedback)3324 void cTaskLib::Load_FormSpatialGroup(const cString& name, const cString& argstr,
3325 				     cEnvReqs& envreqs, Feedback& feedback)
3326 {
3327   cArgSchema schema;
3328 
3329   // Integer Arguments
3330   schema.AddEntry("group_size", 0, 1);
3331 
3332   cArgContainer* args = cArgContainer::Load(argstr, schema, feedback);
3333   if (args) NewTask(name, "FormSpatialGroups", &cTaskLib::Task_FormSpatialGroup, 0, args);
3334 }
3335 
3336 
Task_FormSpatialGroup(cTaskContext & ctx) const3337 double cTaskLib::Task_FormSpatialGroup(cTaskContext& ctx) const
3338 {
3339   double t = (double) ctx.GetTaskEntry()->GetArguments().GetInt(0);
3340   double reward = 0.0;
3341   int group_id = 0;
3342   if (ctx.GetOrganism()->HasOpinion()) {
3343     group_id = ctx.GetOrganism()->GetOpinion().first;
3344   }
3345   double g = (double) m_world->GetPopulation().NumberOfOrganismsInGroup(group_id);
3346   double num = (t-g) * (t-g);
3347   double denom = (t*t);
3348 
3349   reward = 1 - (num/denom);
3350   if (reward < 0) reward = 0;
3351   /*if (orgs_in_group < ideal_group_size) {
3352     reward = orgs_in_group*orgs_in_group;
3353     } else {
3354     reward = ideal_group_size*ideal_group_size;
3355     }
3356     reward = reward / ideal_group_size;*/
3357   return reward;
3358 }
3359 
3360 
3361 /* Reward organisms for having a given group-id, provided the group is under the
3362    max number of members. */
3363 
Load_FormSpatialGroupWithID(const cString & name,const cString & argstr,cEnvReqs & envreqs,Feedback & feedback)3364 void cTaskLib::Load_FormSpatialGroupWithID(const cString& name, const cString& argstr,
3365 					   cEnvReqs& envreqs, Feedback& feedback)
3366 {
3367   cArgSchema schema;
3368 
3369   // Integer Arguments
3370   schema.AddEntry("group_size", 0, 1);
3371   schema.AddEntry("group_id", 1, 1);
3372 
3373   cArgContainer* args = cArgContainer::Load(argstr, schema, feedback);
3374   if (args) NewTask(name, "FormSpatialGroupWithID", &cTaskLib::Task_FormSpatialGroupWithID, 0, args);
3375 
3376   // Add this group id to the list in the instructions file.
3377   m_world->GetEnvironment().AddGroupID(args->GetInt(1));
3378 }
3379 
3380 
Task_FormSpatialGroupWithID(cTaskContext & ctx) const3381 double cTaskLib::Task_FormSpatialGroupWithID(cTaskContext& ctx) const
3382 {
3383   double t = (double) ctx.GetTaskEntry()->GetArguments().GetInt(0);
3384   int des_group_id = ctx.GetTaskEntry()->GetArguments().GetInt(1);
3385 
3386   double reward = 0.0;
3387   int group_id = -1;
3388   if (ctx.GetOrganism()->HasOpinion()) {
3389     group_id = ctx.GetOrganism()->GetOpinion().first;
3390   }
3391 
3392   // If the organism is in the group...
3393   if (group_id == des_group_id) {
3394     double g = (double) m_world->GetPopulation().NumberOfOrganismsInGroup(group_id);
3395     // If the population size is less than the max size
3396     if (g < t) {
3397       reward = 1;
3398     } else {
3399       double num = (t-g) * (t-g);
3400       double denom = (t*t);
3401 
3402       if (denom > 0) {
3403 	reward = 1 - (num/denom);
3404 	if (reward < 0) reward = 0;
3405       } else {
3406 	reward = 0;
3407       }
3408     }
3409   }
3410 
3411   return reward;
3412 }
3413 
3414 /* Reward organisms for having a given group-id.*/
Load_LiveOnPatchRes(const cString & name,const cString & argstr,cEnvReqs & envreqs,Feedback & feedback)3415 void cTaskLib::Load_LiveOnPatchRes(const cString& name, const cString& argstr, cEnvReqs& envreqs, Feedback& feedback)
3416 {
3417   cArgSchema schema;
3418 
3419   schema.AddEntry("patch_id", 0, 1);
3420 
3421   cArgContainer* args = cArgContainer::Load(argstr, schema, feedback);
3422   if (args) NewTask(name, "LiveOnPatchRes", &cTaskLib::Task_LiveOnPatchRes, 0, args);
3423 
3424   // Add this patch id to the list in the instructions file.
3425   m_world->GetEnvironment().AddGroupID(args->GetInt(0));
3426 }
3427 
Task_LiveOnPatchRes(cTaskContext & ctx) const3428 double cTaskLib::Task_LiveOnPatchRes(cTaskContext& ctx) const
3429 {
3430   int des_patch_id = ctx.GetTaskEntry()->GetArguments().GetInt(0);
3431 
3432   double reward = 0.0;
3433   int patch_id = -1;
3434   if (ctx.GetOrganism()->HasOpinion()) {
3435     patch_id = ctx.GetOrganism()->GetOpinion().first;
3436   }
3437 
3438   // If the organism is in the group...
3439   if (patch_id == des_patch_id) {
3440     reward = 1;
3441   }
3442 
3443   return reward;
3444 }
3445 
3446 /* Reward organisms for having a given group-id.*/
Load_CollectOdds(const cString & name,const cString & argstr,cEnvReqs & envreqs,Feedback & feedback)3447 void cTaskLib::Load_CollectOdds(const cString& name, const cString& argstr, cEnvReqs& envreqs, Feedback& feedback)
3448 {
3449   cArgSchema schema;
3450 
3451   schema.AddEntry("even_or_odd", 0, 0);
3452 
3453   cArgContainer* args = cArgContainer::Load(argstr, schema, feedback);
3454   if (args) NewTask(name, "collect-odds", &cTaskLib::Task_CollectOdds, 0, args);
3455 
3456 }
3457 
Task_CollectOdds(cTaskContext & ctx) const3458 double cTaskLib::Task_CollectOdds(cTaskContext& ctx) const
3459 {
3460   int even_odds = ctx.GetTaskEntry()->GetArguments().GetInt(0);
3461 
3462   double reward = 0.0;
3463   // If the organism is in an odd cell...
3464   int cell_id_mod_2 = ctx.GetOrganism()->GetCellID()%2;
3465   if (even_odds == 0){
3466     if (cell_id_mod_2 != 0){
3467       reward = 1;
3468     }
3469   }
3470   else{
3471     if (cell_id_mod_2 ==0){
3472       reward = 1;
3473     }
3474   }
3475   return reward;
3476 }
3477 
3478 /* Reward organisms for having found a targeted resource*/
Load_ConsumeTarget(const cString & name,const cString & argstr,cEnvReqs & envreqs,Feedback & feedback)3479 void cTaskLib::Load_ConsumeTarget(const cString& name, const cString& argstr, cEnvReqs& envreqs, Feedback& feedback)
3480 {
3481   cArgSchema schema;
3482 
3483   schema.AddEntry("target_id", 0, 1);
3484   cArgContainer* args = cArgContainer::Load(argstr, schema, feedback);
3485   if (args) NewTask(name, "ConsumeTarget", &cTaskLib::Task_ConsumeTarget, 0, args);
3486 
3487   // Add this target id to the list in the instructions file.
3488   m_world->GetEnvironment().AddTargetID(args->GetInt(0));
3489 }
3490 
Task_ConsumeTarget(cTaskContext & ctx) const3491 double cTaskLib::Task_ConsumeTarget(cTaskContext& ctx) const
3492 {
3493   int des_target = ctx.GetTaskEntry()->GetArguments().GetInt(0);
3494 
3495   double reward = 0.0;
3496   int target_res = ctx.GetOrganism()->GetForageTarget();
3497 
3498   // If the organism is on the right resource...
3499   if (target_res == des_target) {
3500     reward = 1;
3501   }
3502   return reward;
3503 }
3504 
3505 
3506 
Load_AllOnes(const cString & name,const cString & argstr,cEnvReqs & envreqs,Feedback & feedback)3507 void cTaskLib::Load_AllOnes(const cString& name, const cString& argstr, cEnvReqs& envreqs, Feedback& feedback)
3508 {
3509   cArgSchema schema;
3510   schema.AddEntry("length", 0, 0);
3511   cArgContainer* args = cArgContainer::Load(argstr, schema, feedback);
3512   envreqs.SetMinOutputs(args->GetInt(0));
3513   if (args) NewTask(name, "all-ones", &cTaskLib::Task_AllOnes, 0, args);
3514 }
3515 
Task_AllOnes(cTaskContext & ctx) const3516 double cTaskLib::Task_AllOnes(cTaskContext& ctx) const
3517 {
3518   tBuffer<int> buf(ctx.GetOutputBuffer());
3519   double num_ones = 0.0;
3520   int length = ctx.GetTaskEntry()->GetArguments().GetInt(0);
3521 
3522   for (int i=0; i<length; ++i) {
3523     num_ones += buf[i];
3524   }
3525 
3526   return (num_ones/length);
3527 }
3528 
3529 
Load_RoyalRoad(const cString & name,const cString & argstr,cEnvReqs & envreqs,Feedback & feedback)3530 void cTaskLib::Load_RoyalRoad(const cString& name, const cString& argstr, cEnvReqs& envreqs, Feedback& feedback)
3531 {
3532   cArgSchema schema;
3533   schema.AddEntry("length", 0, 0);
3534   schema.AddEntry("block_count", 1, 0);
3535   cArgContainer* args = cArgContainer::Load(argstr, schema, feedback);
3536   envreqs.SetMinOutputs(args->GetInt(0));
3537   if (args) NewTask(name, "royal-road", &cTaskLib::Task_RoyalRoad, 0, args);
3538 }
3539 
Task_RoyalRoad(cTaskContext & ctx) const3540 double cTaskLib::Task_RoyalRoad(cTaskContext& ctx) const
3541 {
3542   // block size
3543   int length = ctx.GetTaskEntry()->GetArguments().GetInt(0);
3544   int block_count = ctx.GetTaskEntry()->GetArguments().GetInt(1);
3545   int block_size = floor(double(length) / double(block_count));
3546   int block_reward;
3547   int current_spot;
3548   double total_reward = 0.0;
3549   tBuffer<int> buf(ctx.GetOutputBuffer());
3550 
3551   // Cycle through each block. If a block is correct, then add a reward.
3552   for (int i=0; i<block_count; ++i) {
3553     block_reward = 1;
3554     // AND the elements of each block.
3555     for (int j=0; j<block_size; ++j) {
3556       current_spot = i*block_size + j;
3557       block_reward &= buf[current_spot];
3558     }
3559 
3560     //				if (block_reward) total_reward += (block_size);
3561     if (block_reward) total_reward ++;
3562   }
3563 
3564   return (total_reward/block_count);
3565 }
3566 
3567 
Load_RoyalRoadWithDitches(const cString & name,const cString & argstr,cEnvReqs & envreqs,Feedback & feedback)3568 void cTaskLib::Load_RoyalRoadWithDitches(const cString& name, const cString& argstr, cEnvReqs& envreqs, Feedback& feedback)
3569 {
3570   cArgSchema schema;
3571   schema.AddEntry("length", 0, 0);
3572   schema.AddEntry("block_count", 1, 0);
3573   schema.AddEntry("width", 2, 0);
3574   schema.AddEntry("height", 3, 0);
3575   cArgContainer* args = cArgContainer::Load(argstr, schema, feedback);
3576   envreqs.SetMinOutputs(args->GetInt(0));
3577   if (args) NewTask(name, "royal-road-wd", &cTaskLib::Task_RoyalRoadWithDitches, 0, args);
3578 }
3579 
3580 
Task_RoyalRoadWithDitches(cTaskContext & ctx) const3581 double cTaskLib::Task_RoyalRoadWithDitches(cTaskContext& ctx) const
3582 {
3583   // block size
3584   int length = ctx.GetTaskEntry()->GetArguments().GetInt(0);
3585   int block_count = ctx.GetTaskEntry()->GetArguments().GetInt(1);
3586   int block_size = floor(double(length) / double(block_count));
3587   int block_correct;
3588   int num_b_blocks = 0;
3589   int current_spot;
3590   double total_reward = 0.0;
3591   int width = ctx.GetTaskEntry()->GetArguments().GetInt(2);
3592   int height = ctx.GetTaskEntry()->GetArguments().GetInt(3);
3593   int next_case = 1;
3594   int block_type = -1; // -1 undefined; 0 X; 1 A; 2 B
3595   tBuffer<int> buf(ctx.GetOutputBuffer());
3596 
3597   // Cycle through each block. If a block is correct, then add a reward.
3598   for (int i=0; i<block_count; ++i) {
3599     block_correct = 1;
3600     block_type = -1;
3601 
3602 
3603     // Identify the type of block...
3604     // Check for block A
3605     for (int j=0; j<(block_size); ++j) {
3606       current_spot = i*block_size + j;
3607       block_correct &= buf[current_spot];
3608     }
3609 
3610     if (block_correct) block_type = 1;
3611 
3612     // Check for block B
3613     if (block_type == -1) {
3614       block_correct = 1;
3615       for (int j=0; j<block_size; ++j) {
3616 
3617 	current_spot = i*block_size + j;
3618 
3619 	// For starter's lets just check for blocks of type B
3620 	if (j < (block_size -width)) {
3621 	  if (buf[current_spot] == 0) block_correct = 0;
3622 	} else {
3623 	  if (buf[current_spot] == 1) block_correct = 0;
3624 	}
3625 	// this should escape the loop if the block reward is set to 0.
3626 	if (block_correct == 0) break;
3627       }
3628       if (block_correct) block_type = 2;
3629     }
3630 
3631     // Else consider it an X
3632     if (block_type == -1) block_type = 0;
3633 
3634     // Based on the type of block... change states....
3635     switch(next_case){
3636     case 1:
3637       if (block_type == 0) next_case = 2;
3638       if (block_type == 1) {
3639 	total_reward = num_b_blocks + 2;
3640 	next_case = 3;
3641       }
3642       if (block_type == 2) num_b_blocks++;
3643       break;
3644     case 2:
3645       if(block_type == 1) total_reward = num_b_blocks + 2 - height;
3646       next_case = 3;
3647       break;
3648     case 3:
3649       break;
3650     default:
3651       break;
3652     }
3653   }
3654 
3655   return (total_reward/block_count);
3656 }
3657 
3658 
3659 
3660 //! Load the command line for checking an opinion.
Load_OpinionIs(const cString & name,const cString & argstr,cEnvReqs & envreqs,Feedback & feedback)3661 void cTaskLib::Load_OpinionIs(const cString& name, const cString& argstr, cEnvReqs& envreqs, Feedback& feedback) {
3662   cArgSchema schema;
3663   schema.AddEntry("opinion", 0, cArgSchema::SCHEMA_INT);
3664   cArgContainer* args = cArgContainer::Load(argstr, schema, feedback);
3665   if(args) {
3666     NewTask(name, "Whether organism's opinion is set to value.", &cTaskLib::Task_OpinionIs, 0, args);
3667   }
3668 }
3669 
3670 //! This task is complete if this organism's current opinion is set to a configured value.
Task_OpinionIs(cTaskContext & ctx) const3671 double cTaskLib::Task_OpinionIs(cTaskContext& ctx) const
3672 {
3673   cOrganism* org = ctx.GetOrganism();
3674   const cArgContainer& args = ctx.GetTaskEntry()->GetArguments();
3675   int opinion = args.GetInt(0);
3676 
3677   if (org->HasOpinion()) {
3678     return org->GetOpinion().first == opinion;
3679   } else {
3680     return 0.0;
3681   }
3682 }
3683