• [^] # Haskell

    Posté par . En réponse au journal résoudre "trouve 24". Évalué à 3. Dernière modification le 04 mars 2022 à 19:37.

    J’y ai pensé aussi, je l’ai fait. Je ne suis pas un pro du haskell, soyez bienveillant avec vos remarques ;-)

    import Data.List
    -- A value is an Int or an operation with two arguments and a result.
    data Value = V Int | Op Operation Value Value Int
    data Operation = Plus | Min | Mult | Div | Error
    -- Instance of Show class to be able to display Operation type
    instance Show Operation where
     show Plus = "+"
     show Min = "-"
     show Mult = "×ばつ"
     show Div = "÷"
     show _ = "Error"
    -- Instance of Show class for Value.
    instance Show Value where
     show (V a) = show a
     show (Op o a b _) = " (" ++ (show a) ++ (show o) ++ (show b) ++ ") "
    -- Take an Operation and a list of 2 minimal Values. Generate a new value with the first two terms.
    doOp :: Operation -> [Value] -> [Value]
    doOp Plus (a:b:xs) = (Op Plus a b (va+vb):xs)
     where va = getV a
     vb = getV b
    -- We don't want to have negative values, so check if a >= b
    doOp Min (a:b:xs) | (getV a) >= (getV b) = (Op Min a b ((getV a)-(getV b)):xs)
     | otherwise = (Op Error a b (-1)):xs
    doOp Mult (a:b:xs) = (Op Mult a b (va*vb)):xs
     where va = getV a
     vb = getV b
    -- First check that divisor is not 0, then check if b can divide a without rest.
    doOp Div (a:b:xs) | vb == 0 = (Op Error a b (-1)):xs
     | va `mod` vb == 0 = (Op Div a b (va `div` vb)):xs
     | otherwise = (Op Error a b (-1)):xs
     where va = getV a
     vb = getV b
    setV a = V a
    getV (V a) = a
    getV (Op _ _ _ a) = a
    -- Do operations, take a list of Values and do all operations, drop error if a computation is not possible
    doOps :: [Value] -> [[Value]]
    doOps a = filter (dropError.head) $ map (\x -> doOp x a) [Plus, Min, Mult, Div] 
    -- Check for error filter, return True if it's valid.
    dropError :: Value -> Bool
    dropError (Op Error _ _ _) = False
    dropError _ = 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]]
    get24 x | length x == 4 = filter (\x -> (getV (head x))==24) $ concat.map doOps $ concat.map permutations $ concat.map doOps $ concat.map permutations $ concat.map doOps $ permutations $ map setV x
     | otherwise = []

    Et les résultats :

    *Main Data.List> :l try24.hs
    [1 of 1] Compiling Main ( try24.hs, interpreted )
    Ok, one module loaded.
    *Main Data.List> get24 [ 7,7,1,2]
    [[ ( ( (×ばつ7) -1) ÷2) ],[ ( ( (×ばつ7) -1) ÷2) ],[ ( ( (×ばつ7) -1) ÷2) ],[ ( ( (×ばつ7) -1) ÷2) ]]
    *Main Data.List> get24 [ 1,2,3,8]
    [[ ( ( (2-1) ×ばつ3) ×ばつ8) ],[ (×ばつ ( (2-1) ×ばつ3) ) ],[ ( (×ばつ (2-1) ) ×ばつ8) ],[ (×ばつ (×ばつ (2-1) ) ) ],[ ( (3÷ (2-1) ) ×ばつ8) ],[ (×ばつ (3÷ (2-1) ) ) ],[ ( (×ばつ3) ×ばつ (2-1) ) ],[ ( (×ばつ3) ÷ (2-1) ) ],[ ( (2-1) ×ばつ (×ばつ3) ) ],[ ( (×ばつ8) ×ばつ (2-1) ) ],[ ( (×ばつ8) ÷ (2-1) ) ],[ ( (2-1) ×ばつ (×ばつ8) ) ],[ ( (×ばつ (2-1) ) ×ばつ3) ],[ (×ばつ (×ばつ (2-1) ) ) ],[ ( (8÷ (2-1) ) ×ばつ3) ],[ (×ばつ (8÷ (2-1) ) ) ],[ ( ( (2-1) ×ばつ8) ×ばつ3) ],[ (×ばつ ( (2-1) ×ばつ8) ) ],[ ( (8-2) ×ばつ (3+1) ) ],[ ( (3+1) ×ばつ (8-2) ) ],[ ( (8+ (3+1) ) ×ばつ2) ],[ (×ばつ (8+ (3+1) ) ) ],[ ( ( (3+1) +8) ×ばつ2) ],[ (×ばつ ( (3+1) +8) ) ],[ ( (8-2) ×ばつ (1+3) ) ],[ ( (1+3) ×ばつ (8-2) ) ],[ ( (8+ (1+3) ) ×ばつ2) ],[ (×ばつ (8+ (1+3) ) ) ],[ ( ( (1+3) +8) ×ばつ2) ],[ (×ばつ ( (1+3) +8) ) ],[ ( (1+ (8+3) ) ×ばつ2) ],[ (×ばつ (1+ (8+3) ) ) ],[ ( ( (8+3) +1) ×ばつ2) ],[ (×ばつ ( (8+3) +1) ) ],[ ( (2-1) ×ばつ (×ばつ3) ) ],[ ( (×ばつ3) ×ばつ (2-1) ) ],[ ( (×ばつ3) ÷ (2-1) ) ],[ ( (1+ (3+8) ) ×ばつ2) ],[ (×ばつ (1+ (3+8) ) ) ],[ ( ( (3+8) +1) ×ばつ2) ],[ (×ばつ ( (3+8) +1) ) ],[ ( (2-1) ×ばつ (×ばつ8) ) ],[ ( (×ばつ8) ×ばつ (2-1) ) ],[ ( (×ばつ8) ÷ (2-1) ) ],[ ( (1+3) ×ばつ (8-2) ) ],[ ( (8-2) ×ばつ (1+3) ) ],[ ( (3+1) ×ばつ (8-2) ) ],[ ( (8-2) ×ばつ (3+1) ) ],[ ( (3+ (8+1) ) ×ばつ2) ],[ (×ばつ (3+ (8+1) ) ) ],[ ( ( (8+1) +3) ×ばつ2) ],[ (×ばつ ( (8+1) +3) ) ],[ ( (3+ (1+8) ) ×ばつ2) ],[ (×ばつ (3+ (1+8) ) ) ],[ ( ( (1+8) +3) ×ばつ2) ],[ (×ばつ ( (1+8) +3) ) ],[ ( (3+1) ×ばつ (8-2) ) ],[ ( (8-2) ×ばつ (3+1) ) ],[ ( (1+3) ×ばつ (8-2) ) ],[ ( (8-2) ×ばつ (1+3) ) ],[ ( ( (2-1) ×ばつ8) ×ばつ3) ],[ (×ばつ ( (2-1) ×ばつ8) ) ],[ ( (×ばつ (2-1) ) ×ばつ3) ],[ (×ばつ (×ばつ (2-1) ) ) ],[ ( (8÷ (2-1) ) ×ばつ3) ],[ (×ばつ (8÷ (2-1) ) ) ],[ ( (×ばつ8) ×ばつ (2-1) ) ],[ ( (×ばつ8) ÷ (2-1) ) ],[ ( (2-1) ×ばつ (×ばつ8) ) ],[ ( (×ばつ3) ×ばつ (2-1) ) ],[ ( (×ばつ3) ÷ (2-1) ) ],[ ( (2-1) ×ばつ (×ばつ3) ) ],[ ( (×ばつ (2-1) ) ×ばつ8) ],[ (×ばつ (×ばつ (2-1) ) ) ],[ ( (3÷ (2-1) ) ×ばつ8) ],[ (×ばつ (3÷ (2-1) ) ) ],[ ( ( (2-1) ×ばつ3) ×ばつ8) ],[ (×ばつ ( (2-1) ×ばつ3) ) ],[ ( ( (8+1) +3) ×ばつ2) ],[ (×ばつ ( (8+1) +3) ) ],[ ( (3+ (8+1) ) ×ばつ2) ],[ (×ばつ (3+ (8+1) ) ) ],[ ( ( (1+8) +3) ×ばつ2) ],[ (×ばつ ( (1+8) +3) ) ],[ ( (3+ (1+8) ) ×ばつ2) ],[ (×ばつ (3+ (1+8) ) ) ],[ ( ( (1+3) +8) ×ばつ2) ],[ (×ばつ ( (1+3) +8) ) ],[ ( (8+ (1+3) ) ×ばつ2) ],[ (×ばつ (8+ (1+3) ) ) ],[ ( (8-2) ×ばつ (1+3) ) ],[ ( (1+3) ×ばつ (8-2) ) ],[ ( ( (8+3) +1) ×ばつ2) ],[ (×ばつ ( (8+3) +1) ) ],[ ( (1+ (8+3) ) ×ばつ2) ],[ (×ばつ (1+ (8+3) ) ) ],[ ( (2-1) ×ばつ (×ばつ3) ) ],[ ( (×ばつ3) ×ばつ (2-1) ) ],[ ( (×ばつ3) ÷ (2-1) ) ],[ ( ( (3+8) +1) ×ばつ2) ],[ (×ばつ ( (3+8) +1) ) ],[ ( (1+ (3+8) ) ×ばつ2) ],[ (×ばつ (1+ (3+8) ) ) ],[ ( (2-1) ×ばつ (×ばつ8) ) ],[ ( (×ばつ8) ×ばつ (2-1) ) ],[ ( (×ばつ8) ÷ (2-1) ) ],[ ( ( (3+1) +8) ×ばつ2) ],[ (×ばつ ( (3+1) +8) ) ],[ ( (8+ (3+1) ) ×ばつ2) ],[ (×ばつ (8+ (3+1) ) ) ],[ ( (8-2) ×ばつ (3+1) ) ],[ ( (3+1) ×ばつ (8-2) ) ]]
    

    Évidemment, on prend toute les permutations d’une même solution.