« 2.5インチHDDの可能性。 | トップページ | プログラムでチェックしよう! »

2006年2月12日 (日)

シャッフルするには…?

トランプを切って並べたら
番号がランダムに並ぶ…。

これを実現する処理を
作るにはどうしたら良いか?

ここでは、単純に0~9の数とするよん。

さて、最初のプログラムは、
ボケが、プログラムをやり始めた頃に
組んだボケボケプログラム。


どのぐらいボケかと言うと
殆ど期待通りに動かん…。

----------------------------------------
#include    <stdio.h>
#include    <stdlib.h>
#include    <memory.h>
int        card[10];
void shuffle( void )
{
    int        i;
    for( i = 0 ; i < 10 ; i++ )
        card[i]    = 10 * rand( ) / ( RAND_MAX + 1 );
}
int shuffle_check( void )
{
    int        i, list[10];
    memset( list, 0, sizeof( list ) );
    for( i = 0 ; i < 10 ; i++ )
        list[ card[i] ]++;
    for( i = 0 ; i < 10 ; i++ )
        if( list[i] != 1 )
            return 0;
    return 1;
}
void main( void )
{
    int        i;
    i    = -1;
    srand( 0 );    /*  毎回同じ結果を期待 */
    do
    {
        i++;
        shuffle( );
    } while( !shuffle_check( ) );
    printf( "error count %d!", i );
}
----------------------------------------

約7500回に1回、成立する…。
って、おいおい…!

よくよく考えてみると…。
・丸め誤差
・数値の制限(循環する)
から、まず成功しない…。

つまり、やり方が悪い!
と言う訳で直したのがこれ。

----------------------------------------
#include    <stdio.h>
#include    <stdlib.h>
#include    <memory.h>
int        card[10];
void shuffle( void )
{
    int        i, c, r;
    for( i = 0 ; i < 10 ; i++ )
        card[i]    = i;
    for( i = 0 ; i < 9 ; i++ )
    {
        r    = ( 10 - i ) * rand( ) / ( RAND_MAX + 1 );
        c    = card[i];
        card[i]    = card[r];
        card[r]    = c;
    }
}
int shuffle_check( void )
{
    int        i, list[10];
    memset( list, 0, sizeof( list ) );
    for( i = 0 ; i < 10 ; i++ )
        list[ card[i] ]++;
    for( i = 0 ; i < 10 ; i++ )
        if( list[i] != 1 )
            return 0;
    return 1;
}
void main( void )
{
    srand( 0 );    /*  毎回同じ結果を期待 */
    shuffle( );
    printf( shuffle_check( ) ? "good!" : "error!" );
}
----------------------------------------

見た通り、カードを切る様に
数値をランダムに入れ替えています。

この方法は、麻雀牌を混ぜたりするのに
使えるので覚えて損は、無いが…
ちょっと考えれば気が付くよね…。

|

« 2.5インチHDDの可能性。 | トップページ | プログラムでチェックしよう! »

コメント

コメントを書く



(ウェブ上には掲載しません)




トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/108365/8616813

この記事へのトラックバック一覧です: シャッフルするには…?:

« 2.5インチHDDの可能性。 | トップページ | プログラムでチェックしよう! »