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-10

第五回オフラインリアルタイムどう書く( http://atnd.org/events/32979 )。
問題は下記 URL。
http://nabetani.sakura.ne.jp/hena/ord5dahimi/
で。
当日その場で書いたもの。
コメントなど若干手直ししてあるが、ほぼそのまま。

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

int strength( char const * c )
{
    char rep = c[1];
    char m[]="3456789TJQKA2o";
    return strchr( m, rep ) - m;
}
int strengthm( char const * c )
{
    int jo = strength( "Jo");
    int cand = strength( c);
    if ( cand == jo ){
        return strength( c+2);
    } else {
        return cand;
    }
}

char const * dahi_1( char const * f, char const * inHand )
{
    int hc = strlen( inHand )/2;
    char const * ret=calloc( hc*3+3, 1 );
    int fs = strength( f );
    for( int h=0 ; h<hc ; ++h ){
        if ( fs < strength( inHand+h*2)){
            if ( *ret ){
                strcat( ret, ",");
            }
            strncat( ret, inHand+h*2, 2 );
        }
    }
    if ( *ret==0 ){
        strcat( ret, "-");
    }
    return ret;
}
int legal( char const * c )
{
    char const * end = c+strlen( c );
    int jo = strength( "Jo");
    int s=0;
    for( char const * p=c ; p<end ; p+=2 ){
        int sc=strength( p );
        if ( sc==jo ){
            continue;
        }
        if ( s==0 ){
            s=sc;
        } else {
            if ( s!=sc ){
                return 0;
            }
        }
    }
    return 1;
}
char const * dahi_2( char const * f, char const * inHand )
{
    int hc = strlen( inHand )/2;
    char cand[5]={0};
    char const * ret=calloc( hc*hc*3+9, 1 );
    int fs = strengthm( f );
    for( int h=0 ; h<hc ; ++h ){
        for( int h1=0 ; h1<h ; ++h1 ){
            memset( cand, 0, sizeof(cand) );
            strncat( cand, inHand+h*2, 2);
            strncat( cand, inHand+h1*2, 2);
            if ( legal( cand ) && fs < strengthm( cand )){
                if ( *ret ){
                    strcat( ret, ",");
                }
                strcat( ret, cand );
            }
        }
    }
    if ( *ret==0 ){
        strcat( ret, "-");
    }
    return ret;
}
char const * dahi_3( char const * f, char const * inHand )
{
    int hc = strlen( inHand )/2;
    char cand[7]={0};
    char const * ret=calloc( hc*hc*hc*7+9, 1 );
    int fs = strengthm( f );
    for( int h=0 ; h<hc ; ++h ){
        for( int h1=0 ; h1<h ; ++h1 ){
            for( int h2=0 ; h2<h1 ; ++h2 ){
                memset( cand, 0, sizeof(cand) );
                strncat( cand, inHand+h*2, 2);
                strncat( cand, inHand+h1*2, 2);
                strncat( cand, inHand+h2*2, 2);
                if ( legal( cand ) && fs < strengthm( cand )){
                    if ( *ret ){
                        strcat( ret, ",");
                    }
                    strcat( ret, cand );
                }
            }
        }
    }
    if ( *ret==0 ){
        strcat( ret, "-");
    }
    return ret;
}
char const * dahi_4( char const * f, char const * inHand )
{
    int hc = strlen( inHand )/2;
    char cand[9]={0};
    char const * ret=calloc( hc*hc*hc*hc*9+9, 1 );
    int fs = strengthm( f );
    for( int h=0 ; h<hc ; ++h ){
        for( int h1=0 ; h1<h ; ++h1 ){
            for( int h2=0 ; h2<h1 ; ++h2 ){
                for( int h3=0 ; h3<h2 ; ++h3 ){
                    memset( cand, 0, sizeof(cand) );
                    strncat( cand, inHand+h*2, 2);
                    strncat( cand, inHand+h1*2, 2);
                    strncat( cand, inHand+h2*2, 2);
                    strncat( cand, inHand+h3*2, 2);
                    if ( legal( cand ) && fs < strengthm( cand )){
                        if ( *ret ){
                            strcat( ret, ",");
                        }
                        strcat( ret, cand );
                    }
                }
            }
        }
    }
    if ( *ret==0 ){
        strcat( ret, "-");
    }
    return ret;
}
char const * solve( char const * in )
{
    char * f = strdup( in ); // TODO: memory leak!
    char * inHand = strchr( f, ',' )+1;
    inHand[-1]=0;

    int cardCount = strlen( f )/2;
    switch( cardCount ){
        case 1:
            return dahi_1( f, inHand );
        case 2:
            return dahi_2( f, inHand );
        case 3:
            return dahi_3( f, inHand );
        case 4:
            return dahi_4( f, inHand );
        default:
        return strdup("-");
    }
}
int is_same( char const * a, char const * b )
{
    // 不十分にも程があるが、時間の都合でこの程度で我慢した。
    return  strlen(a) == strlen(b);
}

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,", "-" );
    /*#2*/ test( "H7,HK", "HK" );
    /*#17*/ test( "JoC8,H6D7C5S9CQH9STDTCAD9S5DAS2CT", "CTDT,H9D9,S9D9,DACA,CTST,H9S9,DTST" );
    /*#22*/ test( "D8H8S8,CQHJCJJoHQ", "JoCQHQ,JoHJCJ" );
    /*#28*/ test( "H5C5S5D5,C7S6D6C3H7HAH6H4C6HQC9", "C6D6S6H6" );
    /*#32*/ test( "JoS8D8H8,S9DTH9CTD9STC9CAC2", "H9C9D9S9" );
    // テストの大半を省略
    return 0;
}

カードの枚数が可変であることに対しては再帰呼び出しで対応するのが筋だが、
制限時間内に確実に書けるものをということでコピペで増やした枚数固定の関数を4つ用意した。

無様でもいいからまず動くものを、ということで。

メモリリークはひどいと思うけど。

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?