1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

第五回オフラインリアルタイムどう書くの回答例(C99 でもう一度)

Last updated at Posted at 2012-11-12

第五回オフラインリアルタイムどう書く( http://atnd.org/events/32979 )。
問題は下記 URL。
http://nabetani.sakura.ne.jp/hena/ord5dahimi/
で。
当日その場で書いたもの( http://qiita.com/items/6faf952a90659b736037 )があまりにもひどいので書きなおしたのがこれ。

// use "-std=c99"
# include <stdio.h>
# include <stdlib.h>
# include <memory.h>
# include <string.h>
# include <math.h>

char const ORDER[]="3456789TJQKA2o";
enum{  JOKER = 13 };
int strength( char const * card )
{
    return strchr( ORDER, card[1] ) - ORDER;
}
int compareByStrength(const void *va, const void *vb)
{
    char const * a=va;
    char const * b=vb;
    return strength(a) - strength(b);
}
char const * firstCard( int s, char const * cards )
{
    for( char const * p=cards ; *p ; p+=2 ){
        if ( s==strength(p) ){
            return p;
        }
    }
    return 0;
}
int population( size_t bits ){
    int r=0;
    for( int b=1 ; b<=64 ; b<<=1 ){
        r+=!!(bits&b);
    }
    return r;
}
void addAvailables( char * result, int s, int count, char const * cards, char const * postfix )
{
    char const * begin = firstCard( s, cards );
    if ( ! begin ){
        return;
    }
    char const * end=begin;
    for( ; *end && s==strength( end ) ; end+=2 );
    int sample = ( end-begin ) / 2;
    if ( sample<count ){
        return;
    }
    for( size_t bits=1 ; bits<(1<<sample) ; ++bits ){
        if ( count != population( bits )){
            continue;
        }
        if ( * result ){
            strcat( result, "," );
        }
        strcat( result, postfix );
        for( int i=0 ; i<sample ; ++i ){
            if ( bits & (1<<i) ){
                strncat( result, begin+i*2, 2 );
            }
        }
    }
}
char const * solve( char const * input )
{
    char * f = strdup( input );
    char * inHand = strchr( f, ',')+1;
    inHand[-1]=0;
    int nofCardsInHand = strlen( inHand ) / 2;
    int nofCardsInPlay = strlen( f )/2;
    char * result = calloc( pow( nofCardsInHand+1, nofCardsInPlay+1 ), nofCardsInHand*2+1 );
    qsort( f, strlen( f )/2, 2, compareByStrength );
    qsort( inHand, strlen( inHand )/2, 2, compareByStrength );
    int jokerAsWildcard = 1<nofCardsInPlay && firstCard( JOKER, inHand );
    for( int r=strength( f )+1 ; r<14 ; ++r ){
        addAvailables( result, r, nofCardsInPlay, inHand, "" );
        if ( jokerAsWildcard && r!=JOKER ){
            addAvailables( result, r, nofCardsInPlay-1, inHand, "Jo" );
        }
    }
    free( f );
    if ( !*result ){
        *result='-';
    }
    return result;
}
int compare(const void *a, const void *b)
{
    return *(char*)a - *(char*)b;
}
int is_same( char const * a, char const * b )
{
    // いい加減だけど、だいぶ正しい。
    size_t len = strlen(a);
    if ( len != strlen(b) ){
        return 0;
    }
    char * a1 = strdup(a);
    char * b1 = strdup(b);
    qsort(a1, len, 1, compare );
    qsort(b1, len, 1, compare );
    int r = 0==strcmp( a1, b1 );
    free( a1 );
    free( b1 );
    return r;
}

void test( char const * in, char const * expected )
{
    char const * ac = solve( in );
    if ( ! is_same( ac, expected) ){
        puts( "**FAIL**");
    }
    printf( " : %s\n    %s\n    %s\n", in, ac, expected );
    free( ac );
}

int main()
{
// テストデータは大半を省略。
/*#1*/ test( "DJ,", "-" );
/*#7*/ test( "ST,D6S8JoC7HQHAC2CK", "Jo,C2,CK,HA,HQ" );
/*#10*/ test( "Jo,HAC8DJSJDTH2", "-" );
/*#30*/ test( "D4H4S4C4,S6SAH6HAD6DAC6CAJo", 
/*#32*/ test( "JoS8D8H8,S9DTH9CTD9STC9CAC2", "H9C9D9S9" ); 
   return 0;
}

再帰呼び出しを bit 演算で回避した。
テストが成功したかどうかの判断はまだ不完全だが、C99 なら 対費用効果としてこのあたりが落としどころかと。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?