2011-05-24 2 views

Répondre

4

Je vous recommande de diviser la fonction en deux étapes: Tout d'abord, triez les trois nombres. Ensuite, prenez l'élément central. Pour la première étape, considérez également si vous pouvez le prendre une étape à la fois; chaque étape le rapproche un peu plus du tri complet, puis revient en arrière pour le rapprocher encore plus.

+0

Merci, je vais y aller :) – maclunian

2

Le "nombre moyen" est plus grand que l'un des nombres, mais plus petit que l'autre nombre. Et il n'y a qu'un seul numéro intermédiaire. La façon la plus mécanique de résoudre ce serait de commencer

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

Vérifiez si a est le nombre du milieu en étant inférieur à b mais supérieur à c.

Maintenant, si a est le nombre moyen, mais il est en fait plus que b et moins que c? Il y a un autre gardien. Et si b est le numéro du milieu? Il y a deux autres gardes. Que faire si c est le numéro du milieu? Il y a 2 gardes de plus, pour un total de 6 cas différents.

(BTW, l'expression | a < b && a > c = a est appelée garde. Si vous ne disposez pas d'une prise ferme et de ce que les gardes sont, je vous recommande LYAH # Guards)

Bien sûr, il y a de meilleures façons d'écrire la mais pour des raisons de compréhension, il est bon de pouvoir décomposer manuellement et systématiquement toutes les situations possibles et de déterminer ce qu'il faut faire dans chaque situation. How To Design Programs est un excellent livre pour apprendre à être systématique de cette façon.

3

L'obligation Rube Goldberg-réponses:

import Control.Applicative 

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

[Modifier]

Voici une autre version:

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

Je suis sûr que nous pourrions traduire à la flèche syntaxe pour plus d'obscurcissement, mais je laisse cette tâche au lecteur intéressé.

+1

import Data.List; middleNumber a b c = (trier [a, b, c]) !! 1 –

+0

'soit l = [a, b, c] en suppression (minimum l). supprimer (maximum l) $ l' ... :-) – sclv

+0

un autre: 'middleNumber a b c = minimum [max un b, max un c, max b c]' (l'inverse fonctionne aussi) – sclv

0

J'ai fait une méthode de force brute rapide, mais cela est certainement pas la meilleure solution

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

Évidemment, cela est une mauvaise idée car il repose explicitement sur qu'il y ait 3 éléments dans la liste, mais fait le travail

Questions connexes