わたしのスキルで飯は食えるか? (短くしてみた)

makeplex salon:あなたのスキルで飯は食えるか? 史上最大のコーディングスキル判定 (1/2) - ITmedia エンタープライズ

はてなブックマークの1行に書けるように短くしてみた。100文字とあるけど半角なら300文字までいける。

x=256,y=65793;char*t,s[99];f(i,p,j,k){int*m=t=s+x+(k=i%x),*q
=s+p;s[p-1]=41,j=i/x-3,i>768?!j&*t>21-p|j>0&p>19&*t&t[j]?*q=
91+k*y-k+j*x,s[23]=93,puts(s+1):0:*m-(j=i<x?y:1-j)&y*8||(*m-=
j,*q=40+k*y*x+(i<x)*258*x,f(i>>9?768:i,p+5-i/512),*m+=j);i-x
*6&&f(i+1,p);}main(){for(t=gets(s);*t;s[x+*t++]++);f(0,1);}

これで、きっかり300バイト。七対子未対応。最後の1バイトを削るため配列の範囲外アクセスあり。まあ、たいてい動くでしょう。

x=256,      //  0x100
y=65793;    //  0x10101
char*t,
s[99];      //  0-255 入出力バッファ
            //  256- [i+256]にiの牌の個数を格納

//  0 <= i < 256
//      i,i+1,i+2の順子があるなら取り除く
//  256 <= i < 512
//      i,i,iの刻子があるなら取り除く
//  512 <= i < 768
//      i,iの頭があるなら取り除く
//  768 <= i < 1536
//      i%256,i%256+i/256-3が待ちになるなら出力
//
//  p: s+pに面子を出力
f(i,p,j,k)
{
    //  注目する牌の個数を指すポインタ
    //  int*とchar*でアクセスできるようにしておく
    int*m=t=s+x+(k=i%x),

    //  面子を出力するアドレス
    //  int*でアクセスできるようにしておく
    *q=s+p;

    //  s[p-1] = ')'
    s[p-1]=41,

    j=i/x-3,

    //  num = s + 256
    //  k = i%256
    //  j = i/256 - 3
    
    //  if ( i >= 768 )
    i>768?
        
        //  if ( j==0 && p==20 && num[k]==2  ||
        //       j==0 && p==21 && num[k]==1  ||
        //       j> 0 && p==20 && num[k]==1 && num[k+j]==1 )
        !j&*t>21-p|
        j>0&p>19&*t&t[j]?
            
            //  s[p  ] = '['
            //  s[p+1] = k + j
            //  s[p+2] = k
            //  s[23]  = ']'
            *q=91+k*y-k+j*x,s[23]=93,

            //  puts(s+1)
            puts(s+1):0

    //  else
    :
        //  if (           i<256 && num[k]>=1 && num[k+1]>=1 && num[k+2]>=1  ||
        //       256<=i && i<512 && num[k]>=3                                ||
        //       512<=i          && num[k]>=2 )
        *m-(j=i<x?y:1-j)&y*8||

            //  if (           i<256 )  num[k]--, num[k+1]--, num[k+2]--;
            //  if ( 256<=i && i<512 )  num[k] -= 3;
            //  if ( 512<=i          )  num[k] -= 2;
            (*m-=j,

            //  s[p  ] = '('
            //  s[p+1] = i<256 ? k+2 : k
            //  s[p+2] = i<256 ? k+1 : k
            //  s[p+3] = k
            *q=40+k*y*x+(i<x)*258*x,

            //  if ( i >= 512 )
            //      f( 768, p+4 )
            //  else
            //      f( i, p+5 )
            f(i>>9?768:i,p+5-i/512),

            //  if (           i<256 )  num[k]++, num[k+1]++, num[k+2]++;
            //  if ( 256<=i && i<512 )  num[k] += 3;
            //  if ( 512<=i          )  num[k] += 2;
            *m+=j);

    //  if ( i < 1536 )
    i-x*6&&

        //  f( i+1, p )
        f(i+1,p);
}

main()
{
    //  gets(s)
    //  for ( int i=0; s[i]; i++ )
    //      s[s[i]+256]++;
    for(t=gets(s);*t;s[x+*t++]++);

    //  f(0,1)
    f(0,1);
}

無駄な探索をできるだけしないための工夫とか、デバッグを効率化するための工夫なんて知りません。

>mahjong
1112224588899
(111)(222)(888)(99)[54]

>mahjong
1122335556799
(321)(321)(765)(55)[99]
(321)(321)(765)(99)[55]
(321)(321)(555)(99)[76]

>mahjong
1223344888999
(321)(432)(888)(999)[4]
(321)(888)(999)(44)[32]
(432)(432)(888)(999)[1]

>mahjong
1112345678999
(321)(654)(987)(11)[99]
(321)(654)(987)(99)[11]
(321)(654)(999)(11)[87]
(321)(876)(999)(11)[54]
(432)(765)(111)(999)[8]
(432)(765)(111)(99)[98]
(432)(876)(111)(999)[5]
(432)(987)(111)(99)[65]
(543)(876)(111)(999)[2]
(543)(876)(999)(11)[21]
(654)(987)(111)(99)[32]

>mahjong
1112223334479
(321)(321)(321)(44)[97]
(321)(432)(432)(11)[97]
(111)(222)(333)(44)[97]

>mahjong
aabbccddeeffg
(cba)(cba)(fed)(fed)[g]
(cba)(cba)(fed)(gfe)[d]
(cba)(cba)(gfe)(dd)[fe]
(cba)(dcb)(fed)(gfe)[a]
(dcb)(dcb)(gfe)(aa)[fe]
(dcb)(fed)(gfe)(aa)[cb]