2014年6月15日日曜日

140615

Ruby


Hashの値の設定

既にあるキーに対して値を設定すれば格納されていた値が上書きされる。
maps1 = {1010 => false}
maps1[1100] = false
p maps1

maps2 = {1010 => false}
maps2[1100] = false
maps2[1010] = false  # 再度同じ値を指定
p maps2

maps3 = {1010 => false}
maps3[1100] = false
maps3[1010] = true  # 異なる値を指定
p maps3

出力結果
{1010=>false, 1100=>false}
{1010=>false, 1100=>false}
{1010=>true, 1100=>false}

この性質を使うと
状態 {101000=>false, 110000=>false} から
状態 {111000=>false, 101010=>false, 101100=>false, 110100=>false} へ
移行するプログラムを作ることは容易なことがわかる。

2014年6月2日月曜日

140602

誤差について


140315(2)について、数学的には正しいが、プログラミングのうえでは不完全な部分があった。

z = Math.sqrt(x**2+y**2)
  if z == z.to_i && z < 101 then

上記はzが整数になるときについて考えようとしているわけだが、
x**2+y**2が平方数に非常に近い場合、(数学的にz == z.to_i が偽であっても)
z == z.to_i が真となりうる。
よって、
z = Math.sqrt(x**2+y**2)
  if x**2+y**2 == (z.to_i)**2 && z < 101 then
とすべきである。

このことは、次のフェルマーが出した問題を解いているときに気づいた。
x^2 - 61y^2 = 1 の自然数解を求めよ。

y = 1
num = Math.sqrt(61*y**2+1)
while !(num == num.to_i)
  y += 1
  num = Math.sqrt(61*y**2+1)
end
p num
p y

とすると、誤った最小の自然数解
335159612.0
42912791
が出力される。
正しくは次のとおりである。

y = 1
num = Math.sqrt(61*y**2+1)
while !((num.to_i)**2 - 61*y**2 == 1)
  y += 1
  num = Math.sqrt(61*y**2+1)
end
p num
p y

出力結果
1766319049.0
226153980