29 June, 2006

[Haskell] Exercise 3.14

教科書には fromInt :: Int -> Float があると書いてあるのだが無いので仕方なく定義する。
平均以上の個数だが、全部等しければ0個で、3個というのはあり得ないので、0個でも2個でも無ければ1個。

fromInt :: Int -> Float
fromInt x = fromInteger (toInteger x)

averageThree :: Int -> Int -> Int -> Float
averageThree x y z = fromInt (x + y + z) / 3.0

howManyAboveAverage :: Int -> Int -> Int -> Int
howManyAboveAverage x y z
| (x==y) && (y==z) = 0
| (fromInt x > averageThree x y z) && (fromInt y > averageThree x y z) = 2
| (fromInt y > averageThree x y z) && (fromInt z > averageThree x y z) = 2
| (fromInt z > averageThree x y z) && (fromInt x > averageThree x y z) = 2
| otherwise = 1

Main> averageThree 1 2 3
2.0
Main> averageThree 3 3 4
3.333333
Main> howManyAboveAverage 3 3 4
1
Main> howManyAboveAverage 3 4 4
2
Main> howManyAboveAverage 3 3 3
0
Main> howManyAboveAverage 1 2 3
1

リストはまだ教科書には出てこないが、これを使うと簡潔に書ける。

howManyAboveAverage :: Int -> Int -> Int -> Int
howManyAboveAverage x y z = length $ filter (\w -> fromInt w > averageThree x y z) [x,y,z]

Main> howManyAboveAverage 3 3 4
1
Main> howManyAboveAverage 3 4 4
2
Main> howManyAboveAverage 3 3 3
0
Main> howManyAboveAverage 1 2 3
1
Main>

3 comments:

Tom said...
This comment has been removed by the author.
Tom said...
This comment has been removed by the author.
Tom Weeks said...

howManyAboveAverage x y z = length $ filter ((> averageThree x y z) . fromInt) [x,y,z]

Lambdaを使わないほうがいいでしょうね。