Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
No results found
Show changes
Commits on Source (41)
Showing
with 791 additions and 0 deletions
*.o
tri
\ No newline at end of file
Algos_1/Images/graphe_temps.png

102 KiB

#include "../Tris/triInsertion.h"
#include "../Tris/triFusion.h"
#include "../Tris/triRapide.h"
#include "../Tris/triBulle.h"
#include "../Lib/utils.h"
int main(int argc, char **argv){
if(argc<3){
printf("Usage: ./tri <option> <input.txt> d \n");
exit(1);
}
struct data data;
initData(&data);
if((strcmp(argv[1], "--insertion") == 0) || strcmp(argv[1], "-i")== 0){
int n= 0;
long *tab = readToTab(argv[2], &n);
// printf("n:%d\n", n);
// printf("Base : ");
// for(int i = 0; i<n; i++){
// printf("%ld-", tab[i]);
// }
// printf("\n");
triInsertion(tab, n);
// printf("Insertion : ");
// for(int i = 0; i<n; i++){
// printf("%ld-", tab[i]);
// }
// printf("\n");
free(tab);
}
else if(strcmp(argv[1], "--fusion")== 0 || strcmp(argv[1], "-f")== 0){
int n= 0;
long *tab = readToTab(argv[2], &n);
// printf("Base : ");
// for(int i = 0; i<n; i++){
// printf("%ld,", tab[i]);
// }
// printf("\n");
triFusion(tab, n);
// printf("Fusion : ");
// for(int i = 0; i<n; i++){
// printf("%ld,", tab[i]);
// }
// printf("\n");
free(tab);
}
else if((strcmp(argv[1], "--rapide")== 0) || strcmp(argv[1], "-r")== 0){
int n= 0;
long *tab = readToTab(argv[2], &n);
// printf("Base : ");
// for(int i = 0; i<n; i++){
// printf("%ld,", tab[i]);
// }
// printf("\n");
triRapide(tab, n);
// printf("Rapide : ");
// for(int i = 0; i<n; i++){
// printf("%ld,", tab[i]);
// }
// printf("\n");
free(tab);
}
else if((strcmp(argv[1], "--bulle")== 0) || strcmp(argv[1], "-b")== 0){
int n= 0;
long *tab = readToTab(argv[2], &n);
// printf("Base : ");
// for(int i = 0; i<n; i++){
// printf("%ld,", tab[i]);
// }
// printf("\n");
triBulle(tab, n);
// printf("Bulle : ");
// for(int i = 0; i<n; i++){
// printf("%ld,", tab[i]);
// }
// printf("\n");
free(tab);
}
else if (strcmp(argv[1], "-a") == 0)
{
int n= 0;
long *tab = readToTab(argv[2], &n);
printf("Base : ");
for(int i = 0; i<n; i++){
printf("%ld,", tab[i]);
}
printf("\n");
triInsertion(tab, n);
printf("Insertion : ");
for(int i = 0; i<n; i++){
printf("%ld,", tab[i]);
}
printf("\n");
triFusion(tab, n);
printf("Fusion : ");
for(int i = 0; i<n; i++){
printf("%ld,", tab[i]);
}
printf("\n");
triRapide(tab, n);
printf("Rapide : ");
for(int i = 0; i<n; i++){
printf("%ld,", tab[i]);
}
printf("\n");
free(tab);
}
else if (strcmp(argv[1], "-g") == 0)
{
if(argc<3){
printf("Usage: ./tri -g <max> <size>\n");
exit(1);
}
size_t max = atoi(argv[2]);
size_t size = atoi(argv[3]);
long* tab = generate_tab(max, size);
for(size_t i = 0; i<size; i++){
printf("%ld ", tab[i]);
}
printf(".");
printf("\n");
// free(tab);
}
else if((strcmp(argv[1], "--insertion-verbose") == 0) || strcmp(argv[1], "-iv")== 0){
int n= 0;
long *tab = readToTab(argv[2], &n);
printf("Base : ");
for(int i = 0; i<n; i++){
printf("%ld,", tab[i]);
}
printf("\n");
data.time = clock();
triInsertionVerbose(tab, n, &data);
long new_time = (double)clock() - data.time;
data.time = new_time;
printf("Insertion : ");
for(int i = 0; i<n; i++){
printf("%ld,", tab[i]);
}
printf("\n");
printData(data);
free(tab);
}
else if((strcmp(argv[1], "--fusion-verbose") == 0) || strcmp(argv[1], "-fv")== 0){
int n= 0;
long *tab = readToTab(argv[2], &n);
printf("Base : ");
for(int i = 0; i<n; i++){
printf("%ld,", tab[i]);
}
printf("\n");
data.time = clock();
triFusionVerbose(tab, n, &data);
long new_time = (double)clock() - data.time;
data.time = new_time;
printf("Fusion : ");
for(int i = 0; i<n; i++){
printf("%ld,", tab[i]);
}
printf("\n");
printData(data);
free(tab);
}
else if((strcmp(argv[1], "--rapide-verbose") == 0) || strcmp(argv[1], "-rv")== 0){
int n= 0;
long *tab = readToTab(argv[2], &n);
printf("Base : ");
for(int i = 0; i<n; i++){
printf("%ld,", tab[i]);
}
printf("\n");
data.time = clock();
triInsertionVerbose(tab, n, &data);
long new_time = (double)clock() - data.time;
data.time = new_time;
printf("Rapide : ");
for(int i = 0; i<n; i++){
printf("%ld,", tab[i]);
}
printf("\n");
printData(data);
free(tab);
}
else{
printf("Usage: ./tri <option> <input.txt> f\n");
}
return 0;
}
\ No newline at end of file
#include "utils.h"
long* readToTab(char* file, int *sizze){
int fd = open(file, O_RDONLY);
if(fd == -1){
perror("open");
exit(1);
}
int n = 0;
int sizet = 1000, nb_size = 1;
int nb_size_tab = 1;
size_t x=0;
char temp;
char* tmp = malloc(sizeof(char)*sizet);
memset(tmp, 0, sizet);
read(fd,&temp,sizeof(char));
int size_tab = 0;
while(temp != '.'){
if(temp == ' '){
size_tab++;
}
read(fd,&temp,sizeof(char));
}
*sizze = size_tab;
lseek(fd, 0, SEEK_SET);
long *tab = malloc(sizeof(long)*size_tab);
read(fd,&temp,sizeof(char));
while(temp != '.'){
// printf("n:%d j:%d nb_size:%d\n", n,j,nb_size);
if(temp != ' '){
tmp[x] = temp;
//printf("tmp[%d] = %c\n", x, temp);
x++;
}
else{
long t = atol(tmp);
tab[n] = t;
//printf("char:%c long:%d n:%d j:%d nb_size:%d, size:%d\n",temp,tab[j], n,j,nb_size, sizet);
memset(tmp, 0, sizet*nb_size);
x=0;
n++;
}
read(fd,&temp,sizeof(char));
}
// for(int i = 0; i<size_tab; i++){
// if(i%15 == 0)
// printf("i:%ld\n",tab[i]);
// else
// printf("i:%ld ", tab[i]);
// }
free(tmp);
return tab;
}
void initData(struct data* d){
d->time = 0;
d->comparison = 0;
d->ct_fusion = 0;
d->ct_parse = 0;
d->write = 0;
}
long* generate_tab(size_t max, size_t length){
if(length==0){
return 0;
}
long* tab = malloc(sizeof(long)*length+1);
memset(tab, 0, sizeof(long)*length+1);
size_t index = 0;
for(index = 0; index<length; index++){
long p = (long)(rand()%max);
tab[index] = p;
}
return tab;
}
void printData(struct data d){
printf("Time passed : %ld\n", d.time);
printf("Number of comparison : %ld\n", d.comparison);
printf("Number of write : %ld\n", d.write);
printf("Call of fusion : %ld\n", d.ct_fusion);
printf("Call of parsing : %ld\n", d.ct_parse);
}
\ No newline at end of file
#ifndef utils_h
#define utils_h
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <time.h>
#define TAB_SIZE 1000
struct data {
long time;
unsigned int write;
unsigned int comparison;
unsigned int ct_fusion;
unsigned int ct_parse;
};
long* readToTab(char* file, int *sizze);
void initData(struct data* d);
long* generate_tab(size_t max, size_t length);
void printData(struct data d);
#endif
library(ggplot2)
perf <- read.table("perf.dat", header = TRUE)
ggplot(perf, aes(x=taille, y=temps, group=tri, colour=as.character(tri))) + geom_point() +
geom_smooth() + ggtitle("Notre super graphe")
ggsave("graphe.png")
\ No newline at end of file
iTest taille tri temps mem
1 78 fusion 0.00 1592
1 78 insertion 0.00 1512
1 78 rapide 0.00 1508
2 40 fusion 0.00 1416
2 40 insertion 0.00 1488
2 40 rapide 0.00 1524
3 56 fusion 0.00 1532
3 56 insertion 0.00 1460
3 56 rapide 0.00 1460
4 21 fusion 0.00 1472
4 21 insertion 0.00 1496
4 21 rapide 0.00 1476
5 12 fusion 0.00 1492
5 12 insertion 0.00 1520
5 12 rapide 0.00 1512
6 15 fusion 0.00 1516
6 15 insertion 0.00 1468
6 15 rapide 0.00 1468
7 92 fusion 0.00 1496
7 92 insertion 0.00 1508
7 92 rapide 0.00 1528
8 68 fusion 0.00 1592
8 68 insertion 0.00 1456
8 68 rapide 0.00 1488
9 60 fusion 0.00 1488
9 60 insertion 0.00 1512
9 60 rapide 0.00 1508
10 66 fusion 0.00 1456
10 66 insertion 0.00 1528
10 66 rapide 0.00 1472
#!/bin/bash
echo -e "iTest\ttaille\ttri\ttemps\tmem"
for iTest in `seq 1 3`
do
size=$(( `od -An -N4 -tu < /dev/urandom` % 100000))
max=$(( `od -An -N4 -tu < /dev/urandom` % 100000))
../tri -g $max $size 1 >../tabs/perf_tab.txt
for tri in "insertion" "fusion" "rapide" "bulle"
do
res=`( time -f "%U\t%M" ../tri --$tri ../tabs/perf_tab.txt > /dev/null ) 2>&1`
echo -e "$iTest\t$size\t$tri\t$res"
done
rm ../tabs/perf_tab.txt
done
\ No newline at end of file
#!/bin/bash
echo "iTest\ttaille\ttri\ttemps\tmem"
for iTest in `seq 1 3`
do
size=$(( `od -An -N4 -tu < /dev/urandom` % 100000))
max=$(( `od -An -N4 -tu < /dev/urandom` % 100000))
../tri -g $max $size 1 >../tabs/perf_tab.txt
for tri in "insertion" "fusion" "rapide" "bulle"
do
res=`( /usr/bin/time -f "%U\t%M" ../tri --$tri ../tabs/perf_tab.txt > /dev/null ) 2>&1`
echo "$iTest\t$size\t$tri\t$res"
done
rm ../tabs/perf_tab.txt
done
\ No newline at end of file
#include "triBulle.h"
void triBulle(long* A, size_t n){
for(int I = n - 2;I >= 0; I--) {
for(int J = 0; J <= I; J++) {
if(A[J + 1] < A[J]) {
int t = A[J + 1];
A[J + 1] = A[J];
A[J] = t;
}
}
}
}
\ No newline at end of file
#ifndef triBulle_h
#define triBulle_h
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include "../Lib/utils.h"
void triBulle(long* A, size_t n);
#endif
\ No newline at end of file
#include "triFusion.h"
void sousTriFusion(long* A, const size_t p, const size_t r) {
if (p + 1 < r) {
size_t q = (size_t)((p + r) / 2);
sousTriFusion(A, p, q);
sousTriFusion(A, q, r);
fusion(A, p, q, r);
}
}
void fusion(long* A, const size_t p, const size_t q, const size_t r) {
size_t n1 = q - p;
size_t n2 = r - q;
long* Ag = (long*) malloc(n1 * sizeof(long));
long* Ad = (long*) malloc(n2 * sizeof(long));
size_t cursor = 0;
for (size_t i = p; i < q; i++) {
Ag[cursor++] = A[i];
}
cursor = 0;
for (size_t i = q; i < r; i++) {
Ad[cursor++] = A[i];
}
size_t ind_g = 0;
size_t ind_d = 0;
size_t i = p;
while (i < r) {
if (ind_g == n1) {
A[i] = Ad[ind_d++];
}
else if (ind_d == n2) {
A[i] = Ag[ind_g++];
}
else if (Ag[ind_g] < Ad[ind_d]) {
A[i] = Ag[ind_g++];
}
else {
A[i] = Ad[ind_d++];
}
i++;
}
}
void triFusion(long * A, size_t n){
sousTriFusion(A, 0, n);
}
// --------------------------------------------------------
void sousTriFusionVerbose(long * A, size_t p, size_t r, struct data* d){
if(p<(r-1)){
d->comparison++;
size_t q = (size_t)((p+r)/2);
d->write++;
sousTriFusionVerbose(A, p, q,d);
sousTriFusionVerbose(A, q, r, d);
fusionVerbose(A, p, q, r, d);
}
}
void fusionVerbose(long * A, size_t p, size_t q, size_t r, struct data* d){
size_t n1 = q-p;
d->write++;
size_t n2 = r-q;
d->write++;
long Ad[n2];
memset(Ad, 0, n2);
d->write+=n2;
int j = 0;
for(size_t i = q; i<r; i++){
Ad[j] = A[i];
d->write++;
j++;
d->write++;
}
long Ag[n1];
memset(Ag, 0, n1);
d->write+=n1;
j = 0;
for(size_t i = p; i<q; i++){
Ag[j] = A[i];
d->write++;
j++;
d->write++;
}
size_t indg = 0;
size_t indd = 0;
size_t i = p;
d->write++;
while (i < r){
d->comparison++;
if(indg == n1){
d->comparison++;
A[i] = Ad[indd];
d->write++;
indd++;
d->write++;
}
else if(indd == n2){
d->comparison+=2;
A[i] == Ag[indg];
d->write++;
indg++;
d->write++;
}
else if(Ag[indg] < Ad[indd]){
d->comparison+=3;
A[i] = Ag[indg];
d->write++;
indg++;
d->write++;
}
else{
d->comparison+=4;
A[i] = Ad[indd];
d->write++;
indd++;
d->write++;
}
i++;
d->write++;
}
}
void triFusionVerbose(long * A, size_t n, struct data* d){
sousTriFusionVerbose(A, 0, n, d);
}
\ No newline at end of file
#ifndef triFusion_h
#define triFusion_h
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include "../Lib/utils.h"
void sousTriFusion(long * A, size_t p, size_t r);
void fusion(long * A, size_t p, size_t q, size_t r);
void triFusion(long * A, size_t n);
void sousTriFusionVerbose(long * A, size_t p, size_t r, struct data* d);
void fusionVerbose(long * A, size_t p, size_t q, size_t r, struct data* d);
void triFusionVerbose(long * A, size_t n, struct data* d);
#endif
\ No newline at end of file
#include "triInsertion.h"
void triInsertion(long* A, size_t n){
long cle = 0;
for(size_t i = 1; i<n; i++){
cle=A[i];
size_t j = i - 1;
while (j+1 > 0 && A[j] > cle ){
A[j+1] = A[j];
j = j-1;
}
A[j+1] = cle;
}
}
// --------------------------------------------------------
void triInsertionVerbose(long* A, size_t n, struct data* d){
long cle = 0;
d->write++;
for(size_t i = 1; i<n; i++){
cle=A[i];
d->write++;
size_t j = i - 1;
d->write++;
while (j+1 > 0 && A[j] > cle ){
d->comparison+=2;
A[j+1] = A[j];
d->write++;
j = j-1;
d->write++;
}
A[j+1] = cle;
d->write++;
}
}
\ No newline at end of file
#ifndef triInsertion_h
#define triInsertion_h
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include "../Lib/utils.h"
void triInsertion(long* A, size_t n);
void triInsertionVerbose(long* A, size_t n, struct data* d);
#endif
\ No newline at end of file
#include "triRapide.h"
void sousTriRapide(long* A, size_t p, size_t r) {
size_t max = 0; max--;
if(r-1 != max){
if (p<(r-1)) {
size_t q = partition(A, p, r);
sousTriRapide(A, p, q);
sousTriRapide(A, q+1, r);
}
}
}
size_t partition(long* A, size_t p, size_t r) {
long pivot = A[r-1];
size_t i = p;
for (size_t j = p; j <= r-2; j++) {
if (A[j] <= pivot) {
long temp = A[i];
A[i] = A[j];
A[j] = temp;
i++;
}
}
long temp = A[i];
A[i] = A[r-1];
A[r-1] = temp;
return i;
}
void triRapide(long* A, size_t n) {
sousTriRapide(A, 0, n);
}
// --------------------------------------------------------
void sousTriRapideVerbose(long* A, size_t p, size_t r, struct data* d) {
size_t max = 0; max--;
d->write++;
if(r-1 != max){
d->comparison++;
if (p<(r-1)) {
d->comparison++;
size_t q = partitionVerbose(A, p, r, d);
d->write++;
sousTriRapideVerbose(A, p, q, d);
sousTriRapideVerbose(A, q+1, r, d);
}
}
}
size_t partitionVerbose(long* A, size_t p, size_t r, struct data* d) {
long pivot = A[r-1];
d->write++;
size_t i = p;
d->write++;
for (size_t j = p; j <= r-2; j++) {
if (A[j] <= pivot) {
d->comparison++;
long temp = A[i];
d->write++;
A[i] = A[j];
d->write++;
A[j] = temp;
d->write++;
i++;
d->write++;
}
}
long temp = A[i];
d->write++;
A[i] = A[r-1];
d->write++;
A[r-1] = temp;
d->write++;
return i;
}
void triRapideVerbose(long* A, size_t n, struct data* d) {
sousTriRapideVerbose(A, 0, n, d);
}
\ No newline at end of file
#ifndef triRapide_h
#define triRapide_h
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include "../Lib/utils.h"
void triRapide(long* A, size_t n);
size_t partition(long* A, size_t p, size_t r);
void sousTriRapide(long* A, size_t p, size_t r);
void triRapideVerbose(long* A, size_t n, struct data* d);
size_t partitionVerbose(long* A, size_t p, size_t r, struct data* d);
void sousTriRapideVerbose(long* A, size_t p, size_t r, struct data* d);
#endif
\ No newline at end of file
all: tri
tri: Lib/main.c Tris/triBulle.o Tris/triInsertion.o Tris/triFusion.o Tris/triRapide.o Lib/utils.o
gcc -Wall Lib/main.c Tris/triInsertion.o Tris/triFusion.o Tris/triBulle.o Tris/triRapide.o Lib/utils.o -Wall -o tri
insertion: Tris/triInsertion.c Tris/triInsertion.h
gcc -c Tris/triInsertion.c Tris/triInsertion.h -Wall
bulle: Tris/triBulle.c Tris/triBulle.h
gcc -c Tris/triBulle.c Tris/triBulle.h -Wall
fusion: Tris/triFusion.c Tris/triFusion.h
gcc -c Tris/triFusion.c Tris/triFusion.h -Wall
rapide: Tris/triRapide.c Tris/triRapide.h
gcc -c Tris/triRapide.c Tris/triRapide.h -Wall
utils: Lib/utils.c Lib/utils.h
gcc -c Lib/utils.c Lib/utils.h -Wall
clear:
rm Tris/*.o
\ No newline at end of file
# Manuel
Pour utiliser les tris, vous avez besoin de 2 choses:<br>
- Le binaire `tri`<br>
- Un document texte contenant les éléments du tableau, chaque élément est séparé du prochain par un espace et pour finit par un `.`. <br>
Ex : `4 3 11 29 .`<br>
Le binaire demande une option et un fichier, le fichier est du type de ceux définit plus haut, quant aux option il en existe plusieures : <br>
- `-i` ou `--insertion` pour le tri à insertion<br>
- `-f` ou `--fusion` pour le tri à fusion<br>
- `-r` ou `--rapide` pour le tri rapide<br>
- `-a` ou `--all` pour tout les tris disponibles <br>
\ No newline at end of file
83 86 77 15 93 35 86 92 49 21 62 27 90 59 63 26 40 26 72 36 11 68 67 29 82 30 62 23 67 35 29 2 22 58 69 67 93 56 11 42 29 73 21 19 84 37 98 24 15 70 13 26 91 80 56 73 62 70 96 81 5 25 84 27 36 5 46 29 13 57 24 95 82 45 14 67 34 64 43 50 87 8 76 78 88 84 3 51 54 99 32 60 76 68 39 12 26 86 94 39 95 70 34 78 67 1 97 2 17 92 52 56 1 80 86 41 65 89 44 19 40 29 31 17 97 71 81 75 9 27 67 56 97 53 86 65 6 83 19 24 28 71 32 29 3 19 70 68 8 15 40 49 96 23 18 45 46 51 21 55 79 88 64 28 41 50 93 0 34 64 24 14 87 56 43 91 27 65 59 36 32 51 37 28 75 7 74 21 58 95 29 37 35 93 18 28 43 11 28 29 76 4 43 63 13 38 6 40 4 18 28 88 69 17 17 96 24 43 70 83 90 99 72 25 44 90 5 39 54 86 69 82 42 64 97 7 55 4 48 11 22 28 99 43 46 68 40 22 11 10 5 1 61 30 78 5 20 36 44 26 22 65 8 16 82 58 24 37 62 24 0 36 52 99 79 50 68 71 73 31 81 30 33 94 60 63 99 81 99 96 59 73 13 68 90 95 26 66 84 40 90 84 76 42 36 7 45 56 79 18 87 12 48 72 59 9 36 10 42 87 6 1 13 72 21 55 19 99 21 4 39 11 40 67 5 28 27 50 84 58 20 24 22 69 96 81 30 84 92 72 72 50 25 85 22 99 40 42 98 13 98 90 24 90 9 81 19 36 32 55 94 4 79 69 73 76 50 55 60 42 79 84 93 5 21 67 4 13 61 54 26 59 44 2 2 6 84 21 42 68 28 89 72 8 58 98 36 8 53 48 3 33 33 48 90 54 67 46 68 29 0 46 88 97 49 90 3 33 63 97 53 92 86 25 52 96 75 88 57 29 36 60 14 21 60 4 28 27 50 48 56 2 94 97 99 43 39 2 28 3 0 81 47 38 59 51 35 34 39 92 15 27 4 29 49 64 85 29 43 35 77 0 38 71 49 89 67 88 92 95 43 44 29 90 82 40 41 69 26 32 61 42 60 17 23 61 81 9 90 25 96 67 77 34 90 26 24 57 14 68 5 58 12 86 0 46 26 94 16 52 78 29 46 90 47 70 51 80 31 93 57 27 12 86 14 55 12 90 12 79 10 69 89 74 55 41 20 33 87 88 38 66 70 84 56 17 6 60 49 37 5 59 17 18 45 83 73 58 73 37 89 83 7 78 57 14 71 29 0 59 18 38 25 88 74 33 57 81 93 58 70 99 17 39 69 63 22 94 73 47 31 62 82 90 92 91 57 15 21 57 74 91 47 51 31 21 37 40 54 30 98 25 81 16 16 2 31 39 96 4 38 80 18 21 70 62 12 79 77 85 36 4 76 83 7 59 57 44 99 11 27 50 36 60 18 5 63 49 44 11 5 34 91 75 55 14 89 68 93 18 5 82 22 82 17 30 93 74 26 93 86 53 43 74 14 13 79 77 62 75 88 19 10 32 94 17 46 35 37 91 53 43 73 28 25 91 10 18 17 36 63 55 90 58 30 4 71 61 33 85 89 73 4 51 5 50 68 3 85 6 95 39 49 20 67 26 63 77 96 81 65 60 36 55 70 18 11 42 32 96 79 21 70 84 72 27 34 40 83 72 98 30 63 47 50 30 73 14 59 22 47 24 82 35 32 4 54 43 98 86 40 78 59 62 62 83 41 48 23 24 72 22 54 35 21 57 65 47 71 76 69 18 1 3 53 33 7 59 28 6 97 20 84 8 34 98 91 76 98 15 52 71 89 59 6 10 16 24 9 39 0 78 9 53 81 14 38 89 26 67 47 23 87 31 32 22 81 75 50 79 90 54 50 31 13 57 94 81 81 3 20 33 82 81 87 15 96 25 4 22 92 51 97 32 34 81 6 15 57 8 95 99 62 97 83 76 54 77 9 87 32 82 21 66 63 60 82 11 85 86 85 30 90 83 14 76 16 20 92 25 28 39 25 90 36 60 18 43 37 28 82 21 10 55 88 25 15 70 37 53 8 22 83 50 57 97 27 26 69 71 51 49 10 28 39 98 88 10 93 77 90 76 99 52 31 87 77 99 57 66 52 17 41 35 68 98 84 95 76 5 66 28 54 28 8 93 78 97 55 72 74 45 0 25 97 83 12 27 82 21 93 34 39 34 21 .