Projet langage C : Le Compte Est Bon

Documents pareils
1. Structure d un programme C. 2. Commentaire: /*..texte */ On utilise aussi le commentaire du C++ qui est valable pour C: 3.

Le prototype de la fonction main()

1/24. I passer d un problème exprimé en français à la réalisation d un. I expressions arithmétiques. I structures de contrôle (tests, boucles)

Cours d Algorithmique-Programmation 2 e partie (IAP2): programmation 24 octobre 2007impérative 1 / 44 et. structures de données simples


Le Langage C Version 1.2 c 2002 Florence HENRY Observatoire de Paris Université de Versailles florence.henry@obspm.fr

Compression de Données - Algorithme de Huffman Document de Conception

Éléments d informatique Cours 3 La programmation structurée en langage C L instruction de contrôle if

V- Manipulations de nombres en binaire

MISE A NIVEAU INFORMATIQUE LANGAGE C - EXEMPLES DE PROGRAMMES. Université Paris Dauphine IUP Génie Mathématique et Informatique 2 ème année

Les structures de données. Rajae El Ouazzani

Cours d initiation à la programmation en C++ Johann Cuenin

3IS - Système d'exploitation linux - Programmation système

Programmation système I Les entrées/sorties

Bases de programmation. Cours 5. Structurer les données

TP n 2 Concepts de la programmation Objets Master 1 mention IL, semestre 2 Le type Abstrait Pile

Suivant les langages de programmation, modules plus avancés : modules imbriqués modules paramétrés par des modules (foncteurs)

PROJET ALGORITHMIQUE ET PROGRAMMATION II

Cours 6 : Tubes anonymes et nommés

Les structures. Chapitre 3

Architecture des ordinateurs

Chapitre 1 : La gestion dynamique de la mémoire

Programmation en langage C

Info0101 Intro. à l'algorithmique et à la programmation. Cours 3. Le langage Java

Arguments d un programme

IN Cours 1. 1 Informatique, calculateurs. 2 Un premier programme en C

Le langage C. Séance n 4

Cours de Programmation Impérative: Zones de mémoires et pointeurs

Introduction au langage C

Travaux pratiques. Compression en codage de Huffman Organisation d un projet de programmation

Centre CPGE TSI - Safi 2010/2011. Algorithmique et programmation :

Programmation Classique en langage C

Licence Bio Informatique Année Premiers pas. Exercice 1 Hello World parce qu il faut bien commencer par quelque chose...

Algorithmique, Structures de données et langage C

Cours de C. Petits secrets du C & programmation avancée. Sébastien Paumier

Prénom : Matricule : Sigle et titre du cours Groupe Trimestre INF1101 Algorithmes et structures de données Tous H2004. Loc Jeudi 29/4/2004

SUPPORT DE COURS. Langage C

DE L ALGORITHME AU PROGRAMME INTRO AU LANGAGE C 51

Conventions d écriture et outils de mise au point

Archivage Messagerie Evolution pour usage HTML en utilisant Hypermail

I. Introduction aux fonctions : les fonctions standards

INF 104 (SELC) Introduction au langage C

Travaux Dirigés n 1 : chaînes de caractères

Cours de C++ François Laroussinie. 2 novembre Dept. d Informatique, ENS de Cachan

Programmation système de commandes en C

Introduction à la programmation orientée objet, illustrée par le langage C++ Patrick Cégielski

Claude Delannoy. 3 e édition C++

Corrigés des premiers exercices sur les classes

Java Licence Professionnelle CISII,

Premiers Pas en Programmation Objet : les Classes et les Objets

Programmation C++ (débutant)/instructions for, while et do...while

Chap III : Les tableaux

Brefs rappels sur la pile et le tas (Stack. / Heap) et les pointeurs

COMPARAISONDESLANGAGESC, C++, JAVA ET

Rappels Entrées -Sorties

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP

Initiation. àl algorithmique et à la programmation. en C

Architecture des ordinateurs TD1 - Portes logiques et premiers circuits

INITIATION A LA PROGRAMMATION

#include <stdio.h> #include <stdlib.h> struct cell { int clef; struct cell *suiv; };

03/04/2007. Tâche 1 Tâche 2 Tâche 3. Système Unix. Time sharing

Introduction au Langage de Programmation C

Cours de C. Allocation dynamique. Sébastien Paumier

Programmation C. Apprendre à développer des programmes simples dans le langage C

Cours intensif Java. 1er cours: de C à Java. Enrica DUCHI LIAFA, Paris 7. Septembre Enrica.Duchi@liafa.jussieu.fr

OS Réseaux et Programmation Système - C5

Langage C. Patrick Corde. 22 juin Patrick Corde ( Patrick.Corde@idris.fr ) Langage C 22 juin / 289

I00 Éléments d architecture

DU BINAIRE AU MICROPROCESSEUR - D ANGELIS CIRCUITS CONFIGURABLES NOTION DE PROGRAMMATION

Cours d Algorithmique et de Langage C v 3.0

La mémoire. Un ordinateur. L'octet. Le bit

Représentation des Nombres

Introduction à Java. Matthieu Herrb CNRS-LAAS. Mars

Utilisation d objets : String et ArrayList

INTRODUCTION A JAVA. Fichier en langage machine Exécutable

Cours Programmation Système

EPREUVE OPTIONNELLE d INFORMATIQUE CORRIGE

Algorithmique et Programmation, IMA

Les fichiers. Chapitre 4

INF111. Initiation à la programmation impérative en C amini/cours/l1/inf111/ Massih-Reza Amini

Arithmétique binaire. Chapitre. 5.1 Notions Bit Mot

TP2 : tableaux dynamiques et listes chaînées

Exercices types Algorithmique et simulation numérique Oral Mathématiques et algorithmique Banque PT

MINIMUM. connaissances nécessaires à la programmation des microcontrôleurs PIC18 en langage C (une introduction au langage c A.N.S.

Cours Langage C/C++ Programmation modulaire

Simulation : application au système bonus-malus en responsabilité civile automobile

Licence Sciences et Technologies Examen janvier 2010

Université Bordeaux 1, Licence Semestre 3 - Algorithmes et struct...

UEO11 COURS/TD 1. nombres entiers et réels codés en mémoire centrale. Caractères alphabétiques et caractères spéciaux.

Programmer en JAVA. par Tama

PROJET 1 : BASE DE DONNÉES REPARTIES

Informatique Générale

TP 1. Prise en main du langage Python

as Architecture des Systèmes d Information

MICROINFORMATIQUE NOTE D APPLICATION 1 (REV. 2011) ARITHMETIQUE EN ASSEMBLEUR ET EN C

STAGE IREM 0- Premiers pas en Python

Programmation en C. École Nationale Supérieure de Techniques Avancées. Pierre-Alain Fouque et David Pointcheval

TD3: tableaux avancées, première classe et chaînes

Programmation système en C/C++

Transcription:

BERHAULT Guillaume / BERICHON Richard BERNARD François BENCHEKROUN Tarik Projet langage C : Le Compte Est Bon Le Compte Est Bon BERHAULT/BERICHON BERNARD/BENCHEKROUN 1

SOMMAIRE I. Présentationdu projet p.3 II. III. Méthode p4 Donnée p6 Structure élément p6 Définition des prototypes p7 Manipulation structure p7 Ecriture fichiers p8 Affichage p8 Manipulation Pile p9 Quitter programme p9 Validation opération à effectuer p9 Vérification arguments p10 Génération SPInitiale p10 IV. Algorithmes principaux p11 1. Définition p11 2. Validation des calculs p11 3. Quitter Programme p12 4. Historique p12 5. Générer SP6 p13 6. Générer valeurs restantes p15 7. Programme principal p15 V. Implémentation en C p17 Main.c p17 Pile.c p18 Structure element.c p18 Traitement arguments.c p19 Quitter Programme.c p21 Element.c p22 Affichage.c p25 Validation Calcul.c p27 Ecrire.c p28 Le Compte Est Bon BERHAULT/BERICHON BERNARD/BENCHEKROUN 2

Présentation du projet Le but de ce projet est de déterminer la solution menant à un résultat, choisi ou générer aléatoirement, avec des combinaisons de 6 entiers positifs, choisis délibérément ou aléatoirement. Nous disposons de 6 entiers positifs choisis parmi 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 25, 50, 75, 100 et d un entier N compris entre 101 et 999 qui représente le résultat à trouver. En entrée, l utilisateur choisi les valeurs avec lesquelles trouver son résultat, sinon le résultat et les entiers seront choisis aléatoirement. Si l entrée est erronée, alors le programme se termine avec un message d erreur. Pour aboutir à N, nous pouvons utiliser au plus 6 des entiers initiaux en les combinant avec les 4 opérations arithmétiques : +, -, *, /. La division n est effectuée que si les deux entiers sont divisibles. De même la soustraction n est possible que si la différence des deux est positive. Par exemple : Si aucune combinaison ne mène au résultat il faudra alors afficher la solution la plus proche ainsi que les calculs y ayant menés. Remarque : Dans la suite on appellera indifféremment SP x et élément, une solution potentielle contenant une suite de x nombres, ces nombres étant soit des entiers de départ soit un entier obtenu à partir de ceux-ci. Elément ne comporte pas d indice de taille contrairement à SP x et ne sera utilisé s il n y a pas d ambigüité. Le Compte Est Bon BERHAULT/BERICHON BERNARD/BENCHEKROUN 3

Méthodes Au début nous disposons d une seule solution potentielle contenant les 6 entiers de départ, appelée SP6. Nous calculons toutes les combinaisons possibles deux à deux, formant ainsi les solutions potentielles ne contenant plus que 5 valeurs, SP5, avec lesquelles effectuer les calculs. Ainsi de suite jusqu à ce qu il ne reste que des SP1. Afin de conserver les calculs ayant menés aux valeurs intermédiaires nous les stockons dans un historique. Entrée Test Résultat Trouvé Ou Résultat plus proche Analyse Générer SP5 Générer SP4 ------ Affichage Sortie d erreur Gestion des calculs Pour effectuer les calculs, nous devons générer des ensembles de solutions potentielles. Pour ce faire nous pouvons les stocker dans un sac et à chaque nouvel élément pris dedans, nous générons les autres solutions potentielles que nous remettons à l intérieur du sac. A chaque calcul effectué, un test de résultat et / ou de résultat plus proche est effectué. Si un résultat est détecté alors l élément n est pas remis dans le sac. Considérons que les SP1 ne soient pas remises dans le sac, car elles ne serviront pas à la création de nouveaux éléments. Deux approches de gestion des calculs se présentent : Première approche : On génère toutes les SPn-1 à partir des SPn, on supprime les SPn, puis on génère toutes les SPn-2 à partir des SPn-1 et on supprime les SPn-1 etc.on devrait conserver en mémoire 2.764.800 éléments dans le pire des cas si l on conserve les éléments n ayant plus qu une valeur restante : SP6>1 élément de 6 valeurs SP5>1 élément* 6 *4opérateurs=60 éléments de 5 valeurs 2 SP4>60 éléments* 5 *4opérateurs=2.400 éléments de 4 valeurs 2 SP3>2.400 éléments* 4 *4opérateurs=57.600 éléments de 3 valeurs 2 SP2>57.600 éléments* 3 *4opérateurs=691.200 éléments de 2 valeurs 2 SP1>691.200 éléments* 2 *4opérateurs=2.764.800 éléments de 1 valeur 2 Le Compte Est Bon BERHAULT/BERICHON BERNARD/BENCHEKROUN 4

Deuxième approche : On prend une SPn, que l on enlève à l ensemble de SPn, et avec laquelle on génère toutes les SPn-1 possibles. On prend ensuite une SPn-1 pour former les SPn-2 de la même manière. On recommence ainsi jusqu à avoir formé l ensemble des SP1. Une fois l ensemble de SP1 produit et vérifié, on les retire, puis on reprend une SP2 qui crée alors d autres SP1, et ainsi de suite jusqu à ce qu il n y ait plus d éléments... Un calcul détaillé, ci-dessous, montre que cette méthode demande de conserver en mémoire au plus 128 éléments. Notation : SP x =ensemble de SP x. SP6 / 1 élément SP6 / 0 élément SP5 / 60 éléments SP6 / 0 élément SP5 / 59 éléments SP4 / 40 éléments SP6 / 0 élément SP5 / 59 éléments SP4 / 39 éléments SP3 / 16 éléments SP6 / 0 élément SP5 / 59 éléments SP4 / 39 éléments SP3 / 15 éléments SP2 / 12 éléments SP6 / 0 élément SP5 / 59 éléments SP4 / 39 éléments SP3 / 15 éléments SP2 / 11 éléments SP1 / 4 éléments Total de 128 éléments maximum Au vu des résultats, il semble évident qui nous allons utiliser la deuxième approche. Le Compte Est Bon BERHAULT/BERICHON BERNARD/BENCHEKROUN 5

Données Structure de données : Si l utilisateur entre lui-même les différents paramètres, alors l entrée est sous forme de texte. Il faut alors l analyser pour chercher les erreurs et s il n y en a pas, le programme va récupérer la valeur des 6 entiers ainsi que celle du résultat. Si l utilisateur n entre aucun paramètre alors les 6 entiers et le résultat sont choisis aléatoirement par l ordinateur et fourni au programme. Les SP ou éléments, contiennent les valeurs nécessaires aux calculs qui suivent ainsi qu un historique des calculs effectués. Ces données sont stockées dans des tableaux. Ce choix se justifie du fait que l historique contient au maximum 30 éléments et que le tableau des valeurs avec lesquelles effectuer les calculs est de taille 6 au maximum. Les tailles étant prévisibles il n est pas nécessaire de faire d allocation dynamique. Enfin, le choix d une pile comme sac de solutions potentielles semble parfaitement adapté. En effet, la pile ne comporte au départ que notre SP6 qui sera dépilée afin de créer l ensemble de SP5 contenant au plus 60 éléments qui seront rempilés. Parmi ses 60 éléments on va dépiler l élément au sommet et l utiliser afin de fabriquer un premier ensemble de SP4. Ainsi de suite jusqu à ce que la pile soit vide. De plus, la pile permet ce type de traitement des calculs contrairement à une file. Et enfin un arbre aurait pu être envisageable, mais sa complexité n était pas nécessaire. Structure Elément : struct selement long int historique[30]; int taillehistorique; long int valeursrestantes[6]; int taillevaleursrestantes; // long int car les calculs intermédiaires peuvent atteindre 937.500.500 donc il faut au plus 32bits. Mais suivant l architecture de l ordinateur, un int peut varier entre 16bits et plus. // Les tailles servent à savoir où l on en est dans les calculs et intervient donc dans les fonctions d écriture et de modifications de l élément.(voir ciaprès) Le Compte Est Bon BERHAULT/BERICHON BERNARD/BENCHEKROUN 6

Définition des prototypes Fonctions de manipulation de la structure élément : void initialiserelement(element); Cette fonction met à zéro taillehistorique et taillevaleursrestantes. void ModifierHistorique(element e1,long int valeurg,int operateur,long int valeurd); Cette fonction complète l historique de e1 en y inscrivant valeurg operateur valeurd=resultat. Exemple : ModifierHistorique(e1,5,ADD,4) écrit dans l historique 5+4=9 avec des long int. void ModifierTailleHistorique(element e, int increment); La valeur de taillehistorique de l élément e est incrémentée (algébriquement) de la valeur donnée en paramètre. void GenererValeursRestantes(element e1, element e2, int indice1, int indice2, char operateur); Cette fonction écrit dans la première case de valeursrestantes de e2, la valeur de l opération prenant comme paramètre de gauche et de droite, respectivement la «indice1-ième» et la «indice2-ième» valeur de valeurrestantes de e2, et pour opérande un choix parmi +,-,*,/, indiqué par le paramètre «operateur». Ce choix est effectué de la manière suivante : ADD + SUB - MUL * DIV / Remarque : ADD, SUB, MUL et DIV sont définis par des directives au préprocesseur. void ModifierTailleValeursRestantes(element e, int increment); La valeur de taillevaleursrestantes de l élément e est incrémentée (algébriquement) de la valeur donnée en paramètre. int TailleValeursRestantes(element e) ; Elle prend en paramètre un élément et retourne son numéro de SP (retourne 5 si l élément est une SP5). Le Compte Est Bon BERHAULT/BERICHON BERNARD/BENCHEKROUN 7

long int iemevaleursrestantes(element e, int i); Retourne la valeur de la ième case de valeursrestantes[] de l élément donné en paramètre. long int iemehistorique(element,int i); Retourne la valeur de la ième case de historique[] de l élément donné en paramètre. long int ieme(long int [],int); Retourne la ieme valeur d un tableau de long int. void RecopierHistorique(element e1, element e2); Cette fonction recopie l historique de e1 dans e2. int TailleHistorique(element e); Retourne la taille de l historique de l élément donné en paramètre Fonctions d ériture dans fichier : void ecrire (char *fichier, element e); Si lors de la génération d un élément, le calcul effectué est égal au résultat recherché, alors cet élément est transmi à cette fonction «ecrire», ainsi que le nom du fichier dans lequel enregistrer l historique de cet élément. D autres cas peuvent se présenter, dont voici le listing : Valeur calculée=résultat recherché écriture de l historique dans ceb.txt Si en plus l historique de cette élément est le plus petit des résultats valides trouvés écriture de l historique dans best.txt Si le calcul d un élément donne une solution plus proche du résultat que les valeur précédemment calculée écriture de l historique dans pp.txt Le premier appel de cette fonction supprime les fichiers ceb.txt et best.txt éventuellement présents dans le dossier du programme. Fonctions d affichage void affichageinitial(element e,int resultat); Cette fonction permet l affichage des «valeursrestantes» d une SP6 et du résultat. Elle est utilisé ici en début de programme afin d afficher divers informations lors du lancement du programme. void affichageterminal(int t,int*nbresultats,int ecartmin); Cette fonction sert à afficher les solutions trouvées ou, en cas d échec, celui le plus proche. Dans ce cas elle affiche l écart par rapport au résultat ainsi que le calcul effectué en lisant pp.txt. Le Compte Est Bon BERHAULT/BERICHON BERNARD/BENCHEKROUN 8

Fonction de manipulation de Pile Pile creerpile(); Comme son nom l indique, cette fonction crée une pile. int pilevide(pile); Cette fonction retourne 1 ou 0 selon que la pile donnée en paramètre soit vide ou non. element sommet(pile); Retourne l élément au sommet de la pile. Pile depiler(pile); Retourne la même pile que celle donnée en paramètre en y enlevant l élément au sommet. Pile empiler(element,pile); Ajoute «element» au sommet de la pile et retourne le nouveau pointeur de pile. Fonction permettant de quitter le programme en cas d erreur void QuitterProgramme(int a) ; Cette fonction permet de quitter le programme en cas d erreur. Elle écrit sur la sortie d erreur standard la raison de son appel. Fonction de validation des opérations effectuées int validationcalcul(long int valeurg,int operateur,long int valeurd); Cette fonction très importante permet d éviter les opérations inutiles comme les divisions et les multiplications par 1. Elle évite aussi de créer des valeurs nulles, totalement inutiles dans la recherche de solutions. Elle prend donc en paramètre deux entiers et un opérateur reconnu de cette façon : 1 + 2-3 * 4 / Le Compte Est Bon BERHAULT/BERICHON BERNARD/BENCHEKROUN 9

Fonction de vérification des arguments void ValidationArguments(int*ats,int argc,char**argv); Cette fonction permet de détecter les éventuel arguments transmis au programme. Elle vérifie que les 6 valeurs de départ soient bien entrée et qu elles soient toutes comprises entre 1 et 100. Le résultat doit être un entier entre 100 et 999. L option t permettant l affichage de toutes les solutions est également prise en compte par le programme par l intermédiaire de cette fonction. En cas de non spécifications des éléments à utiliser et de résultat à trouver, cette fonction en générera aléatoirement (en accord avec la liste autorisée). Fonction de génération de la SP de départ GenerationSP6(element e, int*resultat,int argc, char**argv); Permet la génération de la SP6 de départ à partir des arguments donnés au programme ou, si aucun paramètre n est fourni, les valeurs des entiers et du résultat sont générés aléatoirement par le programme. Le Compte Est Bon BERHAULT/BERICHON BERNARD/BENCHEKROUN 10

Algorithmes principaux 1. Définitions Dans tout ce qui suivra 0 représentera la valeur booléenne fausse, et 1 la valeur vraie. 2. Validation des Calculs Une étape essentielle du programme est la validation des calculs possibles. En effet 7/5 n est pas possible car 7 et 5 sont premier entre eux. Il ne faut pas effectuer ce calcul sinon il serait nul et pourrait entrainer un division par zéro ce qui est une exception arithmétique. entier validationcalcul (entier valeurg,entier operateur,entier valeurd) caractère operation; si operateur =1 alors operation + ; sinon si operateur =2 alors operation - ; sinon si operateur =3 alors operation * ; sinon si operateur =4 alors operation / ; Si operation='+' retourner 1 Sinon si operation= * Si valeurg=1 ou valeurd=1 // on ne garde pas les multiplications inutiles comme x*1 retourner 0 Sinon retourner 1 sinon si operation='/ si valeurg=1 ou valeurd=1 // on ne garde pas les divisions triviales comme x/1 retourner 0 sinon si valeurg=0 (valeurd) ou valeurd=0 (valeurg) // a=x(b) signifie a=x modulo (b) retourner 1 sinon retourner 0 sinon si operation='-' si (valeurg-valeurd)= 0 retourner 0 sinon retourner 1 sinon QuitterProgramme(3); //Quitte le programme avec la raison 3 définit ci-après Le Compte Est Bon BERHAULT/BERICHON BERNARD/BENCHEKROUN 11

3. Quitter Programme QuitterProgramme(entier a) Si a=0 «Erreur : Donnez 6 entiers de départ (-n) : 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 25 50 75 100\net le resultat (-r) compris entre 101 et 999» Si a=1 «Erreur : Le resultat a trouver n'est pas valide: donner un entier entre 101 et 999» Si a=2 «Erreur : Pas assez d'arguments» Si a=3 «Erreur : Parametres de validationcalcul errones» 4. Historique L historique d un élément est une part essentiel du processus «le compte est bon». En effet il va nous permettre de conserver les calculs déjà utilisés pour générer l élément en question. On considère ici l historique comme un stockage de données des opérations déjà effectuées, modifié par la fonction modifier_historique. Initialement sa taille et ses composantes sont nulles. Void modifier_historique(entier e, entier valeurg, operateur op, entier valeurd) entier compteur 0; pour compteur=0 jusqu'à 5 si compteur = 0 alors ecrire_historique (e, compteur, valeurg); // historique de e : valeurg sinon si compteur = 1 alors ecrire_historique (e, compteur, op); // historique de e : valeurg op sinon si compteur = 2 alors ecrire_historique (e, compteur, valeurd); // historique de e : valeurg op valeurd sinon si compteur = 3 alors ecrire_historique (e, compteur, '='); // historique de e : valeurg op valeurd = sinon si compteur = 4 alors ecrire_historique (e, compteur, ieme_valeur_restante(e1, 0)); // historique de e : valeurg op valeurd = resultat de l opération sinon si compteur = 5 alors ecrire_historique (e, compteur, ')'); compteur compteur+1; modifier_taille_historique (e, 6); Le Compte Est Bon BERHAULT/BERICHON BERNARD/BENCHEKROUN 12

5. Générer notre élément initial (SP6) Elle a pour but de récupérer les 6 entiers de départ ainsi que le résultat, sinon le programme génère automatiquement des valeurs aléatoires. generersp6 (element e, entier resultat, entier argc, chaine de caractères argv[]) entier ValeursInitiales[] 1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,25,50,75,100 // valeurs prises par le // mécanisme de choix aléatoire entier ValeursInitialesUtilisees[6] Si argc>2 alors entiers i,j 0; pour i=1 à i<argc //on traite ici l'option -n pour la saisie des éléments de base Si argv[i]="-n" et argc<10 alors QuitterProgramme(0); Si argv[i]="-n" et argc>10 alors Tant que j 6 Si argv[i+1+j]="-t" ou argv[i+1+j]="-r" ou argv[i+1+j] 0 QuitterProgramme(0) Sinon si argv[i+1+j]>=0 ou argv[i+1+j]<100 ModifierValeursRestantes(e,j,argv[i+1+j]) // A la j ème place du tableau des valeurs // restantes de e, on change de valeur. ModifierTailleValeursRestantes(e,1) // La taille des valeurs restantes de e est égale à 1 j=j+1 i=i+1 Pour i=1 à i<argc //on traite l'option -r pour la saisie du resultat a trouver Si argv[i]="-r" Si argv[i+1])>=101 et argv[i+1]<=999 // On vérifie que le résultat est dans le bon intervalle resultat argv[i+1] sinon QuitterProgramme(1); // quitter pour cause de paramètres invalides i=i+1 Le Compte Est Bon BERHAULT/BERICHON BERNARD/BENCHEKROUN 13

Sinon // trop peu de paramètre, donc génération aléatoire entier i,k,rd random modulo(24),m 0 // 24 élément dans le tableau de valeurs ValeursInitialesUtilisees[0] rd // on stocke les indices des éléments utilisés pour ne pas prendre 6 fois le même! ModifierValeursRestantes(e,0,ValeursInitiales[rd]) ModifierTailleValeursRestantes(e,1); pour i=1 à i<6 m 0; rd random modulo(24) pour k=0 à k<i //on teste pour ne pas utiliser 6 fois le même nombre par exemple. Si rd=valeursinitialesutilisees[k] m 1; // element du tableau déjà utilisé Si m 1 ValeursInitialesUtilisees[i] rd ModifierValeursRestantes(e,i,ValeursInitiales[rd]) ModifierTailleValeursRestantes(e,1) i i+1 sinon i i-1 // on recommence avec le même i. resultat random modulo(1000) // resultat compris entre 0 et 999 tant que resultat<101 resultat random modulo(1000) // on s assure que résultat soit supérieur à 101. Le Compte Est Bon BERHAULT/BERICHON BERNARD/BENCHEKROUN 14

6. Générer Valeurs restantes void GenererValeursRestantes(element e1, element e2, entier indice1, entier indice2, operateur) entier curseur1 0, curseur2 1, TVR TailleValeursRestantes(e1), VRe11 ValeursRestantes(e1,indice1), VRe12 ValeursRestantes(e1,indice2) Si operateur = + alors ModifierValeursRestantes(e2,0,VRe11+VRe12) Si operateur = - alors ModifierValeursRestantes(e2,0,abs(VRe11-VRe12)) Si operateur = * alors ModifierValeursRestantes(e2,0,VRe11*VRe12) Si operateur = / Si VRe11 est divisible par VRe12 Sinon ModifierValeursRestantes(e2,0,VRe11/VRe12) ModifierValeursRestantes(e2,0,VRe12/VRe11) Tant que curseur1<tvr) Si curseur1 indice1 et curseur1 indice2 ModfierValeursRestantes(e2,curseur2,iemeValeursRestantes(e1,curseur1)); curseur2 curseur2 + 1 curseur1 curseur1 + 1 ModifierTailleValeursRestantes(e2,TVR-1); 7. Programme Principal Pile P creerpile() P empiler(e,p) // e est notre SP6 Tant que pilevide(p)=1 E sommet(p) P depiler(p) VR TailleValeursRestantes(e) Si VR>1 alors Pour i=0 à i<vr // on prend une valeur restante d un élément Pour j=i+1 à j<vr // on effectue les opération qu avec les éléments situés après l indice i Le Compte Est Bon BERHAULT/BERICHON BERNARD/BENCHEKROUN 15

for(k=1;k<5;k++) // On effectue les 4 opérations arithmétiques Element e1 initialiserelement(e1) Vri iemevaleursrestantes(e,i);vrj iemevaleursrestantes(e,j) Si validationcalcul(vri,k,vrj) est vrai alors RecopierHistorique(e,e1) ModifierHistorique(e1,VRi,k,VRj) GenererValeursRestantes(e,e1,i,j,k) VR0 iemevaleursrestantes(e1,0) Si iemevaleursrestantes(e1,0)=resultat ecrire("ceb",e1) nbresultats nbresultats + 1 si TailleHistorique(e1) < taillemeilleursolution ecrire("best",e1) taillemeilleursolution TailleHistorique(e1) Sinon si VR0-resultat < ecartmin et VR0 resultat ecrire("pp",e1) ecartmin VR0-resultat si TailleValeursRestantes(e1)>1 P empiler(e1,p) Sinon si iemevaleursrestantes(e1,0) resultat Si TailleValeursRestantes(e1)>1 P empiler(e1,p) k k+1 j j+1 i i+1 Le Compte Est Bon BERHAULT/BERICHON BERNARD/BENCHEKROUN 16

Implémentation en C MAIN.C #include <math.h> #include <time.h> #include <stdio.h> #include <stdlib.h> #include "main.h" int main(int argc,char*argv[]) double t=clock(); //indication de temps mis par le programme. Pile P=creerPile(); long int VRi,VRj,VR0; int VR,resultat=0,ecartMin=1000,tailleMeilleurSolution=31,nbResultats=0,afficherTousResultats=0,i,j,k; ValidationArguments(&afficherTousResultats,argc,argv); element e=(element)malloc(sizeof(struct selement)); initialiserelement(e); element e1=(element)malloc(sizeof(struct selement)); initialiserelement(e1); GenerationSP6(e,&resultat,argc,argv); affichageinitial(e,resultat,&affichertousresultats); P=empiler(e,P); while(pilevide(p)!=1) e=sommet(p); P=depiler(P); VR=TailleValeursRestantes(e); if(vr>1) for(i=0;i<vr;i++) for(j=i+1;j<vr;j++) for(k=1;k<5;k++) e1=malloc(sizeof(struct selement)); initialiserelement(e1); VRi=iemeValeursRestantes(e,i);VRj=iemeValeursRestantes(e,j); if(validationcalcul(vri,k,vrj)) RecopierHistorique(e,e1); ModifierHistorique(e1,VRi,k,VRj); GenererValeursRestantes(e,e1,i,j,k); VR0=iemeValeursRestantes(e1,0); if(iemevaleursrestantes(e1,0)==resultat) ecrire("ceb",e1); nbresultats+=1; if(taillehistorique(e1)<taillemeilleursolution) ecrire("best",e1); taillemeilleursolution=taillehistorique(e1); if(abs(vr0-resultat)<ecartmin && VR0!=resultat) ecrire("pp",e1); ecartmin=abs(vr0-resultat); if(taillevaleursrestantes(e1)>1) P=empiler(e1,P); if(iemevaleursrestantes(e1,0)!=resultat) if(taillevaleursrestantes(e1)>1) P=empiler(e1,P); printf("temps mis pour les calculs : %2.2lfs\n\n",(clock()-t)/1000000); affichageterminal(affichertousresultats,&nbresultats,ecartmin,&affichertousresultats); return EXIT_SUCCESS; Le Compte Est Bon BERHAULT/BERICHON BERNARD/BENCHEKROUN 17

PILE.C #include <stdlib.h> #include "pile.h" struct boite element val; Pile suiv; ; Pile creerpile() return NULL; int pilevide(pile p) return p==null; element sommet(pile P) return P->val; Pile depiler(pile P) Pile q=p; P=P->suiv; free(q); return P; Pile empiler(element t,pile P) Pile p=(pile)malloc(sizeof(struct boite)); p->val=t; p->suiv=p; return p; DEFINITION DE LA STRUCURE «selement» ET DU POINTEUR SUR CETTE STRUCTURE «element» struct selement long int historique[30]; int taillehistorique; long int valeursrestantes[6]; int taillevaleursrestantes; ; typedef struct selement * element; Le Compte Est Bon BERHAULT/BERICHON BERNARD/BENCHEKROUN 18

TRAITEMENTARGUMENTS.C #include <stdio.h> #include <string.h> #include <stdlib.h> #include "quitterprogramme.h" #include "element.h" #include <time.h> //********TRAITEMENT DES ARGUMENTS********* void ValidationArguments(int*ats,int argc,char**argv) int i,n=0,r=0; for(i=1;i<argc;i++) if(strcmp(argv[i],"-n")==0) n=1; if(strcmp(argv[i],"-t")==0) *ats=1; if(strcmp(argv[i],"-r")==0) r=1; if((n==0 && r==1 ) ( r==0 && n==1)) QuitterProgramme(2); void GenerationSP6(element e,int*resultat,int argc,char**argv) int ValeursInitiales[]=1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,25,50,75,100,Valeu rsinitialesutilisees[6]; srand(time(null)); if(argc>2) int i,j=0; for(i=1;i<argc;i++) //on traite ici l'option -n pour la saisie des elements de base if(strcmp(argv[i],"-n")==0 && argc<10) QuitterProgramme(0); if(strcmp(argv[i],"-n")==0 && argc>=10) while(j!=6) if(strcmp(argv[i+1+j],"-t")==0 strcmp(argv[i+1+j],"-r")==0 atoi(argv[i+1+j])<=0) QuitterProgramme(0); break; if (atoi(argv[i+1+j])>=0 atoi(argv[i+1+j])<100) e->valeursrestantes[j]=(long int)atoi(argv[i+1+j]); ModifierTailleValeursRestantes(e,1); j++; Le Compte Est Bon BERHAULT/BERICHON BERNARD/BENCHEKROUN 19

for(i=1;i<argc;i++) //on taite l'option -r pour la saisie du resultat a trouver if(strcmp(argv[i],"-r")==0) if(atoi(argv[i+1])>=101 && atoi(argv[i+1])<=999) *resultat=atoi(argv[i+1]); break; QuitterProgramme(1); int i,k,rd=rand()%24,m=0; ValeursInitialesUtilisees[0]=rd; e->valeursrestantes[0]=(long int)valeursinitiales[rd]; ModifierTailleValeursRestantes(e,1); for (i=1;i<6;i++) m=0; rd=rand()%24; for(k=0;k<i;k++) //on teste pour ne pas utiliser 6 fois le meme nombre par exemple. if(rd==valeursinitialesutilisees[k]) m=1; if(m!=1) ValeursInitialesUtilisees[i]=rd; e->valeursrestantes[i]=(long int)valeursinitiales[rd]; ModifierTailleValeursRestantes(e,1); i--; *resultat=rand()%1000; while((*resultat)<101) *resultat=rand()%1000; Le Compte Est Bon BERHAULT/BERICHON BERNARD/BENCHEKROUN 20

QUITTERPROGRAMME.C #include <stdio.h> #include <stdlib.h> //*************************************SORTIE D'ERREUR void QuitterProgramme(int a) switch (a) case 0: fprintf(stderr,"erreur : Donnez 6 entiers de depart (-n) : 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 25 50 75 100\net le resultat (-r) compris entre 101 et 999\n"); exit(exit_failure); case 1: fprintf(stderr,"erreur : Le resultat a trouver n'est pas valide: donner un entier entre 101 et 999\n"); exit(exit_failure); case 2: fprintf(stderr,"erreur : Pas assez d'arguments\n"); exit(exit_failure); case 3: fprintf(stderr,"erreur : Parametres de validationcalcul errones"); exit(exit_failure); default: break; Le Compte Est Bon BERHAULT/BERICHON BERNARD/BENCHEKROUN 21

ELEMENT.C #include <stdio.h> #include <stdlib.h> #include "element.h" #include <math.h> #define ADD 1 #define SUB 2 #define MUL 3 #define DIV 4 void initialiserelement(element e) e->taillehistorique=0; e->taillevaleursrestantes=0; static void EcrireHistorique(element e,int compteur,long int aecrire); long int ValeurElement(element e) return e->valeursrestantes[0]; int TailleValeursRestantes(element e) return e->taillevaleursrestantes; long int ieme(long int tableau[], int i) return tableau[i]; long int iemehistorique(element e,int i) return ieme(e->historique,i); long int iemevaleursrestantes(element e, int i) return ieme(e->valeursrestantes,i); void ModifierTailleValeursRestantes(element e,int modification) e->taillevaleursrestantes+=modification; static void EcrireHistorique(element e,int compteur,long int aecrire) //n'est pas repertoriee dans element.h int th=taillehistorique(e); e->historique[th+compteur]=aecrire; Le Compte Est Bon BERHAULT/BERICHON BERNARD/BENCHEKROUN 22

void ModifierHistorique(element e1,long int valeurg,int operateur,long int valeurd) int compteur,div=0; long int op; char operation; switch (operateur) case 1 : operation='+';op=valeurg+valeurd;break; case 2 : operation='-';op=valeurg-valeurd;break; case 3 : operation='*';op=valeurg*valeurd;break; case 4 : operation='/'; div=1; if (valeurg%valeurd==0) op=valeurg/valeurd; op=valeurd/valeurg; break; default : break; for(compteur=0;compteur<6;compteur++) long int caractere; switch (compteur) case 0: if(div==1) if(valeurg%valeurd==0) EcrireHistorique(e1,compteur,caractere=valeurG); EcrireHistorique(e1,compteur,caractere=valeurD); if(op>0) EcrireHistorique(e1,compteur,caractere=valeurG); EcrireHistorique(e1,compteur,caractere=valeurD); break; case 1: EcrireHistorique(e1,compteur,caractere=operation); break; case 2: if(div==1) if(valeurg%valeurd==0) EcrireHistorique(e1,compteur,caractere=valeurD); EcrireHistorique(e1,compteur,caractere=valeurG); if(op>0) EcrireHistorique(e1,compteur,caractere=valeurD); EcrireHistorique(e1,compteur,caractere=valeurG); break; case 3: EcrireHistorique(e1,compteur,caractere='='); break; Le Compte Est Bon BERHAULT/BERICHON BERNARD/BENCHEKROUN 23

case 4: EcrireHistorique(e1,compteur,caractere=abs(op)); break; case 5: EcrireHistorique(e1,compteur,caractere=';'); break; default : break; ModifierTailleHistorique(e1,6); void GenererValeursRestantes(element e1, element e2, int indice1, int indice2, char operateur) int curseur1=0,curseur2=1,tvr=taillevaleursrestantes(e1),vre11=e1- >valeursrestantes[indice1],vre12=e1->valeursrestantes[indice2]; switch (operateur) case ADD : (e2->valeursrestantes[0])=(vre11)+(vre12); break; case SUB : (e2->valeursrestantes[0])=abs((vre11)-(vre12)); break; case MUL : (e2->valeursrestantes[0])=(vre11)*(vre12); break; case DIV : if((vre11)%(vre12)==0) (e2->valeursrestantes[0])=(vre11)/(vre12); (e2->valeursrestantes[0])=(vre12)/(vre11); break; for(curseur1=0 ; curseur1<tvr ; curseur1++) if((curseur1!=indice1) && (curseur1!=indice2)) e2->valeursrestantes[curseur2]=e1->valeursrestantes[curseur1]; curseur2++; ModifierTailleValeursRestantes(e2,TVR-1); void ModifierTailleHistorique(element e, int increment) e->taillehistorique+=increment; int TailleHistorique(element e) return e->taillehistorique; void RecopierHistorique(element e1,element e2) int i; for(i=0;i<taillehistorique(e1);i++) e2->historique[i]=e1->historique[i]; ModifierTailleHistorique(e2,TailleHistorique(e1)); Le Compte Est Bon BERHAULT/BERICHON BERNARD/BENCHEKROUN 24

AFFICHAGE.C #include <stdlib.h> #include <stdio.h> #include <string.h> #include "affichage.h" void affichageinitial(element e,int resultat,int *ats) printf("\n******************\t \tle COMPTE EST BON\t \t******************\n\nrealise par:\t\t\tberichon Richard / BERHAULT Guillaume\n\t\t\t\tBERNARD Francois\n\t\t\t\tBENCHEKROUN Tarik\n\n\t*******************************************************************\n\ t*******************************************************************\n"); printf("\nrecherche de %d avec %ld %ld %ld %ld %ld %ld\n\nplease, wait a while...\n\n",resultat,iemevaleursrestantes(e,0),iemevaleursrestantes(e,1),iemeva leursrestantes(e,2),iemevaleursrestantes(e,3),iemevaleursrestantes(e,4),iemevaleu rsrestantes(e,5)); if(*ats) printf("\ntous les resultats seront affiches - faire une pipe avec less pour pouvoir les etudier\n"); void affichageterminal(int t,int*nbresultats,int ecartmin,int *ats) char l; int nbr=*nbresultats; if(*nbresultats!=0) if(t==0) FILE*f=fopen("best.txt","r"); if(f==null) printf("fichier 'best.txt' inaccessible\n"); exit(exit_failure); rewind(f); printf("*******voici une des meilleurs solutions parmis %d solutions trouvees:\n\n",*nbresultats); while((l=fgetc(f))!=eof) if(l=='>') printf("\n\n"); l=fgetc(f); if(l==';') printf("\n"); printf("%c",l); printf("\n\n"); fclose(f); if(t!=0) FILE*f=fopen("ceb.txt","r"); Le Compte Est Bon BERHAULT/BERICHON BERNARD/BENCHEKROUN 25

if(f==null) printf("fichier 'best.txt' inaccessible\n"); exit(exit_failure); rewind(f); printf("******* %d solution(s) trouvee(s):\n\n",*nbresultats); while(nbr!=0) l=fgetc(f); if(l==';') printf("\n"); printf("%c",l); if(l=='\n') nbr--; printf("************\n\n"); fclose(f); FILE*f=fopen("pp.txt","r"); if(f==null) printf("fichier 'pp.txt' inaccessible\n"); exit(exit_failure); printf("aucune solution trouvee. Voici le resultat le plus proche a %d pres:\n\n",ecartmin); rewind(f); while((l=fgetc(f))!=eof) if(l=='>') printf("\n\n"); l=fgetc(f); if(l==';') printf("\n"); printf("%c",l); if(*ats && *nbresultats>0) printf("tous les resultats sont ecrit dans le fichier ceb.txt du repertoire courant\n\n"); printf("done.\n\n"); Le Compte Est Bon BERHAULT/BERICHON BERNARD/BENCHEKROUN 26

VALIDATIONCALCUL.C #include "element.h" #include <stdio.h> #include "quitterprogramme.h" int validationcalcul(long int valeurg,int operateur,long int valeurd) char operation; switch (operateur) case 1 : operation='+';break; case 2 : operation='-';break; case 3 : operation='*';break; case 4 : operation='/';break; default : break; if(operation=='+') return 1; if(operation=='*') if(valeurg==1 valeurd==1) return 0; return 1; if(operation=='/') if(valeurg==1 valeurd==1) return 0; if(valeurg%valeurd==0 valeurd%valeurg==0 ) return 1; return 0; if(operation=='-') if((valeurg-valeurd)== 0) return 0; return 1; QuitterProgramme(3); return 0; Le Compte Est Bon BERHAULT/BERICHON BERNARD/BENCHEKROUN 27

ECRIRE.C #include <stdio.h> #include <stdlib.h> #include <string.h> #include "ecriture.h" #include "element.h" void ecrire (char *fichier, element e) FILE *f=null; int i,th=taillehistorique(e); static int effacercebtxt=0; if(!strcmp(fichier,"ceb")) if(effacercebtxt==0) //On efface un eventuel ceb.txt deja existant au debut du programme f=fopen("ceb.txt","w+"); fclose(f); effacercebtxt=1; f=fopen("ceb.txt", "a"); if(!strcmp(fichier,"pp")) f=fopen("pp.txt", "w+"); fprintf(f,"valeur : %ld, Historique:>",iemeValeursRestantes(e,0)); if(!strcmp(fichier,"best")) f=fopen("best.txt","w+"); fprintf(f,"meilleur solution:>"); for(i=0;i<th-1;) fprintf(f,"%ld",iemehistorique(e,i)); fprintf(f,"%c",(char)iemehistorique(e,i+1)); i+=2; fprintf(f,"\n"); fclose(f); Le Compte Est Bon BERHAULT/BERICHON BERNARD/BENCHEKROUN 28