這是一道我在看 Youtube 時無心間發現的問題,原視頻連接:https://www.youtube.com/watch...c++
問題是:給你一個生成0到1之間隨機數的函數,請求出圓周率 π編程
第一眼看上去彷彿是一個徹底沒頭腦的問題,可是仔細一想,就能夠使用一點編程能力和初中的數學知識解決。vim
思路應該是去尋找兩個東西的交匯點,一個隨機數,是一個數字,也能夠是數軸上的一個點。兩個隨機數,就是兩個數軸上的點,或者是一個座標軸上的點(r1, r2)
,若是調用無數次的隨機數,就能夠得到無數個座標軸上的點。dom
圓周率,咱們必需要找到一個使用了圓周率的東西,很容易想到圓的面積和周長。函數
如今咱們有了無數個在座標軸上的點、圓的面積、圓的周長。emmmm……有想到什麼嗎?oop
也許咱們應該畫一個圖。spa
也許咱們應該把圓畫上去,應該會幫助咱們思考。code
OK,知道了,全部的點會落在正方形(0,0,1,1) 的範圍內,其中有一部分會落在圓的範圍內,若是咱們統計落在圓內的點的個數,記爲 N,那麼 N 與總點數 M 的比值,應該是等於圓的面積比上正方形的面積。視頻
列下公式應該是:blog
$$ r = 1/2 $$
$$\frac{N}{M} = \frac{\pi r^2}{(2r)^2}$$
把公式化簡一下,變成:
$$\pi = 4 * N / M$$
爲了編程中方便計算任意點距離圓心的距離,能夠這樣理解這個機率:
公式中的關係依然成立。
fun main() { var times = 100L for (i in 1..9) { println("loop: $times pi: ${getPi(times)}") times *= 10 } } fun getPi(count: Long): Double { var c = 0 for (i in 0 until count) { val x = Math.random() val y = Math.random() if (x * x + y * y < 1) { c++ } } return 4.0 * c / count }
運行結果:
loop: 100 pi: 3.24 loop: 1000 pi: 3.168 loop: 10000 pi: 3.1528 loop: 100000 pi: 3.14348 loop: 1000000 pi: 3.141964 loop: 10000000 pi: 3.1414304 loop: 100000000 pi: 3.14131604 loop: 1000000000 pi: 3.141585632 loop: 10000000000 pi: 3.1415885784