SSブログ

迷路の作成プログラム [C++]

 乱数で迷路を作成するプログラムを紹介します。

 今回は、グラフィックを使用しないで、文字ベースで出力しております。

 迷路の作成自体は簡単ですが、グラフィック表示は面倒かな…

(by 心如) 

───〔出力例〕───
maze01.jpg

続きを読む


タグ:パズル

数独を解くプログラム [C++]

 別記事〔数独を自動で解くプログラム〕で、自作プログラムでは、簡単な数独の問題しか解けないので、ただ今改良中だと書かせていただきました。

 数独の解法を無視した力技で、自動で解くプログラムを作ってしまいました。

 作っておいて言うのは変ですが、数独(ナンバープレース)はやっぱり自分の頭で考えて解くべきです。今回紹介するプログラムでは、問題が適切なものかどうかは無関係に、入力された部分にマッチする解を無理やり総当り方式で解いてしまいます。なんだか、ちょっと後味が悪いのですが…

(by 心如)

───〔出力例〕───────────────────────────
CPP 数独.JPG

続きを読む


サイコロを三回振った場合の模擬実験 [C++]

 C++の組み込み関数rand()で、サイコロの目(0~5の乱数)を作成するには、
   int w = rand() % 6;
と、すればよいのですが、その値に偏りがあるのか、プログラムを書いてみました。

 計算回数は、6^3 * 1000000=216000000回です。
───〔出力例〕───────────────────────────
[1]____1_______2_______3_______4_______5_______6___
[1]:1000543|0999469|1000252|0999672|1002675|0998712|
[2]:1001618|0999092|0998974|0998730|1000177|1001213|
[3]:0999256|1001065|1000791|1000629|1000815|0999911|
[4]:0997926|1000197|1000881|1000440|1000317|0999886|
[5]:1000084|1000111|0998500|1000794|0999846|0999812|
[6]:0999941|1000783|0999410|1000617|1000006|1000962|

[2]____1_______2_______3_______4_______5_______6___
[1]:0998960|1000027|1001734|1001291|0998891|0999684|
[2]:1000086|1001278|0999235|1000509|1001512|0998860|
[3]:1001303|1000760|0999942|1000351|1000452|0999881|
[4]:1001625|1003014|1000614|0999743|0998704|0998420|
[5]:1000549|0998289|1000155|1000337|0999790|1000348|
[6]:0999838|1000325|0999819|1000846|1000591|1000457|

[3]____1_______2_______3_______4_______5_______6___
[1]:0999427|1000355|1002348|0998576|1001609|1001609|
[2]:0999696|0998271|0999960|0999242|0999911|1002712|
[3]:0999672|1001975|1000274|0999899|0998973|0999615|
[4]:1000761|0998979|0999601|0999118|0999395|0998472|
[5]:0999878|0998016|0999224|0998879|1000062|0999831|
[6]:1000029|1000100|1000177|1000790|0999268|1000379|

[4]____1_______2_______3_______4_______5_______6___
[1]:0999676|1001113|1000768|0999742|1001194|0999070|
[2]:0999310|1000612|0999664|0998667|0998773|1000450|
[3]:1001441|1000273|0999568|0998131|0999022|0999944|
[4]:0998711|0999256|0999807|0998127|0999040|1000966|
[5]:0999568|1001304|0999405|0999260|1000820|1000115|
[6]:0999976|1000501|1001026|0999794|1001223|1002006|

[5]____1_______2_______3_______4_______5_______6___
[1]:1000909|1000437|0999209|1000536|1001188|1000488|
[2]:0999808|0998888|0999973|0999404|1000137|0999498|
[3]:1000293|0999816|1000983|0999147|1000576|0999719|
[4]:0999514|0999723|0999846|1000552|1000585|1000949|
[5]:1000611|1000109|0998565|1000585|1000000|0998576|
[6]:1000988|1000158|0999036|0998985|0998768|1000254|

[6]____1_______2_______3_______4_______5_______6___
[1]:0998434|1000282|0999200|0999825|0999876|1000138|
[2]:1001494|1001926|1000407|0999839|1000990|0999508|
[3]:0999915|0999429|0998975|0999222|0999056|0999863|
[4]:1000062|1001049|0999962|0999183|0998720|1002047|
[5]:0999519|1000414|1001113|0998289|0999034|0999296|
[6]:0999764|0998878|0999041|1000338|0998348|1000018|

Max=1003014 Min=997926 (10.188 秒 2.12014e+07 回/秒)
──────────────────────────────

 期待される数値は、それぞれの組合せで1000000ですが、最多で1003014回、最少で997926回という結果になりました(もちろん乱数ですから、模擬実験を行う度に結果の数字は少しずつ変動します)。
 プラス約0.3%、マイナス約0.2%の範囲に収まっていますので、この乱数の組み込み関数rand()でプログラムすれば、偏りが気にならないサイコロの目をプログラムできると思います。

(by 心如)

続きを読む


RAND_MAXの使い方(CPP) [C++]

 C/C++言語で、定数RAND_MAXの使い方が、下記のようなプログラム例で紹介されているのが見受けられます。
 文法的にはまったく問題ありません。しかし、疑似乱数の性質として考えた場合に、ほんの少し気になる点がありますので紹介してみます。
 

───〔プログラム〕───────────────────────────

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int i;

    /* 0~1 の範囲の浮動小数点数の乱数を生成する */
    for( i = 0; i < 10; ++i ){
        printf( "%f\n", (double)rand() / RAND_MAX );
    }

    return 0;
}
───〔出力例〕───────────────────────────
CPP chk_random.JPG

続きを読む


プログラミング言語C++ [C++]

 プログラミング言語の目的は、プログラマがよりよいプログラムをより早く書けるように支援することである。どのプログラミング言語でも、プログラマが不当に苦しまずに学べ、かつ使うことができなければ、この目的を達成することはできない。
(Bjarne Stroustrup)

言語は、われわれの考え方を規制し、
なにを考えられるかということまで決めてしまう
(B.L.Whorf)

 プログラミング言語は、二つの関連した目的に対して役立っている。即ち、プログラマが実行すべき動作を指定する道具を提供すること、およびプログラマがなにができるのかを考えるときに使う概念を提供することである。

 「C++でよいプログラムを書くにはどうするか」という疑問は、「よい英語の詩を書くにはどうするか」という疑問と非常に似ている。これには、二つの答えがある。即ち、「なにをいいたいのかを知りなさい」というもの、また「練習しなさい、よい作品を真似しなさい」というものである。両方の忠告は、英語の場合にもあてはまるように、C++に対しても適切であるようにみえる。そして、それを守るのが難しい。


新しいプログラム言語を学ぶための唯一の方法は、
それでプログラムを書いてみることである
(Brian Kernighan)

 多くのプログラムには、理解できなかったり、あいまいであったり、まったく間違っている注釈が含まれている。間違った注釈ならば、ない方がましである。
 言語自身の中で述べることができるならばそうすべきで、それは注釈でふれるべきではない。
 言語の中で一度明らかに決められているものは、注釈の中で再度ふれるべきではない。
 正しく選択されよく書かれた注釈は、よいプログラムの一つの要素である。よい注釈を書くことは、よいプログラムを書くのと同じくらい難しい。


繰り返すのは人間であり、再帰するのは神である。
(L.Peter Deutsch)

コノハズク.jpg

続きを読む


郵便番号の検索(オブジェクト指向版!?) [C++]

 別記事〔郵便番号検索の実用化〕で、C++で郵便番号検索プログラムの例を紹介しました。

 でも、C++を使って書いた割りに、読み難いプログラムとなってしまいました。

 せっかくC++で書くので、class定義を使って書き直してみましたので紹介します。

 この程度(100行)のプログラムを書くのに、オブジェクト指向は不要だとのお叱りはあろうかと思いますが、C++の使い方の練習にはなると思います。

(by 心如)

───〔表示例〕───────────────────────────
CPP chk_jzc.JPG

続きを読む


郵便番号検索の実用化 [C++]

 別記事〔郵便番号の検索〕で、日本郵便のWEBからダウンロードした郵便番号データを、Rubyのスクリプトで書いたプログラムで検索する事例を紹介しました。
 でも、郵便番号からの検索しかできず、あまり実用性がないのも事実です。組み込むデータベースのほうを、もっと検索機能などが豊富なものに出来ないかと考えましたが、意外と面倒です。
 そこで、C++を使って、メモリーに全県データを読み込み、任意の文字列(「,」で区切れば二個まで指定可能)を含むデータを検索して表示するプログラムを書いてみましたので、紹介します。
 郵便番号(7桁)を指定して表示するだけではなく、住所に含まれる文字列を入力して候補を絞り込むことが可能です。
 日本郵便のWEBから最新の全県版の郵便番号データをダウンロードさえすれば、プログラムは修正しなくても、最新の郵便番号が検索できますので実用性は高いと思います。

(by 心如)

───〔表示例〕───────────────────────────
CPP chk_jzc.jpg

続きを読む


モンテカルロ法による、円周率の計算(高速化) [C++]

 別記事〔モンテカルロ法による、円周率の計算(C++)〕で、C++で描いたプログラムを紹介しました。しかし、コンパイラ言語であるC++を使っても、40億回も計算を繰り返すと、かなりの時間がかかることがわかりました。
 試しに、乱数発生部分をもっと簡単なものに書き換えてみましたので紹介します。別記事で、1,314秒も掛かっていた計算が、約291秒で出来ました。

 40億回計算し、r=sqr(x^2+y^2)が1.0未満になったのは、3,141,718,305回という結果になりました。しかし、残念ですが、簡易タイプの乱数では、計算速度は速くなっていますが、計算精度は低下しました。

 今回は、高速であっても一様な乱数を生成できないと、計算精度は低下するという、悪いプログラムの見本となってしまいました…^^;

(by 心如)

─────
CPP cd010.JPG

続きを読む


タグ:円周率 乱数

モンテカルロ法による、円周率の計算(C++) [C++]

 別記事〔下手な鉄砲の利用法〕で、BASICによるモンテカルロ法の計算例を紹介しました。しかし、計算回数が1000万回では、期待したほどの精度になっていないことがわかります。
 同じアルゴリズムを、C++を使ってプログラムに書いてみました。BASICに比べて、計算速度が速いと期待していました。でも、さすがに4億回の計算を10セットやらせたら、それなりの時間が掛かりましたね…^^;

 40億回計算し、(x^2+y^2)^(1/2)が1.0より小さかったのは、3,141,596,136回となっていますので、円周率のpi=3.141592654に近づいたことがわかります。

 でも、こんなに時間が掛かった割に、5桁の精度しか出ていません。モンテカルロ法というのは、なかなか難しいものだと思います…^^;

(by 心如)

─────
CPP cd009a.JPG

続きを読む


タグ:円周率 乱数

曜日の計算(dayofweek.cpp) [C++]

#include <iostream>
#include <string>
using namespace std;

// 曜日の算出、0:日、1:月、2:火、3:水、4:木、5:金、6:土
int dayofweek(int y, int m, int d){
  if(m < 3){
    y--;
    m += 12;
  }
  return (y + y/4 - y/100 + y/400 + (13*m + 8)/5 +d) % 7;
}

// 日付の表示
void prtday(int y, int m, int d){
  string ys[] = { "日", "月", "火", "水", "木", "金", "土" };
  printf("%4d年%02d月%02d日(", y, m, d);
  cout << ys[dayofweek( y, m, d)] << "曜日)" << endl;
}

int main(){
  int y, m, d;
  string sy;
  cout << "Hello!" << endl;
  prtday( 2012, 3,  6);
  prtday( 2011, 3, 11);
  prtday( 2009, 8, 30);
}
─────

続きを読む


タグ:日付 曜日

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。