问题描述
|
我从函数的下面开始,不确定如何返回中间数(即既不是最大也不是最小的数字):
middleNumber :: Int -> Int -> Int -> Int
middleNumber a b c
| ...
解决方法
我建议您将函数分为两个步骤:首先,对三个数字进行排序。然后,取中间元素。对于第一步,还要考虑是否可以一次执行一个步骤。每一步使它更接近完全排序,然后向后递归以使其更接近。
,强制性的Rube-Goldberg-答案:
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)]
我确定我们可以将其翻译为箭头语法以进一步混淆,但是我将这个任务留给有兴趣的读者阅读。
,“中间数字”大于其中一个数字,但小于另一个数字。而且只有一个中间数。解决这个问题的最机械的方法是开始
middleNumber a b c
| a < b && a > c = a
小于b
但大于c
,检查a
是否为中间数。
现在,如果a
是中间数,但实际上大于b
却小于ѭ6what怎么办?还有另一个警卫。如果b
是中间数字怎么办?还有另外两个警卫。如果c
是中间数怎么办?还有2位警卫,共处理6个不同的案件。
(顺便说一句,表达式“ 12”被称为警卫。如果您对警卫是什么还没有足够的了解,那么我建议您使用LYAH#警卫)
当然,有更好的方法来编写函数,但是出于理解目的,最好能够手动和系统地分解所有可能的情况,并确定每种情况下的处理方法。 《如何设计程序》是一本很棒的书,旨在学习如何以这种方式进行系统化。
,我做了一个快速的蛮力方法,但这绝对不是最好的解决方案
import Data.List
middleNum :: Int -> Int -> Int -> Int
middleNum a b c = (\\[_,m,_] -> m) $ sort $ a:b:c:[]
显然,这是一个可怕的想法,因为它显式依赖列表中的3个项目,但确实可以完成工作