IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Mathématiques Discussion :

[Enigme] Une jolie énigme!


Sujet :

Mathématiques

  1. #21
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    488
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 488
    Points : 397
    Points
    397
    Par défaut
    J'ai triché et j'ai fait un programme qui élimine tout. Si la condition a < b < c < d < e n'est pas remplie alors on est bloqué dès le deuxième tour. Par contre avec a < b < c < d < e au bout de 23 tours il ne reste plus qu'une solution (2 3 4 5 8).

  2. #22
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 76
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Points : 1 913
    Points
    1 913
    Par défaut
    Zavonen, peux-tu expliquer ces dix valeurs de v?
    Si (a,b,c,d,e) est un 5 uple candidat vérifiant:
    0<a<b<c<d<e<f<11
    les dix valeurs sont:
    (a+b)(c+d+e)
    (a+c)(b+d+e)
    (a+d)( )
    (a+e)( )
    (b+c)()
    (b+d) ()
    (b+e)( )
    (c+d)()
    (c+e)()
    (d+e)()
    correspondant aux différentes possibilités de V (a priori) compte tenu des propriétés des opérations.
    Ce qu'on trouve est plus important que ce qu'on cherche.
    Maths de base pour les nuls (et les autres...)

  3. #23
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 76
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Points : 1 913
    Points
    1 913
    Par défaut
    Pour moi, en prenant l'exemple de v, Valérie a reçue une valeur numérique; elle doit regarder fval^(-1)(v) où fval est la fct (a,b,c,d,e)-->(a+b+c)(d+e). Elle n'arrive pas à conclure, donc fval^(-1)(v) a plus d'un élément.
    Je crois que là-dessus tout le monde est d'accord.
    Mais que conclure si v est (a+b+e)(d+c) ???
    Où alors je n'ai pas bien compris l'énoncé. Faut-il comprendre que V est toujours la somme des 3 plus petits multipliée par la somme des 2 plus grands ???
    Ce qu'on trouve est plus important que ce qu'on cherche.
    Maths de base pour les nuls (et les autres...)

  4. #24
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    488
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 488
    Points : 397
    Points
    397
    Par défaut
    Citation Envoyé par Zavonen
    Faut-il comprendre que V est toujours la somme des 3 plus petits multipliée par la somme des 2 plus grands ???
    Je pense que oui, car, comme je le disais plus haut, sans cette hypothèse on reste bloqué dès la deuxième heure.

  5. #25
    Membre éprouvé Avatar de Nemerle
    Inscrit en
    Octobre 2003
    Messages
    1 106
    Détails du profil
    Informations personnelles :
    Âge : 53

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 106
    Points : 1 213
    Points
    1 213
    Par défaut
    Oui, désolé, c'est une erreur de l'énoncé initial, sorry.
    Nemerle, mathématicopilier de bars, membre du triumvirat du CSTM, 3/4 centre

  6. #26
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Personnellement je trouve (2, 5, 6, 7, 8). C'est à dire pas la même chose que Sovitec... Quelqu'un pour nous départager ? Evidemment j'ai fait ça avec un programme, qui à chaque tour supprime de la liste des possibilités l'ensemble des éléments qui n'ont qu'un seul antécédent pour chacune des opérations . A la fin on fait l'intersection des listes des éléments qui n'ont qu'un seul antécédent pour chacune des opérations, et il ne reste qu'un seul n-uplet.

    --
    Jedaï

  7. #27
    Membre éprouvé Avatar de Nemerle
    Inscrit en
    Octobre 2003
    Messages
    1 106
    Détails du profil
    Informations personnelles :
    Âge : 53

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 106
    Points : 1 213
    Points
    1 213
    Par défaut
    Jedai a tout bon !
    Nemerle, mathématicopilier de bars, membre du triumvirat du CSTM, 3/4 centre

  8. #28
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    Jedai

    Il y a une autre methode a part la "brut force" ?

    J'ai essayé de chercher le terme général de la suite des fonctions "inverse" mais je n'ai pas trouvé...

    X={a,b,c,d,e}

    rencontre 1:
    Card{ Vinverse[1](V(X)) } > 1
    Card{ Sinverse[1](S(X)) } > 1
    Card{ Pinverse[1](P(X)) } > 1
    Card{ Cinverse[1](C(X)) } > 1


    rencontre 2:
    Card{ Vinverse[2](V(X)) } > 1
    Card{ Sinverse[2](S(X)) } > 1
    Card{ Pinverse[2](P(X)) } > 1
    Card{ Cinverse[2](C(X)) } > 1

    ...

    rencontre 24:
    Card{ Vinverse[23](V(X)) } = 1
    Card{ Sinverse[23](S(X)) } = 1
    Card{ Pinverse[23](P(X)) } = 1
    Card{ Cinverse[23](C(X)) } = 1


    avec:

    Vinverse[1](A) = { X | V(X)=A } = { X1, X2, ..., Xn }

    Vinverse[2](A) = Vinverse[1](A) - { X | Card{ Sinverse[1](S(X)) } <= 1 } - { X | Card{ Pinverse[1] ...

    ...

    Vinverse[n+1](A) = Vinverse[n](A) - { X | Card{ Sinverse[n](S(X)) } <= 1 } - { X | Card{ Pinverse[n] ...

    (idem pour Sinverse, Pinverse et Cinverse)
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  9. #29
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    488
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 488
    Points : 397
    Points
    397
    Par défaut
    Citation Envoyé par Nemerle
    Jedai a tout bon !
    Exact, j'ai corrigé mon programme (un bête problème d'indice dans un tableau) et je trouve la même solution, mais comme ma première version ne me donnait aussi qu'une solution je pensais avoir trouvé

  10. #30
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Je donne mon programme tant qu'on y est, il est loin d'être idéal, mais il marche :
    Code Haskell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    module Main where
     
    import Data.List
    import qualified Data.Map as M
     
    main = do
      let (_, _, solution) = until (\(_,n,_) -> n == 24) step (initial, 0, [])
      putStrLn (show solution)
     
    initial = combination [1..10] 5
     
    combination _ 0 = [[]]
    combination l n = 
        [ x:xs | x <- l, xs <- combination (tail $ dropWhile (/= x) l) (n - 1)]
     
    step (poss, st, _) = (new_poss, st + 1, inter)
        where
          new_poss = foldl (\\) poss one_ant
          inter = foldl1 intersect one_ant
          one_ant = map (purge poss) 
                     [sum
                     , product
                     ,(foldl (\a b -> a + b * b) 0)
                     ,(\l -> (sum $ take 3 l) * (sum $ drop 3 l))
                     ]
     
    purge l f = map fst $ filter ((== 1) . snd) $ M.elems results
        where
          results = foldl myInsert M.empty l
          myInsert m x = M.insertWith combine (f x) (x, 1) m
          combine (x,n) (y,m) = (y,n+m)

    --
    Jedaï

  11. #31
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Citation Envoyé par sovitec
    Exact, j'ai corrigé mon programme (un bête problème d'indice dans un tableau) et je trouve la même solution, mais comme ma première version ne me donnait aussi qu'une solution je pensais avoir trouvé
    Est-ce que tu pourrais nous montrer ton programme ?

    --
    Jedaï

  12. #32
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    488
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 488
    Points : 397
    Points
    397
    Par défaut
    Citation Envoyé par Jedai
    Est-ce que tu pourrais nous montrer ton programme ?
    J'ai un peu honte, j'ai bricolé ça en une heure mais enfin :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
     
    type
      TNemerle = record
        Somme: Integer;
        Produit: Integer;
        SommeCarre: Integer;
        ProduitMixte: Integer;
        v1: Integer;
        v2: Integer;
        v3: Integer;
        v4: Integer;
        v5: Integer;
        ToDelete: Boolean;
      end;
    function CompareSomme(v1, v2: Pointer): Integer;
    var
      n1, n2: ^TNemerle;
    begin
      n1 := v1;
      n2 := v2;
      if n1.Somme = n2.Somme then
        Result := 0
      else if n1.Somme > n2.Somme then
        Result := 1
      else
        Result := -1
    end;
     
    function CompareProduit(v1, v2: Pointer): Integer;
    var
      n1, n2: ^TNemerle;
    begin
      n1 := v1;
      n2 := v2;
      if n1.Produit = n2.Produit then
        Result := 0
      else if n1.Produit > n2.Produit then
        Result := 1
      else
        Result := -1
    end;
     
    function CompareSommeCarre(v1, v2: Pointer): Integer;
    var
      n1, n2: ^TNemerle;
    begin
      n1 := v1;
      n2 := v2;
      if n1.SommeCarre = n2.SommeCarre then
        Result := 0
      else if n1.SommeCarre > n2.SommeCarre then
        Result := 1
      else
        Result := -1
    end;
     
    function CompareProduitMixte(v1, v2: Pointer): Integer;
    var
      n1, n2: ^TNemerle;
    begin
      n1 := v1;
      n2 := v2;
      if n1.ProduitMixte = n2.ProduitMixte then
        Result := 0
      else if n1.ProduitMixte > n2.ProduitMixte then
        Result := 1
      else
        Result := -1
    end;
     
    procedure Main;
    var
      T: TList;
      ANemerle, AOldNemerle: ^TNemerle;
      i, i1, i2, i3, i4, i5, j, k: Integer;
      b: Boolean;
    begin
      T := TList.Create;
    //  for i1 := 1 to 8 do
    //    for i2 := i1 + 1 to 9 do
    //      for i3 := i2 + 1 to 10 do
    //        for i4 := 1 to 9 do
    //          if (i4 <> i1) and (i4 <> i2) and (i4 <> i3) then
    //            for i5 := i4 + 1 to 10 do
    //              if (i5 <> i1) and (i5 <> i2) and (i5 <> i3) then
      for i1 := 1 to 6 do
        for i2 := i1 + 1 to 7 do
          for i3 := i2 + 1 to 8 do
            for i4 := i3 + 1 to 9 do
                for i5 := i4 + 1 to 10 do
                  begin
                    ANemerle := GetMemory(SizeOf(TNemerle));
                    ANemerle^.Somme := i1 + i2 + i3 + i4 + i5;
                    ANemerle^.Produit := i1 * i2 * i3 * i4 * i5;
                    ANemerle^.SommeCarre := Sqr(i1) + Sqr(i2) + Sqr(i3) + Sqr(i4) + Sqr(i5);
                    ANemerle^.ProduitMixte := (i1 + i2 + i3) * (i4 + i5);
                    ANemerle^.v1 := i1;
                    ANemerle^.v2 := i2;
                    ANemerle^.v3 := i3;
                    ANemerle^.v4 := i4;
                    ANemerle^.v5 := i5;
                    ANemerle^.ToDelete := False;
                    T.Add(ANemerle);
                  end;
      for i := 1 to 23 do
      begin
        T.Sort(CompareSomme);
        k := -1;
        b := False;
        for j := 0 to T.Count - 1 do
        begin
          ANemerle := T[j];
          if ANemerle^.Somme <> k then
          begin
            if b then
            begin
              AOldNemerle := T[j - 1];
              AOldNemerle.ToDelete := True;
            end;
            b := True;
            k := ANemerle^.Somme;
          end
          else
            b := False;
        end;
        if b then
        begin
          AOldNemerle := T[T.Count - 1];
          AOldNemerle.ToDelete := True;
        end;
     
        T.Sort(CompareProduit);
        k := -1;
        b := False;
        for j := 0 to T.Count - 1 do
        begin
          ANemerle := T[j];
          if ANemerle^.Produit <> k then
          begin
            if b then
            begin
              AOldNemerle := T[j - 1];
              AOldNemerle.ToDelete := True;
            end;
            b := True;
            k := ANemerle^.Produit;
          end
          else
            b := False;
        end;
        if b then
        begin
          AOldNemerle := T[T.Count - 1];
          AOldNemerle.ToDelete := True;
        end;
     
        T.Sort(CompareSommeCarre);
        k := -1;
        b := False;
        for j := 0 to T.Count - 1 do
        begin
          ANemerle := T[j];
          if ANemerle^.SommeCarre <> k then
          begin
            if b then
            begin
              AOldNemerle := T[j - 1];
              AOldNemerle.ToDelete := True;
            end;
            b := True;
            k := ANemerle^.SommeCarre;
          end
          else
            b := False;
        end;
        if b then
        begin
          AOldNemerle := T[T.Count - 1];
          AOldNemerle.ToDelete := True;
        end;
     
        T.Sort(CompareProduitMixte);
        k := -1;
        b := False;
        for j := 0 to T.Count - 1 do
        begin
          ANemerle := T[j];
          if ANemerle^.ProduitMixte <> k then
          begin
            if b then
            begin
              AOldNemerle := T[j - 1];
              AOldNemerle.ToDelete := True;
            end;
            b := True;
            k := ANemerle^.ProduitMixte;
          end
          else
            b := False;
        end;
        if b then
        begin
          AOldNemerle := T[T.Count - 1];
          AOldNemerle.ToDelete := True;
        end;
     
        for j := T.Count - 1 downto 0 do
        begin
          ANemerle := T[j];
          if ANemerle^.ToDelete then
            T.Delete(j);
        end;
      end;
     
      for j := 0 to T.Count - 1 do
      begin
        ANemerle := T[j];
        Memo1.Lines.Add(IntToStr(ANemerle^.Somme) + ' ' + IntToStr(ANemerle^.Produit) + ' ' + IntToStr(ANemerle^.SommeCarre) + ' ' + IntToStr(ANemerle^.ProduitMixte) + ' ' + IntToStr(ANemerle^.v1) + ' ' + IntToStr(ANemerle^.v2) + ' ' + IntToStr(ANemerle^.v3) + ' ' + IntToStr(ANemerle^.v4) + ' ' + IntToStr(ANemerle^.v5));
      end;
      Memo1.Lines.Add(IntToStr(T.Count));
    end;
    Sovitec

    PS : le Haskell c'est encore plus illisble que le perl

  13. #33
    Membre éprouvé Avatar de Nemerle
    Inscrit en
    Octobre 2003
    Messages
    1 106
    Détails du profil
    Informations personnelles :
    Âge : 53

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 106
    Points : 1 213
    Points
    1 213
    Par défaut
    ANemerle comme nom de variable ?
    Nemerle, mathématicopilier de bars, membre du triumvirat du CSTM, 3/4 centre

  14. #34
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Citation Envoyé par sovitec
    PS : le Haskell c'est encore plus illisble que le perl
    Question d'habitude, le Haskell est plutôt lisible au contraire, il ne comporte que peu des éléments qu'on reproche au Perl : pas trop de ponctuation, pas d'utilisation des regex dans tous les coins...

    D'autant que je préfère essayer de comprendre 30 lignes d'Haskell que 220 lignes de Pascal... Avec des noms de variables comme i1, b2, etc...

    Le concept de mon programme est très simple : je démarre avec un triplet ( combinaison de 5 parmi les entiers de 1 à 10 (initial = combination [1..10] 5), 0, [] (liste vide) ). J'applique step() à ce triplet jusqu'à ce que le deuxième élément soit égal à 24 (c'est à dire 24 fois, puisque step rajoute 1 à cet élément à chaque fois). A chaque étape step() calcule pour chaque opération la liste des combinaisons qui sont le seul antécédent de leur résultat (à l'aide de purge() ), les soustrait à la liste des possibilités qui est replacé dans le premier élément du triplet, et place leur intersection dans le troisième élément.

    Rien de bien compliqué, je trouve.
    Si vous souhaitez des éclaircissements supplémentaires sur chaque fonction, n'hésitez pas.

    [EDIT] J'ai maintenant pas mal simplifié le programme, consultez la version commentée suivante pour plus de détails

    --
    Jedaï

  15. #35
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Je remets une version légèrement commentée :
    Code Haskell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    module Main where
    import Data.List
    import qualified Data.Map as M
     
    main = do
      -- applique step 23 fois de suite à partir de initial
      let final = apply 23 step initial
      print $ foldl1 intersect $ map (purge final) ops
     
    -- Combinaisons de 5 éléments parmi les entiers de 1 à 10
    initial = combination [1..10] 5
     
    -- Liste des opérations de Serge, Pierre, Corinne, Valérie
    ops = [sum, product, corinne, valerie]
    corinne = foldl (\a b -> a + b * b) 0 -- somme des carrés
    valerie l = (sum $ take 3 l) * (sum $ drop 3 l) -- (a+b+c)(d+e)
     
    -- Prend une liste de possibilités et supprime les éléments qui sont 
    -- le seul antécédent de leur résultat par l'une des opérations de ops
    step poss = foldl (\\) poss $ map (purge poss) ops
     
    -- Renvoie les éléments de l qui sont le seul antécédent dans l
    -- de leur résultat par f
    purge l f = map head $ M.elems $ M.filter (null . tail) results
        where
          results = foldl myInsert M.empty l
          myInsert m x = M.insertWith (++) (f x) [x] m
     
    -- Combinaisons de n éléments parmi les éléments de l
    combination _ 0 = [[]]
    combination l n = 
        [ x:xs | x <- l, xs <- combination (tail $ dropWhile (/= x) l) (n - 1)]
     
    -- Applique n fois f sur x
    apply n f x = foldr ($) x $ replicate n f

    --
    Jedaï

  16. #36
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    puisque tout le monde y va de son programme, voila le mien...

    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
     
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
     
    public class TestProbleme {
     
    	// la population des solutions possibles
    	private List<int[]> population = new ArrayList<int[]>();
     
    	public TestProbleme() {
    		// initialisation de la population
    		for(int a=1;a<=6;a++)
    		for(int b=a+1;b<=7;b++)
    		for(int c=b+1;c<=8;c++)
    		for(int d=c+1;d<=9;d++)
    		for(int e=d+1;e<=10;e++)
    			population.add( new int[] {a,b,c,d,e} );
    	}
     
    	//	--- Les 4 fonctions de calcul ---
     
    	private int S(int[] x) {
    		return x[0]+x[1]+x[2]+x[3]+x[4];
    	}
     
    	private int P(int[] x) {
    		return x[0]*x[1]*x[2]*x[3]*x[4];
    	}
     
    	private int C(int[] x) {
    		return x[0]*x[0] + x[1]*x[1] + x[2]*x[2] + x[3]*x[3] + x[4]*x[4];
    	}
     
    	private int V(int[] x) {
    		return (x[0]+x[1]+x[2])*(x[3]+x[4]);
    	}
     
    	// --- Les 4 fonctions inverses ---
    	// (on renvoie seulement le nombre d'individus qui sont solution)
     
    	private int Sinv(int value) {
    		int count = 0;
    		for(int[] x : population)
    			if (S(x)==value) count++;
    		return count;			
    	}
     
    	private int Pinv(int value) {
    		int count = 0;
    		for(int[] x : population)
    			if (P(x)==value) count++;
    		return count;			
    	}
     
    	private int Cinv(int value) {
    		int count = 0;
    		for(int[] x : population)
    			if (C(x)==value) count++;
    		return count;
    	}
     
    	private int Vinv(int value) {
    		int count = 0;
    		for(int[] x : population)
    			if (V(x)==value) count++;
    		return count;
    	}
     
     
    	// --- Suppression des individus qui n'ont qu'une seule solution par les fonctions inverses ---
     
    	private void iteration() {
    		// construit la liste des individus "supprimables"
    		List<int[]> removable = new ArrayList<int[]>();
    		for(int[] p : population) {
    			if (Sinv(S(p))==1 || Pinv(P(p))==1 || Cinv(C(p))==1 || Vinv(V(p))==1)
    				removable.add(p);
    		}
    		// supprime les individus de la population
    		population.removeAll(removable);
    	}
     
    	// --- la boucle qui effectue les 23 iterations ----
     
    	private void resolve() {
    		for(int step=1;step<=23;step++)
    			iteration();
     
    		// affiche les individus restants
    		for(int[] x : population)
    			System.out.println(Arrays.toString(x));
    	}
     
    	// --- le main ---
     
    	public static void main(String[] args) {
    		new TestProbleme().resolve();
    	}
     
    }
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  17. #37
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Pseudocode, tu te rends compte qu'à chaque étape tu calcules Card(population) fois chacune des opérations sur chacun des éléments de la population ? Complexité de chaque étape : du O(n^2) (en supposant que n = Card(population), et en affectant un coût "unitaire" aux opérations de Serge, Pierre, Corinne et Valérie).
    Evidemment vu la taille de notre population, je suppose que ça ne se sent pas...

    De mon côté, j'ai simplifié un peu mon programme, il est maintenant presque élégant. La fonction step surtout a été simplifiée, et n'inclue plus que la logique nécessaire à la réduction de l'ensemble des possibilités.

    --
    Jedaï

  18. #38
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    Citation Envoyé par Jedai
    Pseudocode, tu te rends compte qu'à chaque étape tu calcules Card(population) fois chacune des opérations sur chacun des éléments de la population ? Complexité de chaque étape : du O(n^2) (en supposant que n = Card(population), et en affectant un coût "unitaire" aux opérations de Serge, Pierre, Corinne et Valérie).
    Oui, j'en suis totalement conscient. Mais je trouve que le code est plus simple a lire comme cela et a mon sens c'est le plus important dans ce genre de probleme.

    Pour baisser la complexité, il suffit de mettre les calculs effectués en "cache". Mais comme tu l'as dit, le gain/perte ne se voit pas sur une si petite population. Le calcul est instantané.
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  19. #39
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 76
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Points : 1 913
    Points
    1 913
    Par défaut
    J'ai vu que les solutions proposées étaient rédigées dans des langages de (très) haut niveau, disposant du type liste et de puissants opérateurs. ce qui donne un code court, plus ou moins lisible, en tout cas parfaitement clair quand il est documenté.
    J'apporte aussi une solution en C basique, essayant d'être turbo, donc pas de liste, pas de tableaux (du moins pour représenter les candidats).
    Le truc consiste à voir qu'un 5 uple cherché correspond à une partie de 5 éléments d'un ensemble à 10 éléments donc l'ensemble correspond aux nombres à 10 chiffres binaires ayant exactement 5 chiffres non nuls.
    ainsi par exemple le nombre: 0101011010 correspond à la suite (2,4,5,7,9)
    Avec un 32 bits le mieux est d'utiliser un int et d'accéder aux chiffres binaires par les champs de bits.
    Cependant mon algo d'élimination reste en n^2/2 où n est à chaque étape le nombre des possibles restant, et là je ne vois pas comment passer en dessous, mais les opérations sont assez rapides.
    Temps d'exécution 1.5 centième de seconde sur une machine pas toute récente.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    #include <stdio.h>
    #include <stdlib.h>
     
    // type choisi pour représenter une possibilité
    typedef union
    { int nombre;
     
        struct
        {
    unsigned int bit0:
            1;
    unsigned int bit1:
            1;
    unsigned int bit2:
            1;
    unsigned int bit3:
            1;
    unsigned int bit4:
            1;
    unsigned int bit5:
            1;
    unsigned int bit6:
            1;
    unsigned int bit7:
            1;
    unsigned int bit8:
            1;
    unsigned int bit9:
            1;
     
        };
    }suite;
     
    // accès direct aux bits
    int BIT(suite s, int i)
    {
        switch (i)
        {
        case 0:
            return s.bit0;
        case 1:
            return s.bit1;
        case 2:
            return s.bit2;
        case 3:
            return s.bit3;
        case 4:
            return s.bit4;
        case 5:
            return s.bit5;
        case 6:
            return s.bit6;
        case 7:
            return s.bit7;
        case 8:
            return s.bit8;
        case 9:
            return s.bit9;
        default:
            return 0;
        }
    }
    // tableau des possibilités
    suite Possibles [252];
    // pour le comptage des candidats
    int Compte_possibles=252; // a priori tout le monde peut faire l'affaire
     
    // Pour les calcul des 4 fonctions
    int TabS[252];
    int TabC[252];
    int TabP[252];
    int TabV[252] ;
     
    // Comme son nom l'indique
    void init_Possibles()
    {
        int i,j, k, h;
        for (i=0,j=0 ;i<1024;i++,h*=2)
        {
            for (h=1,k=0;h<1024;h*=2)
                if (i&h)k++;
            if (k==5)
                Possibles[j++].nombre=i;
        }
    }
     
    // implémentation de S
    int S (suite n)
    {
        int i,s;
        for (i=0,s=0;i<10;i++)
            if (BIT(n,i))s+=(i+1);
        return s;
    }
    // implémentation de C
    int C (suite n)
    {
        int i,s;
        for (i=0,s=0;i<10;i++)
            if (BIT(n,i))s+=(i+1)*(i+1);
        return s;
    }
    // implémentaton de P
    int P (suite n)
    {
        int i,p;
        for (i=0,p=1;i<10;i++)
            if (BIT(n,i))p*=(i+1);
        return p;
    }
    // implémentation de V
    int V(suite n)
    {
        int i,s1,s2,c;
        for (i=0,s1=0,s2=0,c=0;i<10; i++)
        {
            if (BIT(n,i))
            {
                c++;
                if (c<=3) s1+=i+1;
                else
                    s2+=i+1;
            }
        }
        return s1*s2;
    }
     
    // Cacluler les 4 fonctions pour l'ensemble des possibles
    void filltabs ()
    {
        int i;
        for (i=0;i<252;i++)
            if (Possibles[i].nombre)
            {
                TabS[i]=S(Possibles[i]);
                TabC[i]=C(Possibles[i]);
                TabP[i]=P(Possibles[i]);
                TabV[i]=V(Possibles[i]);
            }
    }
     
    // vérifier dans chaque tableau pour repérer les résultats qui n'appraissent qu'une seule fois
    // dès qu'une valeur est multiple on la met à zéro ainsi que tous ses clones
    // Les valeurs qui vont rester non nulles sont donc uniques
    void check()
    {
        int i,j,X;
        for (i=0;i<251;i++) // pour S
            if ((Possibles[i].nombre)&&TabS[i])
            {
                X=TabS[i];
                for (j=i+1;j<252;j++)
                    if ((Possibles[j].nombre)&&(X==TabS[j]))
                        TabS[i]=TabS[j]=0;
            }
        for (i=0;i<251;i++) //pour C
            if ((Possibles[i].nombre)&&TabC[i])
            {
                X=TabC[i];
                for (j=i+1;j<252;j++)
                    if ((Possibles[j].nombre)&&(X==TabC[j]))
                        TabC[i]=TabC[j]=0;
            }
        for (i=0;i<251;i++) //pour P
            if ((Possibles[i].nombre)&&TabP[i])
            {
                X=TabP[i];
                for (j=i+1;j<252;j++)
                    if ((Possibles[j].nombre)&&(X==TabP[j]))
                        TabP[i]=TabP[j]=0;
            }
        for (i=0;i<251;i++) // pour V
            if ((Possibles[i].nombre)&&TabV[i])
            {
                X=TabV[i];
                for (j=i+1;j<252;j++)
                    if ((Possibles[j].nombre)&&(X==TabV[j]))
                        TabV[i]=TabV[j]=0;
            }
    }
     
    void elimine () // ne garde que les lignes ou S=C=P=V=0
    {
        int i;
        Compte_possibles=0;
        for (i=0;i<252;i++)
        {
            if ((Possibles[i].nombre)&&(TabS[i]||TabC[i]||TabP[i]||TabV[i])) // test
                Possibles[i].nombre=0; // marquage des éliminés
            if (Possibles[i].nombre)Compte_possibles++;
        }
    }
    // l'itérareur
    void One_Step()
    {
        filltabs();
        check();
        elimine();
    }
     
    // fonctions de visualisation pour le déboguage
    // voir un 5-uple
    void showsuite(suite n)
    {
        int i;
        for (i=0;i<10;i++)
            if (BIT(n,i)) printf("%3d",i+1);
    }
    // Montrer tous les tableaux
    void showtabs()
    {
        int i;
        for (i=0;i<252;i++)
            if (Possibles[i].nombre)
            {
                showsuite(Possibles[i]);
                printf("%8d%8d%8d%8d\n", TabS[i],TabC[i],TabP[i],TabV[i]);
            }
    }
     
    // programme principal
    int main()
    {
        int i;
        init_Possibles(); // initialisation
        while (Compte_possibles >1)
            One_Step();
        showtabs(); //Voir le résultat
        return 0;
    }
    Ce qu'on trouve est plus important que ce qu'on cherche.
    Maths de base pour les nuls (et les autres...)

  20. #40
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Je vous signale néanmoins que l'un comme l'autre de vos programme conclut de façon hâtive, ou plutôt fait usage d'un fait qui ne découle pas directement de la description du problème....
    En effet, vous avez remarqué l'un comme l'autre que le nombre de possibilités était réduit à 1 après les 23 étapes... Néanmoins il ne s'agit nullement d'une obligation. Tout ce que la description de l'énigme nous donne c'est que cette solution doit être dans l'intersection des nombres seuls antécédents de leur résultat par chacune des opérations. En effet cette seule considération suffit pour que tous les participants puissent conclure (puisque eux connaissent leur résultat).

    Mon programme est en O(n log n) à chaque étape grâce à l'emploi d'une Map.

    --
    Jedaï

Discussions similaires

  1. Remplacer un bouton submit (bbcode) par une jolie icone
    Par Bruno.C dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 25/01/2008, 13h24
  2. Une jolie SystemError quand j'utilise ldapuserfolder
    Par yacinechaouche dans le forum Zope
    Réponses: 1
    Dernier message: 10/09/2007, 17h06
  3. comment faire une JOLIE interface
    Par estelle84 dans le forum wxWidgets
    Réponses: 4
    Dernier message: 08/05/2007, 19h31
  4. Réponses: 1
    Dernier message: 13/02/2007, 22h00
  5. Crer une jolie Horloge
    Par HwRZxLc4 dans le forum Général JavaScript
    Réponses: 10
    Dernier message: 23/05/2006, 10h18

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo