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).
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).
Si (a,b,c,d,e) est un 5 uple candidat vérifiant:Zavonen, peux-tu expliquer ces dix valeurs de v?
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...)
Je crois que là-dessus tout le monde est d'accord.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.
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...)
Je pense que oui, car, comme je le disais plus haut, sans cette hypothèse on reste bloqué dès la deuxième heure.Envoyé par Zavonen
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
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ï
Jedai a tout bon !
Nemerle, mathématicopilier de bars, membre du triumvirat du CSTM, 3/4 centre
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.
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éEnvoyé par Nemerle
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ï
Est-ce que tu pourrais nous montrer ton programme ?Envoyé par sovitec
--
Jedaï
J'ai un peu honte, j'ai bricolé ça en une heure mais enfin :Envoyé par Jedai
Sovitec
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;
PS : le Haskell c'est encore plus illisble que le perl
ANemerle comme nom de variable ?
Nemerle, mathématicopilier de bars, membre du triumvirat du CSTM, 3/4 centre
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...Envoyé par sovitec
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ï
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ï
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.
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ï
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.Envoyé par Jedai
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.
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...)
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ï
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager