2014年10月20日月曜日

141020

Ruby


区分求積法

会社に行く前に以下の問題にトライしてみた。
https://codeiq.jp/ace/cielavenir/q1120

「y = x^x を x で 1 から 6 まで積分した値を

 1から 6 までを n 分割したものを
 ・台形公式(Trapezoid rule)  
 ・シンプソンの公式(Simpson's rule)  
 ・シンプソンの3/8公式(Simpson's 3/8 rule)  
 ・ブールの公式(Boole's rule)

 で近似する。

 真の値 17128.111274826415512 から0.1未満の誤差にするには
 少なくとも何分割必要か求めよ」
という問題。

実質1時間しかなく台形の場合しか正解しなかったが、
ようやく答えがあったのでコードを晒しておく。

def f(i)     # i番目の高さ
  x = 1 + (i - 1) * @d
  x ** x
end

n = 5
@d = (6.0 - 1.0) / n
sum = 0
for j in (1..n)
  sum += (f(j) + f(j + 1)) / 2 * @d
end
while sum - 17128.111274826415512 >= 0.1
  n += 1
  @d = (6.0 - 1.0) / n
  sum = 0
  for j in (1..n)
    sum += (f(j) + f(j + 1)) / 2 * @d
  end
end
p n

n = 5
@d = (6.0 - 1.0) / (n * 2)
sum = 0
for j in (1..n)
  sum += (f(j * 2 - 1) + 4 * f(j * 2) + f(j * 2 + 1)) / 3 * @d
end
while sum - 17128.111274826415512 >= 0.1
  n += 1
  @d = (6.0 - 1.0) / (n * 2)
  sum = 0
  for j in (1..n)
    sum += (f(j * 2 - 1) + 4 * f(j * 2) + f(j * 2 + 1)) / 3 * @d
  end
end
p n

n = 5
@d = (6.0 - 1.0) / (n * 3)
sum = 0
for j in (1..n)
  sum += (f(j * 3 - 2) + 3 * f(j * 3 - 1) + 3 * f(j * 3) + f(j * 3 + 1)) * 3 / 8 * @d
end
while sum - 17128.111274826415512 >= 0.1
  n += 1
  @d = (6.0 - 1.0) / (n * 3)
  sum = 0
  for j in (1..n)
    sum += (f(j * 3 - 2) + 3 * f(j * 3 - 1) + 3 * f(j * 3) + f(j * 3 + 1)) * 3 / 8 * @d
  end
end
p n

n = 5
@d = (6.0 - 1.0) / (n * 4)
sum = 0
for j in (1..n)
  sum += (7 * f(j * 4 - 3) + 32 * f(j * 4 - 2) + 12 * f(j * 4 - 1) + 32 * f(j * 4) + 7 * f(j * 4 + 1)) * 2 / 45 * @d
end
while sum - 17128.111274826415512 >= 0.1
  n += 1
  @d = (6.0 - 1.0) / (n * 4)
  sum = 0
  for j in (1..n)
    sum += (7 * f(j * 4 - 3) + 32 * f(j * 4 - 2) + 12 * f(j * 4 - 1) + 32 * f(j * 4) + 7 * f(j * 4 + 1)) * 2 / 45 * @d
  end
end
p n

出力結果
1648
40
32
10

0 件のコメント:

コメントを投稿