Type programming game
Stefan Koch
uplink.coder at googlemail.com
Sun Oct 11 10:46:00 UTC 2020
On Sunday, 11 October 2020 at 09:31:43 UTC, Basile B. wrote:
> On Saturday, 10 October 2020 at 23:42:46 UTC, Stefan Koch wrote:
>> Hi,
>>
>> just now I came up with a nice game.
>>
>> Write a template/function takes a sequence of types, and
>> "returns" a string.
>> Whenever the same type appears twice in the sequence directly
>> after the previous occurrence,
>> append ("double " ~ name_of_type) to the string.
>> Whenever it appears three times, append ("triple " ~
>> name_of_type).
>>
>> So (int, int, uint, uint, uint) would return "double int
>> triple uint")
>> Or (char, char, wchar, dchar, dchar) would return "double char
>> double dchar"
>>
>> I am looking forward to what you come up with.
>>
>> After a few submissions have been made I will post my type
>> function, which fulfills this task.
>>
>> Have a good day,
>>
>> Stefan
>
> fully CTFE + using a map to solve uniquness. Naive, longish,
> but easy to understand I'd say as self-criticism... but I
> suppose that the final goal of this game is to show us an
> astonishing TF solution ;)
>
> ---
> import std.algorithm;
>
> string solveByMapping(T...)()
> {
> string[] uniques;
> size_t[] indexes;
> size_t[] count;
> string result;
>
> static foreach (TT; T)
> {
> if (!uniques.canFind(TT.stringof))
> uniques ~= TT.stringof;
> indexes ~= uniques.length - 1;
> }
> count.length = uniques.length;
> static foreach (i, TT; T)
> {
> count[indexes[i]] += 1;
> }
> foreach(ref c; count)
> {
> if (c != 2 && c != 3)
> c = 0;
> }
> foreach(i, c; count)
> {
> if (!c)
> continue;
> result ~= (c == 3) ? " triple " : " twice ";
> result ~= uniques[i];
> }
> return result[1..$];
> }
>
> static assert (solveByMapping!(int, int, uint, uint, uint) ==
> "twice int triple uint");
> static assert (solveByMapping!(int, int, uint) == "twice int");
> static assert (solveByMapping!(float, float, int, int, uint) ==
> "twice float twice int");
> ---
Thanks for attending the game!
And you are right the type function version which works now looks
like this.
It should not be astonishing ;)
---
alias type = __type;
string double_triple(type[] types...)
{
string result;
type current;
uint count;
foreach(i, t;types)
{
if (is(current == t))
{
count++;
// if the last one didn't change we need to eval the
count
if (i == types.length - 1)
goto Leval_count;
}
else
{
Leval_count:
if (count == 2)
{
result ~= "double " ~ __traits(identifier,
current) ~ " ";
}
else if (count == 3)
{
result ~= "triple " ~ __traits(identifier,
current) ~ " ";
}
current = t;
count = 1;
}
}
return result[0 .. $-1];
}
static assert(double_triple(int,int,uint,uint,uint) == "double
int triple uint");
static assert(double_triple(char,char,wchar,dchar,dchar) ==
"double char double dchar");
static assert(double_triple(double, double, float, float, float)
== "double double triple float");
---
In continuation I will post benchmarks of all 4 (or more of
others come in) solutions on longer type sequences.
More information about the Digitalmars-d
mailing list