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