一昨日のエントリの続きです.
回答率が以下の表で示されるアンケートがあるときに,N≦1000の範囲で,アンケートの回答者数を求めてみましょう.
選択肢 | 回答率(%) |
---|---|
学力を身につけてほしい | 8.6 |
健康な体と体力をつけてほしい | 30.8 |
責任感の強い子になってほしい | 8.2 |
何事にも粘り強く努力する子になってほしい | 23.5 |
自立心を身につけてほしい | 28.9 |
モラルを身につけてほしい | 25.8 |
人の心の痛みや辛さがわかる人になってほしい | 57.1 |
多くの友人に恵まれてほしい | 17.9 |
不明 | 1.7 |
(教師格差―ダメ教師はなぜ増えるのか (角川oneテーマ21), p.191 「図4 我が子の成長に対して願うこと」より)
選択肢 | 回答率(%) |
---|---|
教育実践の実感として | 74.1 |
テストの読み書きが以前よりできない | 49.4 |
親が,学力が低下していると言うから | 2.4 |
マスコミが,学力が低下していると言うから | 3.5 |
教育委員会などが低下していると言うから | 1.2 |
学力比較のテストをやってみたから | 11.8 |
何となく | 2.4 |
社会全体が学力低下について騒いでいるから | 3.5 |
家庭学習をやらなくなったから | 40.0 |
わからない | 0.0 |
不明 | 7.1 |
(上掲書, p.195 「図5 学力低下を感じる証拠」より)
一つ目の表は,保護者を対象としたアンケートで,選択肢から2つを選ぶというものです.パーセンテージの合計は,202.5です.って誤差大きいなあ.3つ以上選んでいる人もいたのかな.
二つ目の表は,学校関係者を対象としたアンケートで,複数回答可です.
ともあれ,プログラムです.
#!/usr/bin/env ruby # actualcount2.rb class ActualCount def initialize(rate_a_, max_ = 100) @rate_a = rate_a_.map {|rate| rate.to_i} @max = max_ end def get_actualcount d_a = [] # 解(実数の配列) 1.upto(@max) do |d| counter = 0 # 条件を満たす分子が見つかった個数 n_a = [] # 分子の配列 @rate_a.each do |rate| # (rate-0.5)/@max≦n/d<(rate0.5)/@max を満たす整数nを探す # 変形すると,(rate*10-5)*d/(@max*10)≦n<(rate*10+5)*d/(@max*10) n_min = ((rate.to_f * 10.0 - 5.0) * d.to_f / (@max.to_f * 10.0)).ceil n_max = ((rate.to_f * 10.0 + 5.0) * d.to_f / (@max.to_f * 10.0)).floor if n_min <= n_max counter += 1 n_a << n_min end end if counter == @rate_a.length d_a << d puts "Found! N=#{d}" @rate_a.each do |rate| n = n_a.shift puts " %5d * %5d / %5d = %8.2f -> %5d" % \ [@max, n, d, @max.to_f * n.to_f / d.to_f, rate] end end end d_a end end if __FILE__ == $0 if ARGV.empty? max = 1000 rate1_a = %w(86 308 82 235 289 258 571 179 17) rate2_a = %w(741 494 24 35 12 118 24 35 400 0 71) puts "<case 1>" ac1_a = ActualCount.new(rate1_a, max).get_actualcount puts "<case 2>" ac2_a = ActualCount.new(rate2_a, max).get_actualcount # ac1and2_a = ac1_a & ac2_a # puts "<intersection>" # puts ac1and2_a.join(', ') else max = (ARGV.shift || 100).to_i rate_a = ARGV.empty? ? [14] : ARGV ActualCount.new(rate_a, max).get_actualcount end end
そして実行してみます.ですが,出力はたくさん出るので,割愛します.
明らかにN=1000は解ですが,それ以下でも,それなりに解の候補が出ています.一つ目の表の最小解はN=643でした.二つ目の表の最小解はN=85で,しばらく85の倍数が解として出てきますが,N=425とN=510の間にN=490というのが出てきます.
Rubyスクリプトの終わりのほうに3行,コメントにしているところがありますが,コメントを外して実行すると,二つの表の共通解を出力します.最小はN=660とでます.なのですが,上に書いた通り,回答者は全く違うので,この共通化は意味のないお遊びです.Arrayの&を試してみたかっただけです.
プログラムについては,一昨日のプログラムをロードするのでも求めることは可能ですが,それだと結果表示が分かりにくいなと考えまして,同じクラス名・メソッド名を使って,中身を変えました.
Array変数の名前に「_a」をつけるのは,ここ最近の習慣です.ちなみにHash変数の名前には「_h」をつけます.数値や文字列には,特に何もつけません.またそのうち,書き方が変わりそうな気もします.
コンストラクタの引数は,「rate_a, max」よりも「max, *rate_a」にすべきでした.そうすれば,1個でも10個でも自然に呼び出せるのに.