a = Array.new(2)
b = Array.new(2)
for i in 0..1
b[i] = a
for j in 0..1
b[i][j] = i
end
end
のように書くと,
b = Array.new(2)
for i in 0..1
b[i] = Array.new(2)
for j in 0..1
b[i][j] = i
end
end
b
のように書くと,
def make2d(h,w)
b=Array.new(h)
a=make1d(w)
for i in 0..(h-1)
b[i]=a
end
b
end
では駄目で,なぜ,
def make2d(h,w)
b=Array.new(h)
for i in 0..(h-1)
b[i]=make1d(w)
end
b
end
と書かなくてはいけないかということを分かってもらうためですね.
def median(x,y,z)
if x>y
if y>z
y
else
if x>z
z
else
x
end
end
else
if x>z
x
else
if y>z
z
else
y
end
end
end
end
チェックをするには6通りのすべての組み合わせをおこなう.
irb(main):026:0* median(1,2,3) => 2 irb(main):027:0> median(2,3,1) => 2 irb(main):028:0> median(3,2,1) => 2 irb(main):029:0> median(1,3,2) => 2 irb(main):030:0> median(2,1,3) => 2 irb(main):031:0> median(3,1,2) => 2
def median(x,y,z)
if x>y
if y>z
y
elsif x>z
z
else
x
end
elsif x>z
x
elsif y>z
z
else
y
end
end
となりもう少しすっきり書ける.
def median(x,y,z)
if (y<=x && x<=z) || (z<=x && x<=y)
x
else
if (x<=y && y<=z) || (z<=y && y<=x)
y
else
z
end
end
end
こちらはすっきりと書けるが,同じ条件判断を繰り返す(たとえば,x=3,y=2,z=1の時には,x<=yやy<=xを何度もチェックする)ので本当に速度が必要なところでは問題がでることはある.
なお,この問題ではx,y,zが異なる値だとしているので「<=」としているのは,
「<」でも動くが,「<=」とすると同じ値が含まれているときも正しい値(x=y< zの
ときはx(y)が中央値)を返す.なお,
この条件を奇麗に書くために,
def median(x,y,z)
if (y-x)*(z-x)<=0
x
else
if (x-y)*(z-y)<=0
y
else
z
end
end
end
と書いている人もいて,これも正解ではある(「<=」としているのは,
「<」でも動くが,「<=」とすると同じ値が含まれているときも正しい値を返す).
ただ,Ruby言語でx,y,zが整数値の時は問題ないが,整数値の範囲に制限がある言
語では正しく動かない場合がある.
def max(x,y)
if x>y
x
else
y
end
end
def min(x,y)
if x>y
y
else
x
end
end
def median(x,y,z)
x+y+z-max(x,max(y,z))-min(x,min(y,z))
end
というトリッキーな解法もある(これも整数値の範囲に制限がある言語では正しく
動かない場合がある).Ruby言語では,配列中の最大値を「式.max()」, 最小値を
「式.min()」で得られるので,それを使うと
def median(x,y,z) x+y+z-[x,y,z].max()-[x,y,z].min() endのように短く書ける.
def median(x,y,z) [[x,y].min(),[y,z].min(),[z,x].min()].max()というのも分かりやすい解ではある.
def median(x, y, z) ( ([x, y, z]).sort() )[1] endとする解もあった.「牛刀を以て鶏を割く 」ような解だが,発想は面白い.受け狙いで,
def median(x, y, z)
if x <= y and y <= z
return y
else
if rand(2) == 0
return median(y, x, z)
else
return median(x, z, y)
end
end
end
としていたものあった(「rand(2)」は「6.2 乱数とMonte Carlo法」でやるので,ここでは理解しなくても良い).
def det(a,b,c)
b**2-4*a*c
end
def solutions(a,b,c)
d=det(a,b,c)
if a==0 || d==0
1
else
if d>0
2
else
0
end
end
end
のようなもので,実行例は
irb(main):045:0* solutions(0,1,2) => 1 irb(main):047:0* solutions(1,3,2) => 2 irb(main):049:0* solutions(1,2,1) => 1 irb(main):050:0> solutions(1,2,3) => 0となる.
def solutions(a,b,c)
if a==0 || det(a,b,c)==0
1
else
if det(a,b,c)>0
2
else
0
end
end
end
でも良いが,答えが2の時に同じ計算det(a,b,c)を2回計算するのが気になる人
がいるかもしれない.賢いプログラミング言語処理系では,後者のように書いても前者のように変換してくれることもある.
中央値を求めるのに, def median(x,y,z) min(max(x,y),max(y,z)) endで良いと一瞬思えてしまうかもしれないが,3!=6通りのケースを考えてみると,
median(1,3,2) -> 3と誤った答えを返すことがあることに気がつくだろう.
ruby vote.rb 選択肢番号のように使う.