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

 Delphi Discussion :

Pb avec les boucles imbriquées


Sujet :

Delphi

  1. #1
    Membre régulier
    Homme Profil pro
    retraité
    Inscrit en
    Mars 2023
    Messages
    89
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Creuse (Limousin)

    Informations professionnelles :
    Activité : retraité

    Informations forums :
    Inscription : Mars 2023
    Messages : 89
    Points : 75
    Points
    75
    Par défaut Pb avec les boucles imbriquées
    Bonjour
    Je teste la pertinence de "cycles" en matière de trading.
    Le nombre de cycles à traiter est égal à floor(nombre de barres / 2 )-1;

    Ainsi si je travaille sur 100 barres, j aurais à traiter 49 cycles mais sur 2000 barres, c est 999 cycles que je dois traiter.

    Je souhaite tester les performances de chaque cycle en l associant à un autre, deux autres... n autres jusqu'à couvrir l ensemble des cycles.
    pour être tres concret voici un exemple avec 5 cycles ( le chiffre représentant le numéro du cycle) :

    1 + 2
    1 + 3
    1 + 4
    1 + 5
    2 + 3
    2 + 4
    2 + 5
    3 + 4
    3 + 5
    4 + 5

    (1+2) + 3
    (1+2) + 4
    (1+2) + 5

    (1+2+3) + 4
    (1+2+3) + 5

    (1+2+3+4) + 5

    (1+3) + 4
    (1+3) + 5

    (1+3+4) + 5

    (1+4) + 5

    (2+3) + 4
    (2+3) + 5

    (2+3+4) + 5

    (3+4) + 5
    Si je connais à l avance le nombre de cycles, je peux coder en dur cette imbrication mais comme ce nombre est different suivant le nombre de barres que je traite, je suis perdu.

    J'ai besoin de vos conseils.

    Je vous en remercie par avance.

  2. #2
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 345
    Points : 3 123
    Points
    3 123
    Par défaut
    Bonjour,
    le premier groupe c'est le nombre de combinaisons de 2 objets parmi n soit : n! / (n-2)! / 2! = 10

    pour les autre je réfléchis !

    A+
    Charly

  3. #3
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 345
    Points : 3 123
    Points
    3 123
    Par défaut
    Pour les groupes 2 à 4, c'est :

    (n-2) + (n-3)+ n-4) + ... +1 soit (n-1) * (n*2) / 2 (somme des n-1 nombres entiers)

    ensuite il faut continuer avec n-1 nombres je pense. A voir !

    A+
    Charly

  4. #4
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 345
    Points : 3 123
    Points
    3 123
    Par défaut
    Pardon la somme des n premiers entiers c'est n*(n+1)/2 donc ici avec n-1 ça fait :
    (n-1)*n /2

    A+
    Charly

  5. #5
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 345
    Points : 3 123
    Points
    3 123
    Par défaut
    Voilà pour la somme des nombres des n-1 premier groupes. Après ...

    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
    Function factorielle(fact:integer):integer;
    Begin
      if fact >=1 then factorielle:=fact*factorielle(fact-1)
                  else factorielle:=1;
    End;
     
    Procedure TForm1.Button1Click(Sender: TObject);
    Var
      S  : Integer ;
      N  : Integer ;
      i  : Integer ;
      S1 : Integer ;
      j  : Integer ;
    Begin
      N := StrToIntDef(E_N.Text, 1) ;
      If N > 2 Then
        Begin
          Memo1.Clear ;
          S := Round(Factorielle(N) / Factorielle( N-2) / 2) ;
          Memo1.Lines.Add(IntToStr(S));
          i := N - 2 ;
          For j := 1 To i Do
            Begin
              S1 := (N-2) * (N-1) div 2 ;
              S := S + S1 ;
              Memo1.Lines.Add(IntToStr(S1)+ '  total : '+IntToStr(S));
              N := N-1 ;
            End ;
        End ;
    End;
    à tester

    A+
    Charly

  6. #6
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Au final, cela ressemble à toutes les combinaisons sans répétition de n éléments pris k à k .. n

    Je tenterais bien

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for I := 2 to 5 do
      Inc(CombinaisonCount, CoefficientBinomial(5, I));
    Je n'ai pas Delphi sous la main pour tester mais ça fait 10 + 10 + 5 + 1 = 26 !
    Mince, l'exemple montre 24,
    Il manque (2+4) + 5 et (1+2+4) + 5 dans la liste ci-dessus, pourquoi ?


    Attention à la factorielle qui peut vite provoquer une StackOverflow, je ne retrouve pas la version itératif de la factorielle que j'avais fait pour le sujet combinaisons dans un tlist car finalement le nombre de combinaison était calcul via un Coefficient Binomial qui doit ressembler à la division d'une factorielle par une autre une factorielle.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    S := Round(Factorielle(N) / Factorielle( N-2) / 2) ;
    Doit pouvoir se calculer comme Coefficient Binomial

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    S := CoefficientBinomial(N, 2);
    Code issu de ma réponse dans le combinaisons dans un tlist

    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
    function CoefficientBinomial(N, K: Integer): Integer;
      var
        D: Integer;
        CB: Double;
      begin
        if N < K then
          Abort;
     
        if N = K then
          Exit(1);
     
        if N = K + 1 then
          Exit(N);
     
        CB := 1;
        D := N - K;
        while D > 0 do
        begin
          CB := CB * (N / D);
          Dec(N);
          Dec(D);
        end;
        Result := Trunc(CB);
      end;
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  7. #7
    Membre régulier
    Homme Profil pro
    retraité
    Inscrit en
    Mars 2023
    Messages
    89
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Creuse (Limousin)

    Informations professionnelles :
    Activité : retraité

    Informations forums :
    Inscription : Mars 2023
    Messages : 89
    Points : 75
    Points
    75
    Par défaut
    Merci pour vos réponses.
    Je vais tester cela durant le week-end.

    @ShaiLeTroll s' Il manque (2+4) + 5 et (1+2+4) + 5 dans la liste ci-dessus, c est que j ai fait ça en rédigeant le post et que j e les ai oubliés.. dsl

  8. #8
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 345
    Points : 3 123
    Points
    3 123
    Par défaut
    Oui, c'est bien ça :

    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
    function CoefficientBinomial(N, K: Integer): Integer;
      var
        D: Integer;
        CB: Double;
      begin
        if N < K then
          Abort;
     
        if N = K then
          Begin
            Result := 1 ;
            Exit;
          End ;
     
        if N = K + 1 then
          Begin
            Result := N ;
            Exit;
          End ;
     
        CB := 1;
        D := N - K;
        while D > 0 do
        begin
          CB := CB * (N / D);
          Dec(N);
          Dec(D);
        end;
        Result := Trunc(CB);
      end;
     
    Procedure TForm1.Button1Click(Sender: TObject);
    Var
      S  : Integer ;
      N  : Integer ;
      i  : Integer ;
    Begin
      Memo1.Clear ;
      N := StrToIntDef(E_N.Text, 1) ;
      S := 0 ;
      for I := 2 to N do
        Inc(S, CoefficientBinomial(N, I));
      Memo1.Lines.Add(' -------- total : '+IntToStr(S));
    End;
    mais attention ça croit très vite, au delà de 30 cycles, la capacité de l'integer est dépassée.

    Bravo à ShaiLeTRoll !

    A+
    Charly

  9. #9
    Membre régulier
    Homme Profil pro
    retraité
    Inscrit en
    Mars 2023
    Messages
    89
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Creuse (Limousin)

    Informations professionnelles :
    Activité : retraité

    Informations forums :
    Inscription : Mars 2023
    Messages : 89
    Points : 75
    Points
    75
    Par défaut
    merci pour vos réponses, je vais tester tout cela

  10. #10
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 421
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 421
    Points : 5 820
    Points
    5 820
    Par défaut
    salut

    la formule pour les combinaison sans répétition est

    Ckn=Factorielle(n)/(Factorielle(k)*Factorielle(n-k))
    et avec répétitions

    Dkn=Factorielle(n+k−1)/(Factorielle(k)*Factorielle(n−1))
    le code de la factorielle

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Function Factorielle(X : Int64) : Int64;
    begin
      if x < 2 Then
        Result := 1
      else:
        Result :=  x * factorielle(x - 1);
    end;
    tu peux aussi utilisé aussi une bibliothèque de grand nombre afin d'évité les débordements
    Par exemple L'unité FGInt qui as la fonction factorielle d'implémenté (FGIntFac)
    Nous souhaitons la vérité et nous trouvons qu'incertitude. [...]
    Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
    Blaise Pascal
    PS : n'oubliez pas le tag

  11. #11
    Membre régulier
    Homme Profil pro
    retraité
    Inscrit en
    Mars 2023
    Messages
    89
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Creuse (Limousin)

    Informations professionnelles :
    Activité : retraité

    Informations forums :
    Inscription : Mars 2023
    Messages : 89
    Points : 75
    Points
    75
    Par défaut
    J'ai retiré le résolu car j'ai enfin pu tester et effectivement vous me donnez (Charly910)le calcul pour connaitre le nombre de combinaisons.
    Mais je cherche à faire une boucle pour afficher toutes les combinaisons possibles.

    L'un d'entre vous aurait-il une idée de comment procéder ?

    @anapurna dans Ckn=Factorielle(n)/(Factorielle(k)*Factorielle(n-k)) n est mon nombre de cycles mais k, ça correspond à quoi ?

    D'avance merci.

  12. #12
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    As-tu lu le sujet que j'avais mentionné combinaisons dans un tlist qui gère des cartes à jouer mais c'est le même principe

    Il faut d'appeler GetAllTirages plusieurs fois en utilisant le même Ensemble et changer Count, je te ponds ça durant ma réunion
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  13. #13
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Surement un peu lourd car j'ai bricolé à partir du générateur de Deck de Carte à jouer de l'autre sujet mais fonctionnel

    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
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    unit Unit3;
     
    interface
     
    uses System.Classes,
      System.Generics.Collections;
     
    type
      TNumber = Byte;
     
      TNumberList = class(System.Generics.Collections.TList<TNumber>)
      private
        function GetNumber(Index: Integer): TNumber;
      public
        function Clone(): TNumberList;
        procedure ToStrings(AStrings: TStrings; ADoClear: Boolean = True);
        procedure ToFlatStrings(AStrings: TStrings; ADoClear: Boolean = True);
     
        property Numbers[Index: Integer]: TNumber read GetNumber; default;
      end;
     
      TNumbers = class(TObject)
      strict private
        FAvailableNumbers: TNumberList;
     
        procedure FillAvailableNumbers(AMax: Byte);
      public
        constructor Create(AMax: Byte);
        destructor Destroy(); override;
     
        property AvailableNumbers: TNumberList read FAvailableNumbers;
      end;
     
      TNumberLists = class(System.Generics.Collections.TObjectList<TNumberList>)
      public
        procedure ToStrings(AStrings: TStrings; ADoClear: Boolean = True);
        procedure ToFlatStrings(AStrings: TStrings; ADoClear: Boolean = True);
      end;
     
     
     
    function GetAllNumberTirages(ANumbers: TNumberList; ACount: Byte; ATirages: TNumberLists; ADoClear: Boolean = True; const AOffset: Integer = -1): Integer;
     
    implementation
     
    uses
      System.SysUtils, System.Math;
     
    { TNumberList }
     
    function TNumberList.GetNumber(Index: Integer): TNumber;
    begin
      Result := Items[Index - 1];
    end;
     
    procedure TNumberList.ToStrings(AStrings: TStrings; ADoClear: Boolean = True);
    var
      C: TNumber;
    begin
      AStrings.BeginUpdate();
      try
        if ADoClear then
          AStrings.Clear();
        for C in Self do
          AStrings.Add(IntToStr(C));
     
      finally
        AStrings.EndUpdate();
      end;
    end;
     
    procedure TNumberList.ToFlatStrings(AStrings: TStrings; ADoClear: Boolean = True);
    var
      I: Integer;
      S: string;
    begin
      AStrings.BeginUpdate();
      try
        if ADoClear then
          AStrings.Clear();
        if Count > 1 then
        begin
          S := IntToStr(Items[0]);
          for I := 1 to Count - 1 do
            S := S + ' + ' + IntToStr(Items[I]);
        end;
        AStrings.Add(S);
     
      finally
        AStrings.EndUpdate();
      end;
    end;
     
    function TNumberList.Clone(): TNumberList;
    var
      C: TNumber;
    begin
      Result := TNumberList.Create();
      for C in Self do
        Result.Add(C);
    end;
     
    { TNumbers }
     
    constructor TNumbers.Create(AMax: Byte);
    begin
      FAvailableNumbers := TNumberList.Create();
      FillAvailableNumbers(AMax);
    end;
     
    destructor TNumbers.Destroy();
    begin
      FreeAndNil(FAvailableNumbers);
     
      inherited Destroy();
    end;
     
    procedure TNumbers.FillAvailableNumbers(AMax: Byte);
    var
      I: Byte;
    begin
      for I := 1 to AMax do
        FAvailableNumbers.Add(I);
    end;
     
    { TNumberLists }
     
    procedure TNumberLists.ToStrings(AStrings: TStrings; ADoClear: Boolean);
    var
      List: TNumberList;
    begin
      AStrings.BeginUpdate();
      try
        if ADoClear then
          AStrings.Clear();
        for List in Self do
        begin
          List.ToStrings(AStrings, False);
          AStrings.Add('');
        end;
      finally
        AStrings.EndUpdate();
      end;
    end;
     
    procedure TNumberLists.ToFlatStrings(AStrings: TStrings; ADoClear: Boolean);
    var
      List: TNumberList;
    begin
      AStrings.BeginUpdate();
      try
        if ADoClear then
          AStrings.Clear();
        for List in Self do
          List.ToFlatStrings(AStrings, False);
      finally
        AStrings.EndUpdate();
      end;
    end;
     
    { fonctions diverses }
     
    function GetAllNumberTirages(ANumbers: TNumberList; ACount: Byte; ATirages: TNumberLists; ADoClear: Boolean = True; const AOffset: Integer = -1): Integer;
     
      function CoefficientBinomial(N, K: Integer): Integer;
      var
        D: Integer;
        CB: Double;
      begin
        if N < K then
          Abort;
     
        if N = K then
          Exit(1);
     
        if N = K + 1 then
          Exit(N);
     
        CB := 1;
        D := N - K;
        while D > 0 do
        begin
          CB := CB * (N / D);
          Dec(N);
          Dec(D);
        end;
        Result := Round(CB);
      end;
     
    var
      Remaining: TNumberList;
      I, K: Integer;
      TirageCount, TirageExistingCount: Integer;
    begin
      if not Assigned(ANumbers) then
        Abort;
      if not Assigned(ATirages) then
        Abort;
     
      if ADoClear then
        ATirages.Clear();
     
      if ANumbers.Count < ACount then
        Exit(0);
     
      if ANumbers.Count = ACount then
      begin
        ATirages.Add(ANumbers.Clone());
        Exit(1);
      end;
     
      TirageExistingCount := ATirages.Count;
      if AOffset = -1 then
      begin
        TirageCount := CoefficientBinomial(ANumbers.Count, ACount);
        if ATirages.Capacity < TirageCount + TirageExistingCount then
          ATirages.Capacity := TirageCount + TirageExistingCount;
      end
      else
        TirageCount := -1;
     
      K := Max(AOffset, 0);
      for I := K to ANumbers.Count - 1 do
      begin
        Remaining := ANumbers.Clone();
        try
          Remaining.Delete(I);
     
          GetAllNumberTirages(Remaining, ACount, ATirages, False, K);
          Inc(K);
     
        finally
          Remaining.Free();
        end;
      end;
     
      if TirageCount > 0 then
        Assert(TirageCount = ATirages.Count - TirageExistingCount);
     
      Result := ATirages.Count;
    end;
     
     
     
     
    end.
    J'ai changé Trunc par Round dans CoefficientBinomial pour supporter une valeur inexacte à 164.9999999999999999999999999 devant être 165 et non 164


    utilisation

    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
    procedure TForm1.Button3Click(Sender: TObject);
    var
      Tirages: TNumberLists;
      K: Byte;
    begin
      with TNumbers.Create(StrToInt(Edit3.Text)) do
      try
        AvailableNumbers.ToStrings(Memo1.Lines);
        Memo1.Lines.Add('---');
     
        Tirages := TNumberLists.Create(True);
        try
          for K := 2 to StrToInt(Edit3.Text) do
            GetAllNumberTirages(AvailableNumbers, K, Tirages, False);
     
          Tirages.ToFlatStrings(Memo1.Lines, False);
        finally
          Tirages.Free();
        end;
        Memo1.Lines.Add('---');
     
      finally
        Free();
      end;
    end;
    enfin le résultat comme prévu de 10 + 10 + 5 + 1 correspond à la somme des Coefficients binomiaux Ckn, n à 5 et k de 2..5

    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
    4 + 5
    3 + 5
    3 + 4
    2 + 5
    2 + 4
    2 + 3
    1 + 5
    1 + 4
    1 + 3
    1 + 2
    3 + 4 + 5
    2 + 4 + 5
    2 + 3 + 5
    2 + 3 + 4
    1 + 4 + 5
    1 + 3 + 5
    1 + 3 + 4
    1 + 2 + 5
    1 + 2 + 4
    1 + 2 + 3
    2 + 3 + 4 + 5
    1 + 3 + 4 + 5
    1 + 2 + 4 + 5
    1 + 2 + 3 + 5
    1 + 2 + 3 + 4
    1 + 2 + 3 + 4 + 5
    Montons à 6

    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
    5 + 6
    4 + 6
    4 + 5
    3 + 6
    3 + 5
    3 + 4
    2 + 6
    2 + 5
    2 + 4
    2 + 3
    1 + 6
    1 + 5
    1 + 4
    1 + 3
    1 + 2
    4 + 5 + 6
    3 + 5 + 6
    3 + 4 + 6
    3 + 4 + 5
    2 + 5 + 6
    2 + 4 + 6
    2 + 4 + 5
    2 + 3 + 6
    2 + 3 + 5
    2 + 3 + 4
    1 + 5 + 6
    1 + 4 + 6
    1 + 4 + 5
    1 + 3 + 6
    1 + 3 + 5
    1 + 3 + 4
    1 + 2 + 6
    1 + 2 + 5
    1 + 2 + 4
    1 + 2 + 3
    3 + 4 + 5 + 6
    2 + 4 + 5 + 6
    2 + 3 + 5 + 6
    2 + 3 + 4 + 6
    2 + 3 + 4 + 5
    1 + 4 + 5 + 6
    1 + 3 + 5 + 6
    1 + 3 + 4 + 6
    1 + 3 + 4 + 5
    1 + 2 + 5 + 6
    1 + 2 + 4 + 6
    1 + 2 + 4 + 5
    1 + 2 + 3 + 6
    1 + 2 + 3 + 5
    1 + 2 + 3 + 4
    2 + 3 + 4 + 5 + 6
    1 + 3 + 4 + 5 + 6
    1 + 2 + 4 + 5 + 6
    1 + 2 + 3 + 5 + 6
    1 + 2 + 3 + 4 + 6
    1 + 2 + 3 + 4 + 5
    1 + 2 + 3 + 4 + 5 + 6
    A 10, c'est déjà 1013 combinaisons
    A 11, c'est 2036 combinaisons (c'est là que l'arrondi du coef était inexacte)
    A 20 c'est seulement 1 048 555 combinaisons, le calcul fut rapidement mais ToFlatStrings lui a durer plusieurs minutes pour générer les chaines d'addition soit 46 Mo de 1 + 2 + 3 ...

    Je te laisse imaginer des chiffres à 49, 100, 2000 comme mentionné plus haut dans l'énoncé
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  14. #14
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Note que GetAllNumberTirages appel récursivement GetAllNumberTirages K - 1
    Il y a surement une optimisation à faire à ce niveau

    Pour 10, c'est 1 ms pour 1013 combinaisons, en dessous ce n'est pas mesurable en ms
    Pour 11, c'est 3 ms pour 2036 combinaisons
    Pour 20, c'est 4600 ms pour trouver les 1 048 555 combinaisons
    Pour 21, c'est 10008 ms pour trouver les 2 097 130 combinaisons
    C'est exponentiel
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  15. #15
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 421
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 421
    Points : 5 820
    Points
    5 820
    Par défaut
    Salut

    Voici un debut de solution

    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
    Procedure combinations(results : TStrings;elements : String;k : Integer);
        //Fonction auxiliaire récursive pour générer les combinaisons
     
        Procedure generate_combinations(results : TStrings;elements,current_combination : String;start,k : Integer) ;
        var
          OldCombi : String;
          i : Integer;
        Begin
           if length(current_combination) = k Then
          begin
            results.Append(current_combination); // Ajouter une copie de la combinaison actuelle
            //return
            Exit;
          End;
     
          for i := start to  length(elements) do
          Begin
            OldCombi := current_combination;
            current_combination := current_combination+ elements[i];
          	  // current_combination.append(elements[i]) //
            generate_combinations(results,elements,current_combination, i + 1,k) ;// # Passer à l'élément suivant
            current_combination := OldCombi;  //  # Retirer l'élément ajouté pour essayer les autres combinaisons
          end;
        End;
    Begin
      generate_combinations(results,elements,'',1,k);  //# Commencer avec une combinaison vide et l'index 0
    End;
     
    procedure TForm1.Button1Click(Sender: TObject);
    var
     i : Integer;
    begin
      for i := 1 to length(Edit1.Text) do
        combinations(Memo1.Lines,Edit1.Text,i);
    end;
    Nous souhaitons la vérité et nous trouvons qu'incertitude. [...]
    Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
    Blaise Pascal
    PS : n'oubliez pas le tag

  16. #16
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    OldCombi ne sert à rien, la boucle peut s'écrire ainsi
    D'ailleurs ajouter le mot clé const éviterait des copies de chaine
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
            for i := start to  length(elements) do
              generate_combinations(results,elements,current_combination+ elements[i], i + 1,k) ;// # Passer à l'élément suivant

    Une solution qui ne fonctionne que jusqu'à 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 puisque les éléments sont issues d'une chaine, après faudrait fonctionner en hexadécimal (voire un système alphanumérique jusqu'à Z), il est facile de la remplacer par une TList<Byte>

    Ajouter un BeginUpdate et EndUpdate accélera nettement la vitesse aussi puisque le résultat et l'affichage sont confondus au sein du même objet TStrings.
    Pour le cas du TStrings d'un TMemo, on gagne 90% de temps d'affichage

    Alimenter la TStrings prend 99% du temps de la fonction combinations même avec BeginUpdate et EndUpdate, c'est 100 fois plus lent qu'alimenter une TList<Byte> d'où l'intérêt de séparer la partie donnée de son affichage textuel

    Faudra éliminer les premiers éléments de combinaison de longueur 1

    Voici donc une variante de la proposition de anapurna toujours limite de 1 à 9 mais plus rapide.

    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
    procedure TForm1.Button5Click(Sender: TObject);
     
      procedure combinations(AResults: TStrings; const AElements: string; ACount: Integer);
      var
        ElementLength: Integer;
     
        procedure generate_combinations(const ACurrentCombination: String; AStart, ACount: Integer) ;
        var
          I: Integer;
        Begin
           if Length(ACurrentCombination) = ACount Then
          begin
            AResults.Append(ACurrentCombination); // Ajouter une copie de la combinaison actuelle
            Exit;
          End;
     
          for I := AStart to ElementLength do
            generate_combinations(ACurrentCombination + AElements[i], I + 1, ACount) ;// # Passer à l'élément suivant
        End;
      begin
        ElementLength := Length(AElements);
     
        AResults.BeginUpdate();
        try
          generate_combinations('', 1, ACount);  //# Commencer avec une combinaison vide et l'index 0
        finally
          AResults.EndUpdate();
        end;
     
      End;
     
    var
      I: Integer;
      Chrono: TStopwatch;
    begin
      Chrono := TStopwatch.StartNew();
     
      for I := 2 to Length(Edit5.Text) do
        combinations(Memo1.Lines, Edit5.Text, I);
     
      Chrono.Stop();
      Memo1.Lines.Add(Chrono.ElapsedMilliseconds.ToString() + ' ms');
    end;
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  17. #17
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Adaptation du code d'anapurna de string à TList<Byte> pour la liste d'éléments et converse une TStrings pour les resultats

    Si on le compare au code GetAllNumberTirages, c'est la même idée, une boucle récursive travaillant sur une combinaison jusqu'à ce qu'elle obtient la longueur requise
    La différence, dans cette dernière cela prend tous les éléments et les retirent à chaque tour et l'autre cela prend aucun élément et les ajoutent à chaque tour


    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
    procedure TForm1.Button51Click(Sender: TObject);
     
      procedure combinations(AResults: TStrings; AElements: TList<Byte>; ACount : Integer);
     
        procedure generate_combinations(ACurrentCombination: TList<Byte>; AStart, ACount: Integer) ;
        var
          NewCombi: TList<Byte>;
          S: string;
          I: Integer;
        Begin
          if Assigned(ACurrentCombination) and (ACurrentCombination.Count = ACount) Then
          begin
            if ACount > 0 then
            begin
              S := IntToStr(ACurrentCombination[0]);
              for I := 1 to ACount - 1 do
                S := S + ' + ' + IntToStr(ACurrentCombination[I]);
            end;
     
            AResults.Append(S); // Ajouter une copie de la combinaison actuelle
            Exit;
          End;
     
          for I := AStart to AElements.Count - 1 do
          begin
            NewCombi := TList<Byte>.Create();
            try
              if Assigned(ACurrentCombination) and (ACurrentCombination.Count > 0) then
                NewCombi.AddRange(ACurrentCombination.ToArray());
     
              NewCombi.Add(AElements[I]);
              generate_combinations(NewCombi, I + 1, ACount);// # Passer à l'élément suivant
            finally
              NewCombi.Free();
            end;
          end;
        end;
     
      begin
        AResults.BeginUpdate();
        try
          generate_combinations(nil, 0, ACount);  //# Commencer avec une combinaison vide et l'index 0
        finally
          AResults.EndUpdate();
        end;
     
      End;
     
    var
      I: Integer;
      Elements: TList<Byte>;
      Chrono: TStopwatch;
    begin
      Elements := TList<Byte>.Create();
      try
        Chrono := TStopwatch.StartNew();
     
        for I := 1 to StrToInt(Edit3.Text) do
          Elements.Add(I);
     
        for I := 2 to Elements.Count do
          combinations(Memo1.Lines,Elements,i);
     
        Chrono.Stop();
        Memo1.Lines.Add(Chrono.ElapsedMilliseconds.ToString() + ' ms');
     
      finally
        Elements.Free();
      end;
    end;
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  18. #18
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 421
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 421
    Points : 5 820
    Points
    5 820
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    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
     
     procedure combinations(AResults: TStrings; AElements: TList<Byte>; ACount : Integer);
     
        procedure generate_combinations(ACurrentCombination: TList<Byte>; AStart, ACount: Integer) ;
        var
          NewCombi: TList<Byte>;
          S: string;
          I: Integer;
        Begin
          if Assigned(ACurrentCombination) and (ACurrentCombination.Count = ACount) Then
          begin
            if ACount > 0 then
            begin
              S := IntToStr(ACurrentCombination[0]);
              for I := 1 to ACount - 1 do
                S := S + ' + ' + IntToStr(ACurrentCombination[I]);
            end;
     
            AResults.Append(S); // Ajouter une copie de la combinaison actuelle
            Exit;
          End;
     
          for I := AStart to AElements.Count - 1 do
          begin
            NewCombi := TList<Byte>.Create();
            try
              if Assigned(ACurrentCombination) and (ACurrentCombination.Count > 0) then
                NewCombi.AddRange(ACurrentCombination.ToArray());
     
              NewCombi.Add(AElements[I]);
              generate_combinations(NewCombi, I + 1, ACount);// # Passer à l'élément suivant
            finally
              NewCombi.Free();
            end;
          end;
        end;
     
      begin
        AResults.BeginUpdate();
        try
          generate_combinations(nil, 0, ACount);  //# Commencer avec une combinaison vide et l'index 0
        finally
          AResults.EndUpdate();
        end;
     
      End;
    Dans ce cas là tu devrais pouvoir l'écrire comme cela non ?

    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
     
     procedure combinations(AResults: TStrings; AElements: TList<Byte>; ACount : Integer);
        ///////////////////
        procedure generate_combinations(ACurrentCombination: TList<Byte>; AStart, ACount: Integer) ;
        var
          I: Integer;
        Begin
          if Assigned(ACurrentCombination)  Then 
          Begin  
            if  (ACurrentCombination.Count = ACount) Then
            begin
                AResults.Append(ACurrentCombination.ToString); // Ajouter une copie de la combinaison actuelle
                Exit;
            End;
            for I := AStart to AElements.Count - 1 do
            begin
               generate_combinations(ACurrentCombination.Add(AElements[I]);, I + 1, ACount);// # Passer à l'élément suivant
               // Au pire ici on retire le dernier élément ajouté 
               // ACurrentCombination.Delete(ACurrentCombination.Count);
            end;
          end;
        end;
        /////////////////
    Var 
      Current : TList<Byte>;
     begin
        Current  :=   TList<Byte>.Create()
        Try   
           AResults.BeginUpdate();
           try 
              generate_combinations(Current  , 0, ACount);  //# Commencer avec une combinaison vide et l'index 0
           finally
              AResults.EndUpdate();
           end;
        finally
           Current.free;
       end;
     End;
    je ne peut pas tester le code mais cela semble plus optimisé
    on évite la destruction et créations d'objet le Begin et fin update se fait uniquement au debut
    ...
    Nous souhaitons la vérité et nous trouvons qu'incertitude. [...]
    Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
    Blaise Pascal
    PS : n'oubliez pas le tag

  19. #19
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Add retourne un entier comme la documentation le mentionne : System.Generics.Collections.TList.Add : function Add(const Value: T): Integer; inline;.

    Mais avec le premier code fourni avec la TNumberList qui hérite de TList, on peut tout à fait redéfinir le Add pour qu'il retourne la liste pour réduire le code, d'ailleurs, cela s'appele le "Method Chaining", les fonctions d'un objet retourne toujours Self permettant d'écrire un code du type "Fluent interface"

    D'ailleurs il faudrait en plus gérer un Clone() de l'instance car contrairement au chaine ou + fonctionne par copie, le Add modifie l'objet receveur
    Et la libération des instances par Clone(), on pourrait en donner la responsabilité à la récursivité même si ce n'est pas habituelle, Delphi n'a pas de garbage collector pour ça, sinon faudrait encaspuler la TList dans un TInterfacedObject pour utiliser le compteur de référence des Interfaces.

    c'est en cela que l'approche string (objet managé) est bien plus simple car on gère pas les alloc,realloc,free, c'est implicite, l'approche objet (non managé) nécessite de connaître le cycle de vie des instances

    Enfin ToString de TList, cela ne fournira pas le résultat que tu penses, c'est le ToString par défaut qui sera utilisé soit "TList<System.Byte>" au lieu d'un truc comme "1 + 2 + 3 + 4", il faut impérativement redéfinir dans une classe comme TNumberList.



    Ton code expérimental un peu corrigé (n'utilise pas ToString) ne retourne que

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    1 + 2
    1 + 2 + 3
    1 + 2 + 3 + 4
    1 + 2 + 3 + 4 + 5
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
               ACurrentCombination.Add(AElements[I]);
               generate_combinations(ACurrentCombination, I + 1, ACount);// # Passer à l'élément suivant

    Ta deuxième suggestion est, par contre, tout à faire correcte, Add retournant l'indice de l'objet ajouté autant l'utiliser pour le Delete
    Attention cela fonction uniquement parce que l'on sort le résultat dans TStrings mais si l'on voulait plutôt sortir le résultat sous la forme d'un TObjectList<TList<Byte>> qui est plus intéressant pour les calculs, cela ne fonctionnerait pas sans un Clone() ou alors on pourrait retourner un TArray<TArray<Byte>> qui via le ToArray du TList<Byte> serait très facile à obtenir, un type tout à fait exploitable pour des calculs.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
               K := ACurrentCombination.Add(AElements[I]);
               generate_combinations(ACurrentCombination, I + 1, ACount);// # Passer à l'élément suivant
               // Au pire ici on retire le dernier élément ajouté
               ACurrentCombination.Delete(K);
    au complet

    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
    procedure TForm1.Button6Click(Sender: TObject);
     
      procedure combinations(AResults: TStrings; AElements: TList<Byte>; ACount : Integer);
        ///////////////////
        procedure generate_combinations(ACurrentCombination: TList<Byte>; AStart, ACount: Integer) ;
        var
          I, K: Integer;
          S: string;
        Begin
          if Assigned(ACurrentCombination)  Then
          Begin
            if  (ACurrentCombination.Count = ACount) Then
            begin
              if ACount > 0 then
              begin
                S := IntToStr(ACurrentCombination[0]);
                for I := 1 to ACount - 1 do
                  S := S + ' + ' + IntToStr(ACurrentCombination[I]);
              end;
     
              AResults.Append(S); // Ajouter une copie de la combinaison actuelle
              Exit;
     
            End;
            for I := AStart to AElements.Count - 1 do
            begin
               K := ACurrentCombination.Add(AElements[I]);
               generate_combinations(ACurrentCombination, I + 1, ACount);// # Passer à l'élément suivant
               // Au pire ici on retire le dernier élément ajouté
               ACurrentCombination.Delete(K);
            end;
          end;
        end;
        /////////////////
      Var
        Current : TList<Byte>;
       begin
          Current  :=   TList<Byte>.Create();
          Try
             AResults.BeginUpdate();
             try
                generate_combinations(Current  , 0, ACount);  //# Commencer avec une combinaison vide et l'index 0
             finally
                AResults.EndUpdate();
             end;
          finally
             Current.free;
         end;
       End;
     
    var
      I: Integer;
      Elements: TList<Byte>;
      Chrono: TStopwatch;
    begin
      Elements := TList<Byte>.Create();
      try
        Chrono := TStopwatch.StartNew();
     
        for I := 1 to StrToInt(Edit3.Text) do
          Elements.Add(I);
     
        for I := 2 to Elements.Count do
          combinations(Memo1.Lines,Elements,i);
     
        Chrono.Stop();
        Memo1.Lines.Add(Chrono.ElapsedMilliseconds.ToString() + ' ms');
     
      finally
        Elements.Free();
      end;
    end;
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

Discussions similaires

  1. problème avec les boucles vba
    Par Mon_ami dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 11/04/2009, 06h15
  2. Réponses: 0
    Dernier message: 12/02/2009, 13h07
  3. problème avec les boucle infinies
    Par manciaux dans le forum C
    Réponses: 3
    Dernier message: 14/05/2007, 12h16
  4. [Tableaux] Problème avec les boucles
    Par speed_man002 dans le forum Langage
    Réponses: 4
    Dernier message: 21/09/2005, 15h42

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