裏 RjpWiki

Julia ときどき R, Python によるコンピュータプログラム,コンピュータ・サイエンス,統計学

円周率に近似できる分数

2017年01月31日 | ブログラミング

円周率に近似できる分数

締め切りが 201701/31 10:00 AM なので,その 1 分後に投稿されるように予約

設問

分母、分子ともに整数の分数を使って円周率に近似することを考えます。
小数第 n 位までが円周率と一致するもののうち、分母が最小のものをπ(n)とします。

例えば、n = 1 のとき、π(1) = 19/6 = 3.166…、
n = 2 のとき、π(2) = 22/7 = 3.1428…、
n = 3 のとき、π(3) = 245/78 = 3.14102…
となります。

標準入力から n が与えられたとき、π(n) の分母を求め、標準出力に出力してください。
なお、nは11以下の正の整数とします。
参考)小数点以下11桁までの円周率は以下の通りです。
3.14159265358

【入出力サンプル】
標準入力
2

標準出力
7

=====================================

素直に書けばよいが,R ならではの落とし穴があった。
repeat ループは本来は for (denominator in 1:pow10n) とするのであるが,R の for ループは変域を前もって配列として確保するので,n = 1e11 の場合のようなサイズ(1:1e11)のサイズを取ろうとするとメモリー管理上不都合が生じる。そのため,本来は遅い(?)repeat ループにした。
また,評価システムの実行時間制限(1 秒以内)に沿うために不本意ながら,denominator の変域を制限した。
もちろん,Java などを用いればそんな小細工は不要である。

π = function(n) {
    pow10n = 10^n
    aproxPI = floor(pi* pow10n)
    denominator = ifelse(n < 10, 0, 165000)
    repeat {
        denominator = denominator+1
        if (denominator > pow10n) break
        if (any(floor(((floor(denominator*pi)+(-1:1))/denominator)*pow10n) == aproxPI)) break
    }
    cat(denominator)
}
π(1) # 6
π(2) # 7
π(3) # 78
π(4) # 106
π(5) # 113
π(6) # 113
π(7) # 27678
π(8) # 32763
π(9) # 33102
π(10) # 165849
π(11) # 265381

=====================================

Java の場合

static int PI(int n) {
    double aproxPI, x, PI;
    double [] y = {-2.0, -1.0, 0.0, 1.0, 2.0};
    double pow10 = Math.pow(10,  n);
    int denominator;
    int i;
    boolean ok;
    aproxPI = Math.floor(Math.PI*pow10)/pow10;
    for (denominator = 1; denominator
        ok = false;
        for (i = 0; i < 5; i++) {
            x = y[i]+Math.floor(denominator*Math.PI);
            PI = Math.floor(x/denominator*pow10)/pow10;
            if (PI == aproxPI) {
                ok = true;
                break;
            }
        }
        if (ok) {
            break;
        }
    }
    return denominator;
}

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

PVアクセスランキング にほんブログ村

PVアクセスランキング にほんブログ村