Voilà la solution, j’ai changé les Int en Ratio Int, enlevé les vérifications de la division et de la soustraction (mais là, je n’en vois pas l’intérêt ;-) )
À chaque modification, j’ai laissé l’ancienne ligne en commentaire pour voir les différences.
importData.List-- new lineimportData.Ratio-- A value is an Int or an operation with two arguments and a result.--data Value = V Int | Op Operation Value Value IntdataValue=V(RatioInt)|OpOperationValueValue(RatioInt)dataOperation=Plus|Min|Mult|Div|Error-- Instance of Show class to be able to display Operation typeinstanceShowOperationwhereshowPlus="+"showMin="-"showMult="×ばつ"showDiv="÷"show_="Error"-- Instance of Show class for Value.instanceShowValuewhere-- show (V a) = show ashow(Va)=show$numeratora-- The value is a % 1show(Opoab_)=" ("++(showa)++(showo)++(showb)++") "-- Take an Operation and a list of 2 minimal Values. Generate a new value with the first two terms.doOp::Operation->[Value]->[Value]doOpPlus(a:b:xs)=(OpPlusab(va+vb):xs)whereva=getVavb=getVb-- We don't want to have negative values, so check if a >= b-- We work in QdoOpMin(a:b:xs)=(OpMinab((getVa)-(getVb)):xs)-- | otherwise = (Op Error a b (-1)):xsdoOpMult(a:b:xs)=(OpMultab(va*vb)):xswhereva=getVavb=getVb-- First check that divisor is not 0, then check if b can divide a without rest.doOpDiv(a:b:xs)|vb==0=(OpErrorab(-1)):xs-- | va `mod` vb == 0 = (Op Div a b (va `div` vb)):xs-- | otherwise = (Op Error a b (-1)):xs|otherwise=(OpDivab(va/vb)):xswhereva=getVavb=getVb-- Create a Ratio--setV a = V asetVa=V(a%1)getV(Va)=agetV(Op___a)=a-- Do operations, take a list of Values and do all operations, drop error if a computation is not possibledoOps::[Value]->[[Value]]doOpsa=filter(dropError.head)$map(\x->doOpxa)[Plus,Min,Mult,Div]-- Check for error filter, return True if it's valid.dropError::Value->BooldropError(OpError___)=FalsedropError_=True-- En entrée une liste de values, en sortie une liste d'opérations filtrée.-- Check we have 4 numbers.-- From right to left-- - map setV x => generate a Value list with only V values.-- - compute all permutations-- - For each list of values apply all operations on first two values, we get list of list of list so concat to obtain list of list Values-- - We have 3 elements-- - For each element, we perform permutations and concat to get a list of list of Values.-- - loop twice to get list of list of Value with length == 1.-- - Then filter to check if result is 24.get24::[Int]->[[Value]]get24x|lengthx==4=filter(\x->(getV(headx))==24)$concat.mapdoOps$concat.mappermutations$concat.mapdoOps$concat.mappermutations$concat.mapdoOps$permutations$mapsetVx|otherwise=[]
[^] # Re: Haskel
Posté par Anthony Jaguenaud . En réponse au journal résoudre "trouve 24". Évalué à 4.
Voilà la solution, j’ai changé les
IntenRatio Int, enlevé les vérifications de la division et de la soustraction (mais là, je n’en vois pas l’intérêt ;-) )À chaque modification, j’ai laissé l’ancienne ligne en commentaire pour voir les différences.
Et le résultat :