Как мне вернуть среднее число в Хаскеле - PullRequest
2 голосов
/ 25 мая 2011

У меня есть следующее начало функции, и я не уверен относительно того, как я должен вернуть среднее число (т. Е. Число, которое не является ни самым большим, ни самым маленьким):

middleNumber :: Int -> Int -> Int -> Int
middleNumber a b c
    | ...

Ответы [ 4 ]

4 голосов
/ 25 мая 2011

Я бы порекомендовал вам разбить функцию на два шага: во-первых, отсортировать три числа. Затем возьмите средний элемент. Для первого шага также подумайте, можете ли вы сделать это по одному шагу за раз; каждый шаг приближает его к полной сортировке, а затем возвращает обратно, чтобы приблизить его.

3 голосов
/ 25 мая 2011

Обязательный Рубе-Гольдберг-ответ:

import Control.Applicative

middleNumber a b c = sum $ [sum, negate.minimum, negate.maximum] <*> [[a,b,c]]

[Изменить]

Вот другая версия:

middleNumber a b c = fst $ maximumBy (compare `on` abs.snd) [(a,b-c),(b,c-a),(c,a-b)] 

Я уверен, что мы могли бы перевести это в синтаксис стрелки для дальнейшей запутывания, но я оставляю эту задачу заинтересованному читателю.

2 голосов
/ 25 мая 2011

«Среднее число» больше, чем одно из чисел, но меньше, чем другое число.И есть только одно среднее число.Наиболее механический способ решить эту проблему - начать с

middleNumber a b c
    | a < b && a > c = a

. Проверьте, является ли a средним числом, если оно меньше b, но больше c.

А что если a является средним числом, но на самом деле оно на больше , чем b и меньше , чем c?Там еще один охранник.Что если b - это среднее число?Есть еще 2 охранника.Что если c - это среднее число?Есть еще 2 охранника, всего 6 различных случаев.

(кстати, выражение | a < b && a > c = a называется охранником. Если вы еще не совсем понимаете, что такое охранники, тоЯ рекомендую LYAH # Guards )

Конечно, есть лучшие способы написания функции, но для понимания целей полезно иметь возможность вручную и систематически разбивать все возможные ситуации,и определите, что делать в каждой ситуации. Как разрабатывать программы - отличная книга для изучения того, как действовать систематически.

0 голосов
/ 25 мая 2011

Я сделал метод быстрого перебора, но это наверняка не лучшее решение

import Data.List
middleNum :: Int -> Int -> Int -> Int
middleNum a b c = (\[_,m,_] -> m) $ sort $ a:b:c:[]

Очевидно, что это ужасная идея, поскольку она явно полагается на наличие 3 элементов в списке, но она делает свою работу

...