Page 1 of 1

Save 3 characters off MicroMax

PostPosted: 15 Jul 2011, 20:02
by Kerwin
Since every character counts in umax, changing:

Code: Select all
(X-4)*(X-4)+(Y-3.5)*(Y-3.5))

to:
Code: Select all
X*X-8*X+16+Y*Y-7*Y+12.25

will take out 3 characters.

Re: Save 3 characters off MicroMax

PostPosted: 15 Jul 2011, 22:01
by H.G.Muller
Thanks!

In fact you saved me 12 characters!

For one, the +16 and +12.25 could be added together, as +28.25, and the .35 is rounded away anyway, as the result is assigned to an integer.

But in fact both constants can be dropped, as this expression is used to fill a table with centralization points for each square (X,Y), and will only be used for taking difference between two squares. So any added constant would cancel. 8-)

Re: Save 3 characters off MicroMax

PostPosted: 16 Jul 2011, 01:34
by Kerwin
Oh. Yeah. I did a quick conversion and forgot to combine all the constants.

Re: Save 3 characters off MicroMax

PostPosted: 16 Jul 2011, 02:11
by Kerwin
I just realized that you would be able to save another 10 characters by doing a #define on "if" the way you do with "while" and "for". "I" would be a good replacement. You just need to rename the current "I" to something like "P". I could also be done for "return", but you would only be saving 1 character.

Re: Save 3 characters off MicroMax

PostPosted: 16 Jul 2011, 02:18
by Kerwin
Kerwin wrote:I just realized that you would be able to save another 10 characters by doing a #define on "if" the way you do with "while" and "for". "I" would be a good replacement. You just need to rename the current "I" to something like "P". I could also be done for "return", but you would only be saving 1 character.


Actually, the savings would be more like 27 characters, if done like this:
#define I if(
instead of:
#define I if

but, the obfuscation factor rises dramatically.

Re: Save 3 characters off MicroMax

PostPosted: 16 Jul 2011, 21:26
by Edmund
another char by replacing
16777224 by
1<<24|8

4 chars by two times replacing
(x-2)&M by
x-2&M

Re: Save 3 characters off MicroMax

PostPosted: 17 Jul 2011, 06:51
by Kerwin
The character count for the following is 1031. If we could take out 7 more, we would be in the magical 1024.

Code: Select all
#define F(P,S,N) for(P=S;P<N;P++)
#define W(A) while(A)
#define I if(
#define R return

int V=112,M=136,P=8e3,C=799,X,Y,Q,N,
d[]={-16,-15,-17,0,1,16,0,1,16,15,17,0,14,18,31,33,0,
     1,1,3,-1,3,5,9,
     7,-1,11,6,8,3,6},
b[128]={6,3,5,7,4,5,3,6};

char n[]=".?pnkbrq?P?NKBRQ";

D(k,q,l,e,x,n)
int k,q,l,e,x,n;
{
 int i=0,j,t,p,u,r,y,m=n>1|q>e?q:e,v,h,z;

 N++;
 do{
  u=b[i];
  I u&k)
  {r=p=u&7;
   j=d[p+23];
   W(r=p>2&r<0?-r:-d[++j])
   {y=i;
    do
    {y+=r;I y&M)break;
     t=b[y];I t&k|p<3&!(r&7)-!t)break;
     v=99*d[t&7|16];
     I v<0)m=P;
     I m>=l)R m;
   
     I h=n-(y!=x))
     {I p<6)v+=b[i+8]-b[y+8];
      I p==4)v+=9*(e>C?!((x^y)&68):-3);

      b[i]=0;b[y]=u;
      I p<3)
      {v-=9*((i-2&M||b[i-2]!=u)+(i+2&M||b[i+2]!=u)-1);
       I y+r+1&128){b[y]|=7;v+=C;}
      }
      v=-D(24-k,-l,-m,z=-e-v,y,h);
      v-=v>P/3;
      I x==9){I v+P&&i==X&y==Y){Q=z;R l;}v=m;}
      b[i]=u;b[y]=t;
 
      I v>m){m=v;I x&8){X=i;Y=y;}}
     }
     t+=p<5;I p<3&&6*k+(y&V)==128)t--;
    }W(!t);
   }
  }
 }W(i=i+9&~M);
 R m+P?m:-D(24-k,-P,P,0,x,1)/2;
}

main()
{
 int k=8,*p,c[9],d;

 F(X,0,8)
 {b[X+V]=(b[X]+=16)-8;b[X+16]=18;b[X+96]=9;
  F(Y,0,8)b[16*Y+X+8]=X*X-8*X+Y*Y-7*Y;
 }

 W(1)
 {F(N,0,121)putchar(N&8&&(N+=7)?10:n[b[N]&15]);
  p=c;W((*p++=getchar())>10);
  I *c-10){X=*c-16*c[1]+C;Y=c[2]-16*c[3]+C;}else
  {d=6;N=0;W(N<1e6)D(k,-P,P,Q,8,d++);}
  I D(k,-P,P,Q,9,2)==P)k^=24;
 }
}

Re: Save 3 characters off MicroMax

PostPosted: 17 Jul 2011, 07:01
by Kerwin
OK. I think I found a few more characters to save. We are now down to 1020.

Code: Select all
#define F(P,S,N) for(P=S;P<N;P++)
#define W while(
#define I if(
#define R return

int V=112,M=136,P=8e3,C=799,X,Y,Q,N,
d[]={-16,-15,-17,0,1,16,0,1,16,15,17,0,14,18,31,33,0,
     1,1,3,-1,3,5,9,
     7,-1,11,6,8,3,6},
b[128]={6,3,5,7,4,5,3,6};

char n[]=".?pnkbrq?P?NKBRQ";

D(k,q,l,e,x,n)
int k,q,l,e,x,n;
{
 int i=0,j,t,p,u,r,y,m=n>1|q>e?q:e,v,h,z;

 N++;
 do{
  u=b[i];
  I u&k)
  {r=p=u&7;
   j=d[p+23];
   W r=p>2&r<0?-r:-d[++j])
   {y=i;
    do
    {y+=r;I y&M)break;
     t=b[y];I t&k|p<3&!(r&7)-!t)break;
     v=99*d[t&7|16];
     I v<0)m=P;
     I m>=l)R m;
   
     I h=n-(y!=x))
     {I p<6)v+=b[i+8]-b[y+8];
      I p==4)v+=9*(e>C?!((x^y)&68):-3);

      b[i]=0;b[y]=u;
      I p<3)
      {v-=9*((i-2&M||b[i-2]!=u)+(i+2&M||b[i+2]!=u)-1);
       I y+r+1&128){b[y]|=7;v+=C;}
      }
      v=-D(24-k,-l,-m,z=-e-v,y,h);
      v-=v>P/3;
      I x==9){I v+P&&i==X&y==Y){Q=z;R l;}v=m;}
      b[i]=u;b[y]=t;
 
      I v>m){m=v;I x&8){X=i;Y=y;}}
     }
     t+=p<5;I p<3&&6*k+(y&V)==128)t--;
    }W !t);
   }
  }
 }W i=i+9&~M);
 R m+P?m:-D(24-k,-P,P,0,x,1)/2;
}

main()
{
 int k=8,*p,c[9],d;

 F(X,0,8)
 {b[X+V]=(b[X]+=16)-8;b[X+16]=18;b[X+96]=9;
  F(Y,0,8)b[16*Y+X+8]=X*X-8*X+Y*Y-7*Y;
 }

 W 1)
 {F(N,0,121)putchar(N&8&&(N+=7)?10:n[b[N]&15]);
  p=c;W (*p++=getchar())>10);
  I *c-10){X=*c-16*c[1]+C;Y=c[2]-16*c[3]+C;}else
  {d=6;N=0;W N<1e6)D(k,-P,P,Q,8,d++);}
  I D(k,-P,P,Q,9,2)==P)k^=24;
 }
}

Re: Save 3 characters off MicroMax

PostPosted: 17 Jul 2011, 15:03
by marcelk
Code: Select all
int V=112,M=136,P=8e3,C=799,X,Y,Q,N,
I'm pretty sure that in C99 it is still allowed to leave out the 'int ' here,
making it an implicit type declaration and having 4 chars saved (same
as was already done with main).
Code: Select all
V=112,M=136,P=8e3,C=799,X,Y,Q,N,


The 'ints' can't be removed from the local variable declarations though, but they can
be removed from the function prototypes.
Code: Select all
D(k,q,l,e,x,n)
int k,q,l,e,x,n;
Actually, the whole prototype can go, saving 16:
Code: Select all
D(k,q,l,e,x,n)


While we're at it, this one looks wasteful:
Code: Select all
char n[]=".?pnkbrq?P?NKBRQ";
The array can be made implicitly, and n changed into a pointer,
which seems safe to me in this case:
Code: Select all
char *n=".?pnkbrq?P?NKBRQ";


Then we have the issue of main's locals:
Code: Select all
main()
{
 int k=8,*p,c[9],d;
Doing this costs 4 chars and is not needed. Just lump
them together with the other globals. 'd' then gets in a naming
conflict, so rename it into 'e'.
Code: Select all
V=112,M=136,P=8e3,C=799,X,Y,Q,N,
d[]={-16,-15,-17,0,1,16,0,1,16,15,17,0,14,18,31,33,0,
     1,1,3,-1,3,5,9,
     7,-1,11,6,8,3,6},
k=8,*p,c[9],e;
            ^
...
main()
...
  {e=6;N=0;W N<1e6)D(k,-P,P,Q,8,e++);}
   ^                            ^


So 25 off, we're well below 1000 now.

Re: Save 3 characters off MicroMax

PostPosted: 17 Jul 2011, 15:23
by marcelk
main gets arguments that micromax doesn't need: int argc and char **argv.
So it can use them for its own benefit instead, sparing some declaration overhead.

Code: Select all
main()
{
int k=8,*p,c[9],d;
Becomes
Code: Select all
main(d)
{
int k=8,*p,c[9];

Saving one char, the comma.

Re: Save 3 characters off MicroMax

PostPosted: 17 Jul 2011, 23:13
by Kerwin
I did Marcel's changes, and the character count is down to 997.

I then replaced this array:
d[]={-16,-15,-17,0,1,16,0,1,16,15,17,0,14,18,31,33,0,
1,1,3,-1,3,5,9,
7,-1,11,6,8,3,6},
with a string:
*d="$%#45D45DCE4BFSU4557379=;3?:<7:"

and did the corresponding adjustment to the usage of d.

We are now down to 961 characters.

Code: Select all
#define F(P,S,N) for(P=S;P<N;P++)
#define W while(
#define I if(
#define R return

V=112,M=136,P=8e3,C=799,X,Y,Q,N,s=16,
b[128]={6,3,5,7,4,5,3,6};

char *n=".?pnkbrq?P?NKBRQ",
*d="$%#45D45DCE4BFSU4557379=;3?:<7:";

D(k,q,l,e,x,n)
{
 int i=0,j,t,p,u,r,y,m=n>1|q>e?q:e,v,h,z;

 N++;
 do{
  u=b[i];
  I u&k)
  {r=p=u&7;
   j=d[p+23]-52;
   W r=p>2&r<0?-r:-d[++j]+52)
   {y=i;
    do
    {y+=r;I y&M)break;
     t=b[y];I t&k|p<3&!(r&7)-!t)break;
     v=99*(d[t&7|s]-52);
     I v<0)m=P;
     I m>=l)R m;
   
     I h=n-(y!=x))
     {I p<6)v+=b[i+8]-b[y+8];
      I p==4)v+=9*(e>C?!((x^y)&68):-3);

      b[i]=0;b[y]=u;
      I p<3)
      {v-=9*((i-2&M||b[i-2]!=u)+(i+2&M||b[i+2]!=u)-1);
       I y+r+1&128){b[y]|=7;v+=C;}
      }
      v=-D(24-k,-l,-m,z=-e-v,y,h);
      v-=v>P/3;
      I x==9){I v+P&&i==X&y==Y){Q=z;R l;}v=m;}
      b[i]=u;b[y]=t;
 
      I v>m){m=v;I x&8){X=i;Y=y;}}
     }
     t+=p<5;I p<3&&6*k+(y&V)==128)t--;
    }W !t);
   }
  }
 }W i=i+9&~M);
 R m+P?m:-D(24-k,-P,P,0,x,1)/2;
}

k=8,*p,c[9];

main(e)
{
 F(X,0,8)
 {b[X+V]=(b[X]+=s)-8;b[X+s]=18;b[X+96]=9;
  F(Y,0,8)b[s*Y+X+8]=X*X-8*X+Y*Y-7*Y;
 }

 W 1)
 {F(N,0,121)putchar(N&8&&(N+=7)?10:n[b[N]&15]);
  p=c;W (*p++=getchar())>10);
  I *c-10){X=*c-s*c[1]+C;Y=c[2]-s*c[3]+C;}else
  {e=6;N=0;W N<1e6)D(k,-P,P,Q,8,e++);}
  I D(k,-P,P,Q,9,2)==P)k^=24;
 }
}

Re: Save 3 characters off MicroMax

PostPosted: 18 Jul 2011, 00:18
by Adam Hair
At this rate, HG will have to change the name from µmax to nmax :)

Re: Save 3 characters off MicroMax

PostPosted: 18 Jul 2011, 00:41
by marcelk
Code: Select all
#define F(P,S,N) for(P=S;P<N;P++)
                ^
This space can go.
Code: Select all
#define F(P,S,N)for(P=S;P<N;P++)

But it seems that in the character counts thus far the
preprocessor stuff was excluded. I don't think that is
fair, because we can go down to 1 char that way.

Re: Save 3 characters off MicroMax

PostPosted: 25 Oct 2011, 23:29
by AmyJNelson
Kerwin wrote:Since every character counts in umax, changing:

Code: Select all
(X-4)*(X-4)+(Y-3.5)*(Y-3.5))

to:
Code: Select all
X*X-8*X+16+Y*Y-7*Y+12.25

will take out 3 characters.

Really Thanks!

On the one hand, 18and 10.25 could be added as 28.25, and 0.35 is rounded away anyway, the result is assigned to an integer.
But in fact, the two constants can be removed, as this term is used to fill a table with the focal point for each square (X, Y), and will only be used for making difference between two squares. So any added substance would be constant
business development