ロト7の番号を作成するプログラム(Ruby) [Ruby]
Rubyで、ロト7の番号(5口分)を作成するプログラムを作りました。
疑似乱数で、1から37の数字の中から7個の数字を取り出すだけの処理です。
これでロト7に当選する確率が良くなることはまったくありません。
あくまで、Rubyによるプログラム作成の練習です。
このプログラムで作成したロト番号でロト7を購入したが外れた。
どうしてくれる… なんて言わないで下さいね ^^;
(by 心如)
郵便番号の検索 [Ruby]
プログラムには検索がつきものです。Rubyのライブラリを見ても、正規表現やハッシュなどはそれ自体が検索することに主眼を置いていると言えます。Enumerableモジュールや配列にはdetectやselectといった検索のためのメソッドがあり、頻繁に使用されています。
この記事では、拡張ライブラリを使って大きなデータを効率良く検索する方法を紹介しましょう。
◆郵便番号データベース
日本郵便は、郵便番号と住所の対応表をWebで公開しています。誰でも無料でダウンロードできます。全国一括版の郵便番号データをダウンロードしてみましょう。
〔郵便番号データダウンロード ※各種郵便番号データのダウンロードはこちらからどうぞ〕
2012年4月15日現在、データ数123,218件、ファイルサイズは約12Mバイトあります。
このデータは、15個のカラムから構成されるCSV形式で、文字コードはShift_JISになっています。
各カラムの意味は、データの説明のページ掲載されています。最初の9つのカラムの意味は次のようになっています。
・全国地方公共団体コード
・(旧)郵便番号(5桁)
・郵便番号(7桁)
・都道府県名(半角カタカナ)
・市区町村名(半角カタカナ)
・町域名(半角カタカナ)
・都道府県名(漢字)
・市区町村名(漢字)
・町域名(漢字)
※ 13番目のカラムの説明に、「1つの郵便番号で2つ以上の町域を表す場合の表示」とあります。ここが1の場合、同じ郵便番号を持つ複数のレコードが現れることを示します。
詳しい説明は、『たのしいRuby』 ――Rubyではじめる気軽なプログラミング――を参照していただくとして、早速ですが表示例とプログラム例を紹介します。
───〔表示例〕───────────────────────────
紹介したスクリプト(プログラム)を使ってみますと、初回はCSV形式のファイル”KEN_ALL.CSV”から、データベースのファイル”ken_all.db”を作るため、約18秒掛かっています。
しかし、二回目は、既に出来ているデータベースから指定した郵便番号の住所を取り出すだけなので、約16mSecで同じ住所(1000000=”東京都千代田区”)を取り出せています。
同じ郵便番号(7711224)に対して、6件の住所が登録されている例(”徳島県板野郡藍住町東中富”)も上手く表示できました。
(by 心如)
『コレクション完成』(模擬実験、その三) [Ruby]
別記事〔『コレクション完成』(模擬実験、その二〕で、Rubyによる数値計算により、10000人分の模擬実験を行うプログラムを紹介しました。
しかし、数値を数字で表示しただけでは、せっかくの度数データもどういう分布になっているのか直感的な理解ができません。
そこで簡易的なヒストグラムを表示するプログラムをRubyで書いてみましたので紹介いたします。
(by 心如)
───〔出力例〕───────────────────────────
10000人のサンプル分布〔個数:人数〕
(最多:140個、最少:12個、平均37.0142個)
140: 1|
132: 1|
122: 1|
121: 2|
110: 2|
109: 3|
107: 1|
103: 1|
102: 1|
101: 2|
100: 1|
99: 2|
98: 3|
97: 1|
96: 3|
95: 2|
94: 2|
93: 1|
92: 3|
91: 4|#
90: 2|
89: 4|#
88: 10|##
87: 4|#
86: 6|#
85: 6|#
84: 6|#
83: 6|#
82: 14|##
81: 12|##
80: 10|##
79: 6|#
78: 9|#
77: 17|###
76: 10|##
75: 10|##
74: 16|##
73: 24|####
72: 23|###
71: 27|####
70: 28|####
69: 19|###
68: 28|####
67: 30|#####
66: 45|#######
65: 41|######
64: 38|######
63: 49|#######
62: 51|########
61: 47|#######
60: 46|#######
59: 63|#########
58: 69|##########
57: 76|###########
56: 69|##########
55: 80|############
54: 98|###############
53: 86|#############
52: 94|##############
51:103|###############
50:128|###################
49:133|####################
48:153|#######################
47:154|#######################
46:172|##########################
45:191|#############################
44:192|#############################
43:225|##################################
42:207|###############################
41:214|################################
40:281|##########################################
39:265|########################################
38:283|##########################################
37:284|###########################################
36:329|#################################################
35:331|##################################################
34:348|####################################################
33:352|#####################################################
32:361|######################################################
31:379|#########################################################
30:340|###################################################
29:329|#################################################
28:348|####################################################
27:355|#####################################################
26:360|######################################################
25:309|##############################################
24:300|#############################################
23:252|######################################
22:230|###################################
21:229|##################################
20:174|##########################
19:143|#####################
18: 85|#############
17: 76|###########
16: 39|######
15: 17|###
14: 9|#
13: 3|
12: 1|
* 平均の37個以下は5983人、74個以上は185人でした
『コレクション完成』(模擬実験、その二) [Ruby]
別記事〔『コレクション完成』(模擬実験)〕で紹介した事例について、予測した平均個数はだいたい妥当な数字であることをRubyスクリプトによる数値計算(模擬実験)で確認しました。
でも、平均だけでは、実際にどのくらい購入すればコレクションが完成するのか今ひとつよくわからないと感じます。そこで、コレクションが完成するまでの購入個数別に人数の分布を出してみました。
平均購入個数の37個以下でコレクションが完成する人が約59%、平均の2倍の74個以上購入したのは2.28%という模擬実験の結果が出ました。
平均個数以下でコレクションが完成する人が六割弱だというのは面白いのではないかと思います。12種類の場合は、3倍の36個くらい買ってみて、それでも全種類が揃わない場合、収集を続けるかどうか少し考え直すほうが良いのではないかと私は思います。
(by 心如)
──────────────────────────────
BATファイルにRubyスクリプトを埋め込む例 [Ruby]
Rubyには、コマンドラインオプションとして、「-S」と「-x」があります。
-Sは、スクリプトを環境変数「PATH」を使って検索し実行するためのオプションです。
-xは、ファイルに埋め込まれたRubyスクリプトの実行を指定します。このオプションが指定されていると、与えられたファイルをそのまま実行せず、「#!」で始まり「ruby」を含む行を探して、そこをスクリプトの先頭として解析を開始します。
それ以降に「__END__」と書かれた行があれば、そこをスクリプトの終わりとします。なければ、ファイルの終わりをスクリプトの終わりとします。
実際の使い方については、下記のサンプルをご参照ください。BATファイル名の「ex001」と入力すると、埋め込まれたRubyスクリプトが実行されます。RubyでDOSコマンドを作ったような気分が味わえます…^^;
(by 心如)
──────────────────────────────
ECHO OFF
ruby -S -x "%0.bat" %*
goto end
#! ruby -Ks
#
# コレクション完成の模擬実験(BATファイル埋め込み)
#
# 2012.04.14 ───── coded by 心如
st = Time.now # 時刻データの取得
srand(st.sec ^ st.usec ^ Process.pid) # 乱数の初期化
Omake_max = 12 # おまけの種類数
Kai = 10 # 試算する人数
sc = 0 # 購入総数
max_cnt, min_cnt = 12, 40
(1..Kai).each do |n|
omake = []
cnt = 0
until (omake.uniq).size == Omake_max do
omake << rand(Omake_max) + 1
cnt += 1
end
sc += cnt
max_cnt = cnt if cnt > max_cnt
min_cnt = cnt if cnt < min_cnt
printf("%5d人目:%3d個(総数:%5d個)、平均:%6.3f個\n",
n, cnt, sc, sc.to_f / n)
end
puts "(最多:#{max_cnt}個、最少:#{min_cnt}個)"
__END__
:end
ECHO ON
──────────────────────────────
『コレクション完成』(模擬実験) [Ruby]
別記事〔『コレクション完成』(数学パズル)〕で、一箱100円のキャラメルにおまけとして12種類のフィギュアが入っている場合、12種類全部を揃えてコレクションを完成させるには、平均して37~38個のキャラメルを購入する計算になることを紹介しました。
実際に、キャラメルを購入して試してみるのは、時間とお金の無駄になりますので、Rubyによる数値計算によって模擬実験を行いましたので、そのプログラムと計算結果を紹介します。
──────────────────────────────
#! ruby -Ks
#
# 2012.04.13 ───── coded by 心如
st = Time.now # 時刻データの取得
srand(st.sec ^ st.usec ^ Process.pid) # 乱数の初期化
Omake_max = 12 # おまけの種類数
Kai = 200 # 試算する人数
sc = 0 # 購入総数
max_cnt, min_cnt = 12, 40
(1..Kai).each do |n|
omake = []
cnt = 0
until (omake.uniq).size == Omake_max do
omake << rand(Omake_max) + 1
cnt += 1
end
sc += cnt
max_cnt = cnt if cnt > max_cnt
min_cnt = cnt if cnt < min_cnt
printf("%5d人目:%3d個(総数:%5d個)、平均:%6.3f個\n",
n, cnt, sc, sc.to_f / n)
end
puts "(最多:#{max_cnt}個、最少:#{min_cnt}個)"
──────────────────────────────
Rubyの条件判断 [Ruby]
指定した条件が成立したときだけ実行したい処理の書き方
─────
【書式】
if 条件 then
実行したい処理
end
─────
【書式】
if 条件 then
条件が成り立つときに実行したい処理
else
条件が成り立たないときに実行したい処理
end
─────
『たのしいRuby』読みやすいプログラムを書こう [Ruby]
─────
プログラムは、コンピュータに理解させるためのものである。しかし、その一方で人間が読み書きするものでもあります。
同じように動作するプログラムでも、人間が読みやすいものもあれば、そうでないものもあります。
この読みやすさは、プログラムの設計や構造だけではなく、「見た目」によっても左右されます。
プログラムの見た目をよくするためのポイントとして、以下の三つの点があげられます。
・改行と「;」(セミコロン)
・インデント
・空白
◆改行と「;」
Rubyの文法の特徴の一つに、改行を文の区切りとして使えることがあげられます。
これは、「区切りを書くのが面倒」といった理由だけで、このようになっているわけではありません。
「改行」そのものを、一種の自然な区切りと見なそう、ということなのです。
そのため、適切に改行することが、読みやすいプログラムへの第一歩となります。
・こまめに改行する
一般的に、改行はこまめに行った方が見やすいプログラムになります。
もちろん、やたらと改行する必要はありませんが、1行が80字を越えるような場合、どこかで改行した方がよいでしょう。どうにも改行できそうにない場合には、プログラムの設計や構造自体を見直した方がよいかもしれません。
・ふだん「;」は使わない
改行以外に、文の区切りになる記号として「;」があります。1行に複数の文を書きたい場合に使えます。たとえば、
str = "hello"; print str
と書くのは、
str = "hello"
print str
と書くのと同じ意味になります。
しかし、「;」を多用すると、プログラムが読みにくくなりがちです。
使う前に、どうしても同じ行に書かなければいけないか? と自問してみましょう。
◆インデント
インデントとは「字下げ」のことです。
プログラムの行頭に空白文字をいくつか並べて、まとまりを強調するために使います。
本書では、空白文字2つをインデント1つとしています。
次の例では、printの2行がif~endの内部にある処理、ということをわかりやすくするために、インデントを行っています。
if a == 1
print message1
print message2
end
繰り返しなどが入れ子になったときには、インデントをさらに深くします。
こうすると、文と繰り返しの対応関係が、わかりやすくなります。
while a < 10
while b < 20
b = b + 1
print b
end
a = a + 1
print a
end
インデントを行うべき場所として、つぎのようなところがあげられます。
・条件分岐
・繰り返し
・ブロック
・メソッドやクラスの定義
インデントする際には、以下のことを守りましょう。
・何でもないところで突然字下げしたりしない
・インデントの幅は揃える
◆空白
空白は、プログラム中のいたるところで現れます。次のことに気をつけましょう。
・空白の長さはそろえて、バランスよく
特に、演算子の前後の空白は同じ長さにしないと、妙な文法エラーが起きることがあります。
たとえば、aとbを足したいとき、空白の書き方によっては意図せぬ演算になってしまいます。
a+b 〇好ましい書き方
a + b 〇好ましい書き方
a +b ×間違った書き方
a+ b △好ましくない書き方
「a +b」は、「+b」という引数を持った「a」というメソッドのメソッド呼び出し「a(+b)」と誤解されてしまいます。
「+」の前後の空白をバランスよく書いてあれば、このようなことは起きません。
◆よいスタイル
よいスタイルを身につけるには、他の人の書いたRubyのプログラムを読んで、それを真似るところから始めるのがよいでしょう。プログラムの内容についても、スタイルについても、上達するには他の人のプログラムをたくさん読むことが欠かせません。
─────