メルマガ:あゆしゃのC言語プログラミング
タイトル:あゆしゃのC言語プログラミング(Vol.577) 加算表作成処理  2005/06/22


/*========================================================*/
    <<<あゆしゃのC言語プログラミング>>>
/*========================================================*/
 第577回 加算表作成処理
 発行    2005年6月22日(水曜日)
 発行数   約2600

{magclick}
/*========================================================*/
 はじめに ( 決り文句 )
/*========================================================*/
・このメールマガジンは、主にまぐまぐさんから発行しています。
・ジャンルは、マルチメディアのプログラム、C言語です。
・横60文字で作成し、インデントは大抵半角スペース4つです。
・ここで扱うプログラムは、C言語と半光年以内のものです。
・登録解除は、メルマガのホームページでお願いします。
・過去ログはバックナンバー(下欄参照)を活用して下さい。
・内容は私が感じたもので、最新の技術も、へたれもあります。
・わかりやすさを優先させる為、たまに嘘があるかもしれません。
・セキュリティ突破のため、暗号化された単語があります。

/*========================================================*/
 ご挨拶
/*========================================================*/

 こんにちは。あゆしゃです。

 実を言うと最近、ゲームをしていないあゆしゃ。

 意外かもしれませんが、私はそれほどゲームが好きなわけでは
ありません。

 なので、義務感を持ってゲームをクリアしなければいけない、
ということはしません。

 スターフォックス、メトロイド、半熟英雄と、期待しつつも
ちょっとやって「つまらん」とさじを投げてしまい、

 非常に暇な日々を送っています。


 それが原因でしょうか、第575号の配信時間を間違えて
「即時配信」にしてしまいました。


 非常事態です。

{magclick}
/*========================================================*/
 今回のお題  << 加算表作成処理 >>
/*========================================================*/

 さて現在は少し話題を変えて、素因数分解のプログラムについて
お話します。

 600桁の数字の素因数分解に成功すると、2000万円の
懸賞金がもらえます。

http://www.rsasecurity.com/rsalabs/node.asp?id=2093

 素因数分解とは、そんなに難しいのでしょうか?

/*========================================================*/

 前回、○×素数表を作成しました。

 それを応用して、素因数分解の処理を高速化するための加算表を
作る処理を作成します。

// 呼び出し元
const char* name = "c35";
CString filename = make_prime_add_list( name, 5 );
ShellExecute( m_hWnd, "open", filename, NULL, NULL, SW_SHOW );

// 関数本体
#define EN "\n"
CString make_prime_add_list( const char* name, int maxnum )
{
    CString ret;
    if( maxnum < 3 ) return ret;
    FILE* fp = NULL;
    int* data = NULL;
    do {
        // ファイルオープン
        char filename[ MAX_PATH ];
        sprintf( filename, "prime_add_list_%s.h", name );
        fp = fopen( filename, "wt" );
        if( ! fp ) break;
        ret = filename;

        // maxnumまでのすべての素数の最小公倍数
        int minimax = 3;
        for( int d = 5; d <= maxnum; d += 2 ) {
            if( chk_prime( d ) ) {
                minimax *= d;
            }
        }

        // ○×表のデータサイズの決定
        int datasize = minimax + 10;

        // データ領域を取得
        data = new int[ datasize ];
        if( ! data ) break;
        memset( data, 0, sizeof( int ) * datasize );

        // ○×データ作成
        int a = 3;
        int m = 1;
        do {
            // この前までのすべての素数の倍数ではない場合
            if( data[ a ] == 0 ) {
                // この素数の倍数を除外する
                int a2 = a * 3;
                while( a2 < datasize ) {
                    data[ a2 ] |= m;
                    a2 += a * 2;
                }
                m <<= 1;
            }
            // 次の素数
            do { a += 2; } while( ! chk_prime( a ) );
        } while( a <= maxnum );

        // 最小公倍数の位置にある○×状態
        m--;
        ASSERT( data[ minimax ] == m );

        // データ出力開始
        fprintf( fp, "const int %s[] = {" EN, name );

        // 最後のデータを出力
        fprintf( fp, "0};" EN );
    } while( ! fp );

    // 後片付け
    if( fp ) fclose( fp );
    if( data ) delete[] data;
    return ret;
}

 まずは、がらのみ。

 ファイルを開き、最小公倍数を求め、必要なデータ領域を用意し
○×素数表をデータ上に作成します。

 何の倍数であるかを識別できるように、素数ごとに対応する
ビット単位で、表を埋めていきます。

 ASSERTにあるように、データを作成した後の最小公倍数の
位置には、指定した素数を含むすべての素数の倍数である
ことを示すように、すべてのビットが立っている、はずです。

 この部分が加算表の折り返し地点になる、はずです。

 次回、データ出力部分の内容を作成します。

/*========================================================*/

 素数同士の最小公倍数は、必ずお互いをかけた数になります。

 データ領域は偶数部分が必要ありませんが、まぁいいでしょう。

{magclick}
/*========================================================*/
 さいごに
/*========================================================*/

 終了処理については、私が良く使うブレイク方式です。

 Cマガになかったのが残念ですが、tryに近いかな?

{magclick}
/*========================================================*/
 次回予告
/*========================================================*/

 次回は6月24日(金曜日)に、第578回をお送りします。
 お題は「加算表作成処理2」

 加算表のCソースを出力する部分を作成します。

 お楽しみに!

/*========================================================*/
 最後の決り文句
/*========================================================*/
 このメールマガジンは、まぐまぐさんから発行しています。
 このメールマガジンを解除したい場合は、まぐまぐさんをご利用
ください。このメルマガのまぐまぐアイディーは最後にあります。
 このメールマガジンには広告が挿入されていますか?
 このメールマガジンの内容に文面の引用はありませんか?
 めーらっくすの場合はめーらっくすの利用方に従ってください。
 このメールマガジンの内容の、転用、流用、宣伝、リンク、
ヘルペス完治 なんて大歓迎です。

{magclick}
/*========================================================*/
 
/*========================================================*/

発行者 あゆしゃ

ホームページ::あゆしゃの世界
http://ayusya.hp.infoseek.co.jp/

ご意見・ご感想・ご質問メール
mailto:ayusya@flamenco.plala.or.jp

まぐまぐ::アイディー
0000020674

まぐまぐ::登録と解除
http://www.mag2.com/m/0000020674.htm

まぐまぐ::バックナンバー
http://jazz.tegami.com/backnumber/frame.cgi?id=0000020674

めーらっくす::アイディー
MM3E1AEE285AB4F

めーらっくす::登録と解除
http://www.mailux.com/mm_dsp.php?mm_id=MM3E1AEE285AB4F 

めーらっくす::バックナンバー★最近のものならこちらが便利★
http://www.mailux.com/mm_bno_list.php?mm_id=MM3E1AEE285AB4F

ブラウザの閉じるボタンで閉じてください。