|
IsmAvatar
|
|
Reply #1 Posted on: July 03, 2011, 04:36:24 pm |
|
|
LateralGM Developer
Location: Pennsylvania/USA Joined: Apr 2008
Posts: 877
|
pigeonhole each of the options, then choose one with random(n). This is a simple but somewhat inefficient way to do it.
A more efficient way to do it would be the same way we plan on implementing max, which also isn't implemented at this point.
max(a) = a max(a,b) = a > b ? a : b; max(a,b,c) = max(a,max(b,c)); max(a,b,c,d) = max(a,max(b,max(c,d)))
likewise, instead of doing the > comparator for the secondary base case, you'd simply do a random() > 0.5 type of thing.
|
|
|
Logged
|
|
|
|
fredcobain
|
|
Reply #2 Posted on: July 03, 2011, 04:59:37 pm |
|
|
Location: Brazil Joined: Apr 2011
Posts: 40
|
pigeonhole each of the options, then choose one with random(n). This is a simple but somewhat inefficient way to do it.
A more efficient way to do it would be the same way we plan on implementing max, which also isn't implemented at this point.
max(a) = a max(a,b) = a > b ? a : b; max(a,b,c) = max(a,max(b,c)); max(a,b,c,d) = max(a,max(b,max(c,d)))
likewise, instead of doing the > comparator for the secondary base case, you'd simply do a random() > 0.5 type of thing.
mmm... interesting... does the function s round() and random() are is implemented in enigma (built in) ?
|
|
|
Logged
|
|
|
|
Josh @ Dreamland
|
|
Reply #3 Posted on: July 03, 2011, 05:13:10 pm |
|
|
Prince of all Goldfish
Location: Pittsburgh, PA, USA Joined: Feb 2008
Posts: 2950
|
ENIGMA will have one shortly. I need to make modifications to the syntax checker to allow functions to accept enigma::varargs.
|
|
|
Logged
|
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble "I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
|
|
|
RetroX
|
|
Reply #4 Posted on: July 04, 2011, 11:53:55 am |
|
|
Master of all things Linux
Location: US Joined: Apr 2008
Posts: 1055
|
pigeonhole each of the options, then choose one with random(n). This is a simple but somewhat inefficient way to do it.
A more efficient way to do it would be the same way we plan on implementing max, which also isn't implemented at this point.
max(a) = a max(a,b) = a > b ? a : b; max(a,b,c) = max(a,max(b,c)); max(a,b,c,d) = max(a,max(b,max(c,d)))
likewise, instead of doing the > comparator for the secondary base case, you'd simply do a random() > 0.5 type of thing.
I don't get how this is more efficient.
|
|
|
Logged
|
My Box: Phenom II 3.4GHz X4 | ASUS ATI RadeonHD 5770, 1GB GDDR5 RAM | 1x4GB DDR3 SRAM | Arch Linux, x86_64 (Cube) / Windows 7 x64 (Blob)Why do all the pro-Microsoft people have troll avatars?
|
|
|
|
TheExDeus
|
|
Reply #6 Posted on: July 08, 2011, 10:25:03 am |
|
|
Joined: Apr 2008
Posts: 1860
|
Why can't we use stdarg.h? Is this nested max() is really better than this: double max(int n, ...){ double max, tmp; va_list ap; va_start(ap, n); max = va_arg(ap, double); for(int i = 2; i <= n_args; i++) { if((tmp = va_arg(ap, double)) > max) max = tmp; } va_end(ap); return max; } edit: Didn't see this: ENIGMA will have one shortly. I need to make modifications to the syntax checker to allow functions to accept enigma::varargs. And whats the difference exactly between this and stdarg.h provided functionality? I guess its that Josh's thing uses variants, so I don't need to cast to double or something. So max like this: max(int 5, double 3.14) would return integer, while this: max(int 5, double 6) would return a double. Using the simple stdarg would only return doubles or integers. edit: Also, if doesn't really do what I think it does, then can we finally implement them with stdarg? Its like 10min of work to implement max, min, average, median and so on. Thous are some basic functions I really need.
|
|
« Last Edit: July 08, 2011, 10:31:45 am by HaRRiKiRi »
|
Logged
|
|
|
|
Josh @ Dreamland
|
|
Reply #7 Posted on: July 08, 2011, 11:39:23 am |
|
|
Prince of all Goldfish
Location: Pittsburgh, PA, USA Joined: Feb 2008
Posts: 2950
|
For starters, HaRRi, stdargs.h will kill the program if you pass it a var or a variant. Also, good luck getting the argument count.
|
|
|
Logged
|
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble "I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
|
|
|
TheExDeus
|
|
Reply #8 Posted on: July 08, 2011, 02:14:12 pm |
|
|
Joined: Apr 2008
Posts: 1860
|
stdargs.h will kill the program if you pass it a var or a variant. Yeah, that is what I meant. Also, good luck getting the argument count. Indeed, though if you made compiler parse this: max(10,25,34.2); into this: max(4,10,25,34.2); where the first argument is the argument number, then stdargs.h could be used. You already parse that string into this: max(varargs(), (varargs(), 10, 25, 34.2)); , so it seems that you can do it (and arguments are counted anyway for error reporting purposes, but I guess GCC is the one that does it). Also, it seems that you have implemented the max function, but its chaotic in that definitions in mathc.h and .cpp are not used, but required. So if I delete max(double x,double y){ return fmax(x,y); }, I will get an error, while the function itself isn't called. Also, it will take only 3 arguments if its written like that. I still need to change it into: double max(double numbers, ...){} to take any number of arguments and still work. edit: Also, if max(10,25,34.2) is called then it will return 34, not 34.2. edit2: And I would want to study your method on how you implemented max, so I can add median and others. edit3: Also, if it seems I'm just mumbling then ignore me. I'm in a habit of not explaining myself clearly.
|
|
« Last Edit: July 08, 2011, 04:23:56 pm by HaRRiKiRi »
|
Logged
|
|
|
|
Josh @ Dreamland
|
|
Reply #9 Posted on: July 08, 2011, 02:27:42 pm |
|
|
Prince of all Goldfish
Location: Pittsburgh, PA, USA Joined: Feb 2008
Posts: 2950
|
max(varargs(), (varargs(), 10, 25, 34.2)); is incorrect; the string should come out as max((varargs(), 10, 25, 34.2));
But I don't parse that. #define max(x...) max((varargs(),x))
and #define won't give me the number of arguments passed.
Again, double max(double numbers, ...){} won't work. It will kill the program as soon as the user calls max(somevar,someothervar). That wasn't a joke. It's possible that C++0x offers a functionality to overload an stdargs pass, but I don't know how well it is supported.
|
|
|
Logged
|
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble "I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
|
|
|
TheExDeus
|
|
Reply #10 Posted on: July 08, 2011, 03:10:15 pm |
|
|
Joined: Apr 2008
Posts: 1860
|
is incorrect; the string should come out as It still works though. Again, double max(double numbers, ...){} won't work. That was actually the whole working code. I have this in mathnc.h: double max(double n, ...); And this in mathnc.cpp: #include "stdarg.h" double max(double n, ...){} So nothing inside the function. And when I do this in EDL: draw_text(100,100,string(max(12,329,21,343,1000,2981))); It correctly draws 2981. And IDE_EDIT_objectfunctionality.h has it parsed like this: draw_text(100, 100, toString(max(varargs(), (varargs(), 12, 329, 21, 343, 1000, 2981)))); That is why its weird. I don't have any code inside that would actually do the comparing, but it still works. On the other hand if I deleted the code from mathnc.cpp it would trow an error saying that the function max is undefined.
|
|
« Last Edit: July 08, 2011, 04:24:08 pm by HaRRiKiRi »
|
Logged
|
|
|
|
Josh @ Dreamland
|
|
Reply #11 Posted on: July 08, 2011, 03:16:40 pm |
|
|
Prince of all Goldfish
Location: Pittsburgh, PA, USA Joined: Feb 2008
Posts: 2950
|
Ah; you've stumbled on a way to make ENIGMA honor max() having unlimited parameters. That's... typically kind of dangerous, but I guess it's as good a hack as any. For the time being, you can implement those functions like this: variant choose(...); int choose(const enigma::varargs& args) { return args.get(rand() % args.argc); } #define choose(x...) choose((varargs(), x))
You must declare and implement choose before defining it. In the source, you may be wise to #undef choose, then implement it. DO NOT implement choose(...); it's too segfault-prone. This way, worst-case scenario is link error, not random abort().
|
|
« Last Edit: July 08, 2011, 03:23:51 pm by Josh @ Dreamland »
|
Logged
|
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble "I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
|
|
|
RetroX
|
|
Reply #12 Posted on: July 08, 2011, 09:03:13 pm |
|
|
Master of all things Linux
Location: US Joined: Apr 2008
Posts: 1055
|
It is possible to do choose() with variadic templates, but probably not very efficiently:
template<typename... types> double choose(types... vals) { return choose_impl(random(sizeof...(vals)), vals...); }
template<typename... types> double choose_impl(unsigned counter, double head, types... vals) { return counter == 0 ? head : choose_impl(counter - 1, vals...); } Untested, but should work. And requires the -std=gnu++0x flag. Also will give very odd errors if you have arguments that can't cast to double.
|
|
« Last Edit: July 08, 2011, 09:05:15 pm by RetroX »
|
Logged
|
My Box: Phenom II 3.4GHz X4 | ASUS ATI RadeonHD 5770, 1GB GDDR5 RAM | 1x4GB DDR3 SRAM | Arch Linux, x86_64 (Cube) / Windows 7 x64 (Blob)Why do all the pro-Microsoft people have troll avatars?
|
|
|
|
|