Ruby
Python
数学

自然数1〜100のカードから1枚抜いたときに3の倍数であって5の倍数でない確率をRubyとPythonで求めてみる

More than 1 year has passed since last update.

高校数学の復習をしているのでRubyやPythonを使って解いてみました。

ベン図

ベン図.png

解く

標本空間S={1, 2, 3, ..., 98, 99, 100}として、3の倍数であることを事象A、5の倍数であることを事象Bとすると、3の倍数または5の倍数のカードは

E1 = A \cup B
  • n(A) = 3の倍数の数 = 100/3 = 33 枚
  • n(B) = 5の倍数の数 = 100/5 = 20 枚
  • n(A \cap B) 3の倍数かつ5の倍数の数 = 15の倍数の数 = 100/15 = 6 枚

なので

n(E1) = n(A \cup B)
= n(A) + n(B) - n(A \cap B)
= 33 + 20 - 6
= 47

なので3の倍数であって5の倍数でないカードは

n(E) = n(E1) - n(B)
= 47 - 20
= 27

3の倍数であって5の倍数でないカードを引く確率は

n(E) / n(S)
= 27/100

Rubyで書く

和集合は | で計算可能。積集合は &。

> s = (1..100).to_a
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]
> a = []
=> []
> s.to_a.each{|i|
* a << i if i %3 == 0
> }
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]
> b = []
=> []
> s.to_a.each{|i|
* b << i if i % 5 == 0
> }
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]
> e1 = a | b
=> [3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99, 5, 10, 20, 25, 35, 40, 50, 55, 65, 70, 80, 85, 95, 100]
> e = e1.length - b.length
=> 27
> e.to_f / 100
=> 0.27

Pythonで書く

和集合はunion()関数で計算可能。積集合はintersect()関数。

>>> a = set(range(3,101,3))
>>> b = set(range(5,101,5))
>>> e1 = a.union(b)
>>> e = len(e1) - len(b)
>>> float(e)/100
0.27

追記)和集合は|でも計算可能。

>>> a = set(range(3,101,3))
>>> b = set(range(5,101,5))
>>> e1 = a | b
>>> e = len(e1) - len(b)
>>> float(e)/100
0.27

Sympyも使ってみた。

>>> from sympy import FiniteSet
>>> ma = range(3,101,3)
>>> mb = range(5,101,5)
>>> a = FiniteSet(*ma)
>>> b = FiniteSet(*mb)
>>> e1 = a.union(b)
>>> e = len(e1) - len(b)
>>> float(e)/100
0.27

range()関数楽でいい。

参考