-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpascal.cpp
More file actions
85 lines (71 loc) · 2.54 KB
/
pascal.cpp
File metadata and controls
85 lines (71 loc) · 2.54 KB
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
// g++ -o pascal pascal.cpp -lflint -L/usr/local/lib
#include <iostream>
#include <string>
#include <climits>
#include <flint/fmpz.h>
using namespace std;
// Programme : afficher la n-ième ligne du triangle de Pascal (coefficients binomiaux)
// Utilisation : ./pascal_fmpz <n> ou echo <n> | ./pascal_fmpz
// - n peut être un entier très grand (lu en base 10 dans un fmpz)
// - le programme n'affiche la ligne complète que si n tient dans un unsigned long
// (il est impossible de boucler n fois si n dépasse la capacité d'indexation du programme).
// - tout est calculé en fmpz (entiers de FLINT) pour garder la précision.
int main(int argc, char** argv)
{
string s;
if (argc >= 2) {
s = argv[1];
} else {
if (! (cin >> s)) {
cerr << "Erreur : aucun entier fourni en argument ou stdin" << endl;
return 1;
}
}
fmpz_t n;
fmpz_init(n);
if (fmpz_set_str(n, s.c_str(), 10) != 0) {
cerr << "Erreur : impossible de parser l'entier '" << s << "'" << endl;
fmpz_clear(n);
return 2;
}
// Cas n < 0
if (fmpz_sgn(n) < 0) {
cerr << "Erreur : n doit etre >= 0" << endl;
fmpz_clear(n);
return 3;
}
// On ne peut pas itérer jusqu'à n si n ne tient pas dans un unsigned long.
// On vérifie donc si n tient dans un unsigned long (fmpz_fits_ulong_p).
// Vérification que n tient dans un unsigned long : n <= ULONG_MAX
if (fmpz_cmp_ui(n, ULONG_MAX) > 0) {
cerr << "n est trop grand pour iterer (ne tient pas dans unsigned long)." << endl;
cerr << "Impossible d'afficher la ligne complete du triangle de Pascal dans ce cas." << endl;
fmpz_clear(n);
return 4;
}
unsigned long n_ui = fmpz_get_ui(n);
// On imprimera les coef de la ligne n : C(n,0) ... C(n,n)
// On utilise une formule multiplicative en fmpz :
// C(n,k) = C(n,k-1) * (n - k + 1) / k
// avec division exacte par k (k est un entier petit, on utilise fmpz_divexact_ui).
fmpz_t c;
fmpz_init(c);
fmpz_set_ui(c, 1); // C(n,0) = 1
// Impression de la première valeur
fmpz_print(c);
unsigned long k, mult;
for (k = 1; k <= n_ui; ++k) {
mult = n_ui - k + 1; // tient dans unsigned long parce que n_ui tient
// c = c * mult
fmpz_mul_ui(c, c, mult);
// c = c / k (division exacte)
fmpz_divexact_ui(c, c, k);
// afficher c
cout << ' ';
fmpz_print(c);
}
cout << endl;
fmpz_clear(c);
fmpz_clear(n);
return 0;
}