// (c) 2007 Electronic Arts Inc.
#include <stdio.h>
#include <stdgimex.h>
#include <stdgimex.cpp>

int findthird(int i)
{
    int bestdiff = 255;
    int bestone,besttwo,bestval;
    int low=max(0,(i*31+128)/255-16);
    int high=min(31,(i*31+128)/255+16);
    for (int one5=low; one5<=high; ++one5)
    {
        int one = (one5*255+16)/31;
        for (int two5=low; two5<=high; ++two5)
        {
            int two = (two5*255+16)/31;
            int val = (one*1+two*2)/3;
            int diff = abs(val-i);
            if (diff<bestdiff)
            {
                bestdiff = diff;
                bestone = one;
                besttwo = two;
                bestval = val;
            }
        }
    }
    printf("1/3 %3d + 2/3 %3d = %3d, diff = %d,   ",bestone,besttwo,bestval,bestdiff);
    return bestval;
}

int findhalf(int i)
{
    int bestdiff = 255;
    int bestone,besttwo,bestval;
    int low=max(0,(i*31+128)/255-16);
    int high=min(31,(i*31+128)/255+16);
    for (int one5=low; one5<=high; ++one5)
    {
        int one = (one5*255+16)/31;
        for (int two5=low; two5<=high; ++two5)
        {
            int two = (two5*255+16)/31;
            int val = (one+two)/2;
            int diff = abs(val-i);
            if (diff<bestdiff)
            {
                bestdiff = diff;
                bestone = one;
                besttwo = two;
                bestval = val;
            }
        }
    }
    printf("1/2 %3d + 1/2 %3d = %3d, diff = %d,  ",bestone,besttwo,bestval,bestdiff);
    return bestval;
}

int findround(int i)
{
    int best5 = (i*31+128)/255;
    int bestval = (best5*255+16)/31;

    int bestdiff = abs(bestval-i);
    printf("round %3d, diff = %d, ",bestval,bestdiff);
    return bestval;
}

int main()
{
    int roundsum = 0, thirdsum=0, halfsum=0, bothsum=0;
    int roundzero = 0, thirdzero=0, halfzero=0, bothzero=0;
    for (int i=0; i<256; ++i)
    {
        printf("%3d: ",i);
        int round = findround(i);
        int third = findthird(i);
        int half =  findhalf(i);

        int rounddiff = abs(round-i);
        int thirddiff = abs(third-i);
        int halfdiff  = abs(half-i);
        int val=third;
        int diff = thirddiff;
        if (halfdiff<thirddiff)
        {
            val = half;
            diff = halfdiff;
        }
        roundsum += rounddiff;
        thirdsum += thirddiff;
        halfsum += halfdiff;
        bothsum += diff;

        if (rounddiff==0) ++roundzero;
        if (thirddiff==0) ++thirdzero;
        if ( halfdiff==0) ++halfzero;
        if (     diff==0) ++bothzero;

        printf("best %3d, diff = %d \n",val, diff);

    }
    printf("total rounddiff %d, thirddiff %d, halfdiff = %d, bothdiff = %d\n",roundsum,thirdsum,halfsum,bothsum);
    printf("levels round %d, third %d, half = %d, both = %d\n",roundzero,thirdzero,halfzero,bothzero);

    return 0;
}

