Algorithmique ou programmation au Lycée ?

Bonsoir,
il me semble que certains ont déjà abordé la question ici.

Je me suis un peu penché sur la différence entre ALGORITHME et PROGRAMME. La différence importante que j'ai trouvé est qu'un programme fera la plus part du temps des calculs approchés, je laisse de côté le cas de XCas, tandis qu'en algorithmique les calculs sont exacts.

Je trouve mal employé le terme ALGORITHMIQUE dans les programmes du Lycée : si l'on regarde ce qui est proposé en 2nde dans les manuels et les textes officiels, on trouve uniquement des programmes mathématiques. Si l'on pouvait juste faire de l'algorithmique, on pourrait utiliser des choses comme Alice que je testerais bientôt.

En résumé, demander à nos IPR de préciser le vocabulaire ne serait pas une mauvaise chose.

Qu'en pensez-vous ?
«1

Réponses

  • Je me suis un peu penché sur la différence entre ALGORITHME et PROGRAMME. La différence importante que j'ai trouvé est qu'un programme fera la plus part du temps des calculs approchés, je laisse de côté le cas de XCas, tandis qu'en algorithmique les calculs sont exacts.

    Cette distinction que tu fais ne me semble pas du tout pertinente. Je vois plutôt un programme comme l'implémentation d'un algorithme dans un langage de programmation.
    Il y a bien sûr tout un tas d'algorithmes qui font des calculs approchés (comme l'algorithme de Héron), et des programmes qui font des calculs exacts (dans des systèmes de calcul formel, par exemple, pour inverser une matrice).
  • La distinction est "subtile" je l'admets.

    Quand on fait des calculs en C en implémentant l'algorithme de Héron, on utilisera des flottants. Pas de souci tant que l'on ne dépasse pas les capacités de calcul. Que se passe-t-il le jour où l'on va trop loin ? On obtient un résultat bancal. On sort du cadre de l'algorithmique. La traduction de l'algorithme est donc partielle et il me semble important de faire la différence.

    Pour ce qui est du terme employé dans les programmes officiels, si vraiment on pouvait faire de l'algorithmique, on pourrait se passer des maths ce que permet un logiciel comme Alice. Or ceci ne semble pas être l'esprit des programmes officiels.
  • Non. Un programme contient, dans un langage particulier, l'implémentation de plusieurs algorithmes. Il peut très bien donner des résultats exacts, tout dépend de ce qu'on fait.

    Au lycée on veut faire de l'algorithmique, pas de la programmation (i.e. pas s'embêter avec la syntaxe du C++ ou du Java, ni débugger un code source pendant longtemps). Plusieurs livres de seconde utilisent fort justement Algobox http://www.xm1math.net/algobox/ pour l'agorithmique, qui est remarquable.
  • Bonsoir,

    J'ajouterai qu'un programme Basic sur TI-89 peut parfaitement tirer profit du moteur formel, et fournir des résultats exacts "à coup sûr" (pourvu que la forme close existe et soit suffisamment maniable).

    Sinon, les algorithmes de calcul multiprécision permettent de fournir des résultats exacts dans n'importe quel langage.

    À mon humble avis, les programmes de mathématiques utilisent le terme décalé d'algorithmique pour éviter à tout prix d'évoquer la programmation, discipline qui semble tabou en France depuis les années 90... Mais au lycée, soyons sérieux, il s'agit bien de programmation et de rien d'autre.

    http://www.lix.polytechnique.fr/~dowek/lycee.html

    Cordialement.
  • > source pendant longtemps). Plusieurs livres de
    > seconde utilisent fort justement Algobox

    C'est mortel d'ennui ce truc, c'est de l'informatique du temps des pionniers, il manque que les cartes perforées ;) Franchement, mais qu'est-ce qu'on fait d'intéressant avec une usine à gaz comme ça ? Je viens de regarder leur animation : 11 lignes de (pseudo) code laborieux pour faire la somme de nombre de 1 à 100. N'importe quel programme un peu substantiel sera infaisable tant le machin est lourd.

    Dans les exemples, ils proposent une fonction de Syracuse, 24 lignes de code peu intuitif pour afficher les 101 premiers termes de la suite. La suite de Syracuse est un truc simple donc il est incompréhensible que le code produit ne soit pas simple et intuitif.


    Voyons ce que cela donne en Python :
    def f(x):
        if x%2==0:return x/2
        else: return 3*x+1
    a=input()
    print "0 ->", a
    for i in range(1,101):
        b=f(a)
        print i, "->", b
        a=b
    


    Je traduis pour ceux qui ne connaissent pas. D'abord, vous remarquez que le code est indenté. C'est non seulement volontaire mais obligatoire en Python: cela oblige à structurer son code en même temps que cela le rend plus lisible.
    Python est tellement simple que c'est du pseudo code exécutable.

    lignes 1 à 3 : on définit, comme en math, une fonction f qui prend une variable x (remarquer que le type de x n'est pas précisé).
    Le code s'écrit ensuite comme l'algo s'énonce : si le reste de la division de x par 2 vaut 0 alors f(x) vaut la moitié de x, sinon f(x) vaut 3*x+1

    ligne 4 : l'utilisateur du programme est invité à entrer un nombre (fonction input). Dans la suite du programme le nombre entré s'appelle a.

    ligne 5 : on affiche (instruction print) 0 -> a où a est remplacé par sa valeur

    lignes 6 à 9 : on parcours les entiers i avec 1<= i < 101 et à chaque entier
    *) on calcule f(la valeur courante)
    *) on affiche cette valeur avec l'indice correspondant
    *) on met à jour la valeur courante.
    Vous remarquerez à quel point la syntaxe est lisible dans l'en-tête de la boucle(for toto in ...) , on ne dirait pas autrement en langage mathématique

    A mon avis une partie des élèves apprendraient ça relativement rapidement. Je dis "une partie" car il y a une part incompressible d'élèves complètement rétifs à ce genre de travail, et parmi ces élèves on en trouvera même qui sont d'un niveau correct en math.


    AMHA, si la programmation doit marcher au lycée, il faut un support qui permettent de faire des choses ludiques (et en particulier graphiques). Python permet très facilement de faire cela.


    EDIT Idem pour l'algorithme de génération du tableau de Pascal que je trouve beaucoup intuitif à écrire en Python :
    n=input()
    t=[[0 for i in range(n+1)] for j in range(n)]
    for ligne in range(n):
        t[ligne][0]=1
        for colonne in range(1,ligne+1):
            t[ligne][colonne]=t[ligne-1][colonne]+t[ligne-1][colonne-1]
        for colonne in range(ligne+1) : 
            print t[ligne][colonne],
        print
    

    Je commente en deux mots pour ceux qui seraient intéressés :

    ligne 1 : on demande à l'utilisateur d'entrer n
    ligne 2 : on crée un tableau rempli de 0.
    ligne 3 à la fin : on affiche le tableau ligne par ligne.
    ligne 4: chaque ligne du tableau commence par 1
    lignes 5 et 6 : on remplit la ligne courante : chaque des termes est la somme des deux qui sont juste au-dessus
    ligne 7 et 8 : on affiche les termes de la ligne courante côte-à-côte
    ligne 9 : saut de ligne
  • c.candide: bien lire le programme officiel http://media.education.gouv.fr/file/30/52/3/programme_mathematiques_seconde_65523.pdf je cite
    La seconde est une classe de détermination. [...] Au collège les élèves ont rencontré des algorithmes. [...] Ce qui est proposé dans le programme [du lycée] est une formalisation en langage naturel propre à donner lieu à une traduction sur un calculatrice où à l'aide d'un autre logiciel. Il s'agit de familiariser les élèves avec les grands principes d'organisation d'un algorithme [...]

    Ainsi, comme en seconde on s'adresse à un ensemble inhomogène d'élèves qui iront ensuite dans des premières différentes (pas que du S, loin de là), l'accent est mis sur la phase avec stylo et papier de formalisation et de rigueur dans l'organisation (qui est utile à tous), moins sur celle plus technique de programmation proprement dite (qui présente une phase supplémentaire de difficulté, même si bien sûr elle est importante et que certains lycéens peuvent apprendre Python très facilement).


    Il y a même un document d'accompagnement sur eduscol spécialement pour la seconde http://media.eduscol.education.fr/file/Programmes/17/8/Doc_ress_algo_v25_109178.pdf qui dit bien que l'on ne cherche pas à former des programmeurs, mais des élèves qui face à un problème sont capables pour le résoudre de maîtriser un minimum l'aspect formalisation mathématique et algorithmique.

    A mon sens, si sur la copie c'est bien conçu, clair et correct, mais que l'implémentation sur machine ne tourne pas à cause de bugs liés seulement à la syntaxe propre du langage utilisé, c'est pas sanctionnable (autrement dit, aucune exigence à avoir de ce côté là), alors que dans un cours de programmation ça le serait. Cela étant, varier les exemples d'implémentation d'un même algorithme est bien sûr important pour faire sentir le truc (calculatrice, algobox, python, Xcas...).
  • J'enseigne l'algorithmique dans le supérieur depuis plusieurs années, c'est pour cela que je pense que les objectifs du programme de seconde tel qu'il est présenté sont très ambitieux, surtout qu'une bonne partie des enseignants ne sont pas sans doute pas très enthousiastes et que même si c'est le cas ils n'ont pas forcément le recul nécessaire pour faire une séance de TP et pouvoir répondre à 15 élèves simultanément bloqués sur un programme qui ne compile pas (sans parler de s'exécuter correctement). D'un autre coté, faire de l'algorithmique sans passer à l'étape programmation sur machine, c'est comme faire de l'anglais uniquement à l'écrit, c'est barbant, ça passe à coté d'un aspect très motivant : réussir à faire faire le programme à la machine, et ça empêche la possibilité de corriger des erreurs par interaction avec la machine. Donc pas facile, espérons qu'avec le temps, les collègues prendront leurs marques, que cet enseignement s'enracinera et sera jugé enrichissant.
  • Merci parisse.

    Il faut faire comprendre que le dialogue avec la machine est fondamental. La manière timorée et ambiguë dont sont rédigés les nouveaux programmes de lycée est un enfumage absolument nuisible.

    L'algorithmique vise à démontrer les programmes et à en évaluer le coût. C'est largement hors de la portée du lycéen moyen/moyen-plus.

    Mais coder une boucle for pour résoudre graphiquement une équadiff du premier ordre par la méthode d'Euler (voire RK4), est facile et essentiel. L'abstraction inverse des tableurs, dont l'usage est vivement conseillé dans le secondaire, est une erreur didactique grave qui empêche les élèves d'accéder à ce dialogue direct avec la machine.

    Cordialement.
  • Bonjour,

    J'ai enseigné 19 ans l'algorithmique en prépa Hec, après avoir enseigné 19 ans
    dans le Secondaire.

    Pour moi l'algorithmique est la décomposition en tâches simples d'un calcul compliqué :
    on veut résoudre une équation, mais on ne décortique pas l'addition; on le rédige en français.
    Un programme est la transcription de l'algorithme dans le dialecte d'un instrument de calcul.

    Je ne connais aucun argument qui permette de dire qu'un langage de programmation est
    supérieur à un autre. L'essentiel est d'en connaitre un, de le pratiquer, d'en connaitre les
    limites, et de vérifier les algorithmes qui sont des productions de la pensée.

    Je me suis amusé jadis à batir des problèmes de maths dont la résolution nécessitait un
    instrument de calcul : il fallait donc analyser le problème, bâtir un algorithme, l'exécuter
    sur une machine pour obtenir enfin le résultat ; on quittait le cocon de la classe où tout
    tombe juste. Ces problèmes ont été édités par Belin, mais on ne les trouve plus, aussi
    en ai-je fait une version électronique :
    http://www.lulu.com/product/ebook/algorithmique-pour-le-lyc%C3%A9e---tome-1/11270264?productTrackingContext=product_view/more_by_author/right/1

    Bonne journée,
    Daniel Saada
    www.daniel-saada.eu
  • Je suis du même avis que Danielsaada sur la première partie du message.
    Mais ce serait quand même bien d'éviter de faire de la pub pour tes livres à chaque message...
  • danielsaada écrivait:

    > tombe juste. Ces problèmes ont été édités par
    > Belin, mais on ne les trouve plus, aussi
    > en ai-je fait une version électronique :
    > http://www.lulu.com/product/ebook/algorithmique-po
    > ur-le-lyc%C3%A9e---tome-1/11270264?productTracking
    > Context=product_view/more_by_author/right/1


    Ta médiocrité est affligeante.
  • candide : angélique, confiant, crédule, igénu, innocent, naif, pur, simple,...

    mais pas hargneux.
  • parisse écrivait:
    > ... les objectifs du programme de seconde
    > tel qu'il est présenté sont très ambitieux,
    > surtout qu'une bonne partie des enseignants ne
    > sont pas sans doute pas très enthousiastes et que
    > même si c'est le cas ils n'ont pas forcément le
    > recul nécessaire pour faire une séance de TP...

    Cela peut très vite s'apprendre dans la mesure où les programmes que l'on fait au Lycée ne sont pas non plus d'une complexité folle. Par contre, l'EN a osé proposer juste deux journées aux enseignants pour présenter "l'algorithmique" du nouveau programme.

    C'est n'importe quoi quand on sait que la majorité des enseignants de maths ne font jamais de programmation. De plus, il ne faudrait pas oublier que l'algorithmique et la programmation sont devenues des disciplines à part entière.


    parisse écrivait:
    > D'un autre coté,
    > faire de l'algorithmique sans passer à l'étape
    > programmation sur machine, c'est comme faire de
    > l'anglais uniquement à l'écrit, c'est barbant...

    Tu as raison. J'ai essayé cette année d'utiliser AlgoBox avec des 2nde Art Appliqué et je me suis vite rendu compte des limites de ce logiciel qui, à mon humble avis, a plus sa place au collège qu'en lycée, ou à défaut avec des classes difficiles.

    Je pense en fait que suivant les profils des classes que l'on a il faudrait adapter le langage de programmation. A titre perso., je pense faire bosser des S avec Python car je le pratique et du coup je pourrais plus facilement faire face aux problèmes techniques, tandis qu'en 2nde je vais à coup sûr utiliser le langage JavaScript intégré dans CaRMetal, afin de faire des dessins tout en programmant (et en me débrouillant pour très sournoisement faire faire des maths aux élèves sans qu'ils s'en rendent compte).

    PS Perso. à l'intention de Mr Parisse : dès que j'ai 5 min, je remontrais le souci que j'ai eu avec XCas sur mon Mac.
  • projetmbc écrivait:


    > de programmation. A titre perso., je pense faire
    > bosser des S avec Python car je le pratique et du
    > coup je pourrais plus facilement faire face aux
    > problèmes techniques, tandis qu'en 2nde je vais à
    > coup sûr utiliser le langage JavaScript intégré
    > dans CaRMetal, afin de faire des dessins tout en
    > programmant

    Je ne connaissais pas CaRMetal mais c'est vrai que les résultats sont assez sympas.

    Note que Python permet très facilement de dessiner avec turtle et/ou Tkinter.


    >(et en me débrouillant pour très
    > sournoisement faire faire des maths aux élèves
    > sans qu'ils s'en rendent compte).

    Moi je me dirais que justement c'est l'occasion de NE PAS faire de maths mais bon, je suppose que ce n'est pas ce que disent les programmes officiels ...
  • c.candide a écrit:
    Note que Python permet très facilement de dessiner avec turtle et/ou Tkinter.

    Ou avec Pygame.
    Algebraic symbols are used when you do not know what you are talking about.
            -- Schnoebelen, Philippe
  • Et que pensez-vous de Scillab ? Dans l'académie de Versailles, nous avons beaucoup d'événements pour nous faire utiliser Scilab. Je l'ai beaucoup utilisé en ION pour le traitement de l'image, mais ça me semble un peu lourd pour une classe "normale" et l'introduction à l'algorithmique.
  • Pourquoi ? La notion de fonction est facile à coder.
    Algebraic symbols are used when you do not know what you are talking about.
            -- Schnoebelen, Philippe
  • nicolas.patrois écrivait:

    > Ou avec Pygame.

    Je suis moins convaincu là. Pygame c'est de la programmation graphique et évènementielle (c'est le binding Python de la SDL qui est une bibliothèque graphique C très répandue), ça met la barre beaucoup plus haut, pour le moindre programme, faut initialiser l'écran, puis il faut placer la boucle des évènements, faut gérer la sortie de la fenêtre (obligatoire, comme avec la SDL), faut faire des blits, rafraichir, etc.


    Avec Turtle, rien de tout ça, tout est très intuitif et sans aucun intermédiaire et on peut déjà bien s'amuser puisque Turtle gère les évènements du clavier et de la souris.

    Et avec Python, pour dessiner en statique, on peut aussi utiliser matplotlib.
  • Disons que ce que projetmbc voulait dire par "dessiner" n'est pas très clair, on peut y comprendre beaucoup de choses.

    Au stade débutant, je fais dessiner mes élèves avec turtle, de façon à mieux s'approprier la logique des boucles. Quand c'est visuel, y a pas photo, les notions passent mieux.

    Au moment où ils doivent réaliser leurs propres projets, c'est souvent pygame qu'ils choisissent, car c'est le meilleur raccourcis pour faire un jeu sans trop se fatiguer. Dans ce cas le dessin est une étape de décoration.
  • Bonsoir,

    Je ne voudrais pas paraître lourd, mais la programmation graphique c'est facile aussi en VBScript :

    http://pagespro-orange.fr/profmaths/vbs_gfx/

    (Lien déjà signalé.... et non non, je ne vends rien. :))

    Étant donné que tous les élèves ont accès à un Windows et qu'il n'y a rien à installer, c'est un compromis pratique pour débuter, convenez-en...

    Très cordialement.
  • Arnaud K écrivait:
    > Au stade débutant, je fais dessiner mes élèves
    > avec turtle,

    (...)

    > Au moment où ils doivent réaliser leurs propres
    > projets, c'est souvent pygame qu'ils choisissent,
    > car c'est le meilleur raccourcis pour faire un jeu
    > sans trop se fatiguer. Dans ce cas le dessin est
    > une étape de décoration.


    Bon, je comprends plus rien. Tu illustres les notions d'algorithmique en classe de seconde avec Python dans le cadre de tes cours de maths ? Je n'arrive pas à savoir qui fait quoi, parce que les uns font de l'algobox, les autres n'utilisent aucun logiciel sur ordinateur, d'autres font de la POO et d'autres encore font un projet en pygame donc le spectre est large.
  • > aptitude search vbscript
    >
    

    VBscript est peut-être bien, mais je vais avoir du mal à préparer quoique ce soit avec.
    Bon d’accord, je suis de mauvaise foi, mais les standards (sic) de Microsoft, très peu pour moi.
    > aptitude search visualbasic
    p   libmono-microsoft-visualbasic8.0-cil                               - Visual Basic 2005 runtime libraries for Mono
    
    Algebraic symbols are used when you do not know what you are talking about.
            -- Schnoebelen, Philippe
  • VBScript écrivait:

    >
    > Je ne voudrais pas paraître lourd, mais la
    > programmation graphique c'est facile aussi en
    > VBScript :



    Excellent langage pour écrire des virus, vos élèves vont adorer ;)
  • Bonjour,

    Pour en revenir aux algorithmes, je voudrais vous soumettre

    cette question qui m'a été posée par un informaticien :

    existe-t-il un algorithme non récursif qui affiche les 6^n

    résultats quand on lance n dés ?

    Daniel Saada
    www.daniel-saada.eu
  • Théoriquement toujours.
  • Et pratiquement ?
  • X:-(
    un algorithme non récursif

    Vu le caractère antinomique entre les mots "algorithmes" et "non récursif", vaut mieux que tu précises exactement ce que tu entends pas "algo non récursif"???
    Aide les autres comme toi-même car ils sont toi, ils sont vraiment toi
  • danielsaada écrivait:
    > Et pratiquement ?


    C'est immédiat et de plusieurs façons. Par exemple, tu boucles sur tous les entiers k de 1 à $6^n$ et tu affiches la représentation "complète" en base 6 de $k$. Ou encore tu écris une fonction next() qui détermine le suivant d'une chaîne au sens lexicographique avec pour alphabet les 6 faces du dé ('1', '2', ...,'6') et tu génères les sorties possibles à partir de la chaîne formée que de '1' en appelant la fonction la fonction next(). Voilà pour les idées de base. Ensuite, il faut le coder.
  • oups, pardon Daniel, je viens de comprendre. J'avais lu le mot "récursif" dans le sens logique et je croyais que tu demandais un algorithme qui est par exemple récursivement énumérable et non de complémentaire récursivement énumérable en tant que fonction, etc... X:-(X:-(

    En fait tu demandes une procédure qui n'effectue pas un appel à elle-même loooool

    Tu la veux en quel langage?
    Aide les autres comme toi-même car ils sont toi, ils sont vraiment toi
  • Langage hybride pour donner l'idée:


    let iter m = let s=[] in for i=1 to 6 do s:=(!s) @ (ajoute i m)

    où ajoute x m renvoie une liste où chaque uplet de m (a,b,c..) est devenu (x,a,b,c,..)

    ensuite, en partant de la liste L:= [(1);(2)...;(6)],

    tu fais

    let f n=begin L:= [(1);(2)...;(6)]; for i:=1 to n do L:=iter L; L end
    Aide les autres comme toi-même car ils sont toi, ils sont vraiment toi
  • Code en Python :
    DEBUT=1
    FIN=6
    
    def next(mot, n):
        i=n-1
        while i>=0 and mot[ i]==FIN:
            i-=1
        if i==-1:
            return "pas de suivant"
        else:
            mot[ i]+=1
            mot[ i+1:]=[DEBUT]*(n-i-1)
            return mot
    
    def afficher(mot):
        for i in range(len(mot)):print mot[ i],
        print
    
    NB_JETS=2
    mot=[DEBUT]*NB_JETS
    
    while mot!="pas de suivant":
        afficher(mot)
        mot=next(mot, len(mot))
    
    1 1
    1 2
    1 3
    1 4
    1 5
    1 6
    2 1
    2 2
    2 3
    2 4
    2 5
    2 6
    3 1
    3 2
    3 3
    3 4
    3 5
    3 6
    4 1
    4 2
    4 3
    4 4
    4 5
    4 6
    5 1
    5 2
    5 3
    5 4
    5 5
    5 6
    6 1
    6 2
    6 3
    6 4
    6 5
    6 6
    
    Tiens, quelqu'un sait l'écrire en Maple qu'on compare ?

    [Sur le forum, il faut écrire '[ i' (avec une espace) sinon l'afficheur lit une bannière BBcode de mise en italique. ;) AD]
  • En Python, il y a plus simple :
    #! /usr/bin/env python
    #coding=utf-8
    
    # A non-recursive algorithm that displays the 6^n results
    # obtained by throwing n dice discernible.
    
    diceSize = 6
    nbOfThrows = 2
    
    diceSize  += 1
    
    # One throw.
    results = [ [k] for k in range(1, diceSize) ]
    
    # More than one trhow.
    for k in range(1, nbOfThrows):
        oldResults = results
        results = []
    
        for oneOldResult in oldResults:
            for j in range(1, diceSize):
                results += [ oneOldResult + [j] ]
    
    # Display the results
    for oneResult in results:
        print oneResult
    

    [Même remarque sur '[ i' que dans le message précédent. AD]
  • à Daniel: la remarque que te faisait projetmbc, c'est que la "récursivité" (au sens informatique, appel de soi-même par une procédure) est "conservative". Tout programme peut être réécrit de manière équivalente (faire la même chose) sans.

    Cependant, il faut penser aux types de données utilisées, sinon, ça peut vite, bien que possible, devenir une usine à gaz.

    Preuve: a:=f(a) fait la même chose que la chose suivante:

    let diag x y = y (x x f)
    a:=diag diag f


    (à condition de bien choisir l'ordre d'évaluation)

    En effet, à l'exécution, ça donne:

    a ":=" diag diag f ":=" f (diag diag f)

    qui est de la forme a:=f(a)




    Appliqué à ton exemple précis, tu veux une f telle que f n :=g(1,f (n-1)), g(2, f(n-1)), ... ,g(6,f(n-1))

    donc pas tellement besoin de passer par la preuve générale. Il suffit d'itérer n-1 fois "R:=t(R)" où R est intialement la liste demandée pour n=1 et où t est tel que f n := t(f (n-1))

    En pascal, tout dépend comment tu poses la question. Est-ce que tu veux comme contrainte qu'on ne dispose que de l'instruction "write", auquel cas ça devient un exercice différent et d'ailleurs apparatenant à un champ d'exercices amusants, puisque plus soumis à la preuve (les hypothèses "informatiques théoriques" ne sont pas vérifées).

    Donc je reformule ta question sous la forme "pascal":

    Soit la procédure:

    procedure deploi (s:string; n:integer);
    var i:interger;
    begin
    if n<2
    then for i:=1 to 6 do begin write(s);write('-');writeln(i) end;
    else for i:=1 to 6 do deploi(entierversstring(i) + s,n-1);
    end;


    Exercice: écrire une procédure non récursvie qui fait exactement la même chose sans se servir de type compliqués (tableaux, dévoiement de string, etc)
    Aide les autres comme toi-même car ils sont toi, ils sont vraiment toi
  • projetmbc écrivait:
    > En Python, il y a plus simple :


    avec Python 2.6 :
    Original exception was:
      File "mot_suivant_mathsnet.py", line 13
        results = [  for i in range(1, diceSize) ]
                       ^
    SyntaxError: invalid syntax
    

    [Même remarque le [ i] a disparu car interprété comme bannière de départ d'italique. AD]
  • Dans la catégorie où on n'autorise que write et read, voici une procedure récursive (la plus simple du monde)
    [color=#0000FF]procedure prouve (a:string; var t:string);
    var u,v:sting;
    begin
        writeln (a); writeln('pourquoi?')
        readln (r);
        if r='hypo' then 
            t:= ' axiome: ' + a + ';' 
        else
            prouve('si ' + r + ' alors ' + a,u);
        prouve(r,v);
        t:=u+v;
    end;[/color]
    

    Question: comment programmer une procédure exactement équivalente sans appel récursif et sans trop tricher sur les types de données utilisés ?
    Aide les autres comme toi-même car ils sont toi, ils sont vraiment toi
  • christophe chalons écrivait:
    > Exercice: écrire une procédure non récursvie qui
    > fait exactement la même chose sans se servir de
    > type compliqués

    Si on considère les entiers comme étant un type simple, il suffirait d'utiliser un codage des tableaux via par exemple une écriture 6-adique. Donc pas infaisable mais là j'ai la flemme.


    c.candide écrivait:
    > projetmbc écrivait:
    > > En Python, il y a plus simple :
    > avec Python 2.6 :

    En tant qu'amateur, autant utiliser la dernière version, ou presque. Non ?
    De toute façon, l'initialisation peut se faire via une classique boucle for sans faire appel à une "list comprehension".
  • à pmbc: mouais "en pratique" l'injection naturelle de l'ensemble des tableaux dans $\N$ explose ou poil trop vite :D
    Aide les autres comme toi-même car ils sont toi, ils sont vraiment toi
  • à Daniel, ce que j'entends par "contrainte de type", c'est simplement que certaines données sont calibrées en mémoire pour n'être abordées avec simplicité qu'avec des appels récursifs.

    Exemple: on veut chercher s'il y a 3 dans une liste L donnée sans qu'on ait choisi son format:

    (en caml)

    let rec cherche L = if premier élément de L =3 renvoyer true sinon, cherche (suite de L)

    Un exercice amusant est de se demander s'il existe un moyen (à part celui, abstrait de la preuve que j'ai donnée plus haut, mais qui abuse de l'implémentation, supposée donnée, de la programmation fonctionnelle dans le langage) de programmer "cherche" sans tricher, sans appel récursif (j'entends par tricher celui de supposer qu'on connait au moins un peu L)
    Aide les autres comme toi-même car ils sont toi, ils sont vraiment toi
  • erratum au moins un peu le format de L
    Aide les autres comme toi-même car ils sont toi, ils sont vraiment toi
  • projetmbc écrivait:

    > En tant qu'amateur, autant utiliser la dernière
    > version, ou presque. Non ?

    Non. La plupart des grosses appli ne tournent pas sous Python 3 (NumPy, SciPy, PyQt, PyGame, Django, etc) donc je n'ai pas de raison de changer.


    > De toute façon, l'initialisation peut se faire via
    > une classique boucle for sans faire appel à une
    > "list comprehension".

    Et si Tu corrigeais ton code ?


    Maintenant venons-en à ta réflexion "En Python, il y a plus simple".

    Python n'a rien à voir dans ta solution prétendumement simple. D'abord, tu ne donnes pas de code réutilisable avec des fonctions, ton affichage est brouillon, ce qui déjà l'aurait rendu un peu moins simple.


    Mais l'essentiel n'est pas là. L'essentiel est que ton code est extrêmement maladroit puisqu'il utilise une quantité phénoménale de mémoire. Ta méthode est très primaire : il suffit de stocker en mémoire tous les résultats de n jets pour avoir ceux correspondant à n+1 jets. Pas très développement durable ton code.


    J'ai fait une petite expérience, on demande à ton code de nous générer les 2**22 jets (22 lancer d'une pièce) : ton code utilise 800 Mo de mémoire !!! faut quand même le faire ça !! Il faut voir que 2**22 n'est pas un nombre astronomique,
    c'est de l'ordre de 4 millions, en informatique, c'est un petit nombre.

    Et en plus le temps d'exécution est prohibitif (1m38.502s sur ma machine).



    Maintenant, tu prends mon code, il va utiliser 7 Mo de mémoire pendant toute l'exécution et cette exécution sera plus rapide (52.347) sans compter que mon code possède des possibilités d'être optimisé que ton code n'a pas. Enfin, j'ai juste posté le code correspondant à l'algorithme dont j'ai parlé (l'ordre lexicographique) qui est d'ailleurs une méthode bien connue, la première citée dans le livre de Knuth (tome 3 je crois).

    Bref, tu aurais dû dire non pas "En Python, il y a plus simple" mais "En Python, il y a plus simpliste".
  • hé hé, j'aime bien que ça commence à sentir la discussion de vestiaire, en ce moment c'est d'actualité.

    Quand je lis ces histoires de "mégaoctets", pourquoi (je ne connais pas python) ne pas tout simplement ne pas programmer le "chronomètre" (j'entends par là une petite procedure qui fait passer de (3;2;6;1;6) à (3;2;6;2;1); etc; etc pour les n-uplet (5uplets dans l'exemple)?

    Ca ne consomme aucune mémoire (à part le papier de l'imprimante ou le buffer de sortie) et il suffti de programmer une fonction qui donne la longueur du uplet pour l'arrêter là où il faut et afficher "sa partie" qu'il faut.
    Aide les autres comme toi-même car ils sont toi, ils sont vraiment toi
  • christophe chalons écrivait:

    > Quand je lis ces histoires de "mégaoctets",
    > pourquoi (je ne connais pas python) ne pas tout
    > simplement ne pas programmer le "chronomètre"
    > (j'entends par là une petite procedure qui fait
    > passer de (3;2;6;1;6) à (3;2;6;2;1); etc; etc pour
    > les n-uplet (5uplets dans l'exemple)?

    Comprends pas trop ce que tu veux dire avec ton "chronomètre". Ma méthode next() est exactement ta procédure.

    Autre méthode, encore plus simple et largement plus rapide et qui ne consomme aucune mémoire : on convertit en base b (b=6 pour des dés) :

    b=2
    n=22
    
    for q in range(b**n):
        resultat=""
        for z in range(n):
            print q%b,
            q/=b
        print
    
    $ time python base.py > a
    
    real    0m33.569s
    user    0m32.318s
    sys     0m0.520s
    
  • lol oui possible, je ne connais pas python, c'était pour caser ma blague sur les vestaires surtout ....

    par chronomètre, j'entendais faire défiler l'un après l'autre les éléments de $\{1;2;..;6\}^n$ l'un après l'autre, classés dans l'ordre lexicographique.
    Aide les autres comme toi-même car ils sont toi, ils sont vraiment toi
  • Bonsoir,

    Voici un algorithme, indépendant de tout langage et lisible par tous,

    qui génère les k^n résultats quand on lance n dés à k faces.

    L'ensemble des résultats est l'univers E = {1,...,k}^n ;

    un événement élémentaire est un n-uplet ( d(1), d(2),..., d(n) .
    Le programme qui suit affiche sans redondance tous les éléments de E
    ( = remplace l'affectation) :

    10 pour i allant de 1 à n : d(i) = 1

    20 afficher d(1), d(2),...,d(n)

    30 i = n

    40 d(i) = 1 + d(i)

    50 si d(i) <=k aller en 20

    60 d(i) =1 et i =i - 1

    70 si i > 0 aller en 40

    80 FIN.

    On peut vérifier cet algorithme en insérant un compteur C qui, à la fin du programme,
    doit afficher le cardinal de E.
    Pour moi, un algorithme est pédagogiquement supérieur à tout programme.

    Daniel Saada
  • looool, tu utilises la numérotation auquel nous étions habitués dans notre enfance, pour les programmes en basic (10;20;30...) ainsi que les "goto". Ralala, ça nous rajeunit pas.

    Soit dit en passant, je ne peux, avec toi, que regretter les condamnations par les vertueux pédagogues de l'informatique de l'outil "goto". A ma connaissance, on ne le retrouve ni en caml, ni en pascal, ni en C.

    Leur motif était la lisibilité et la "bonne tenue" du programme, mais tu viens de montrer que le "goto", in fine, c'est quand-même bien pratique dans les cas exotiques.

    Alors je crois qu'il est vrai que le basic de notre enfance n'accepte pas les appels récursifs si je me souviens bien. C'est marrant, que de souvenir... :D

    Et effectivement, voici une bonne raison de chercher des programmes sans appels récursifs: utiliser un langage qui ne les implémente pas (assembleur, basic, et..?)
    Aide les autres comme toi-même car ils sont toi, ils sont vraiment toi
  • danielsaada écrivait:
    > Bonsoir,
    >
    > Voici un algorithme, indépendant de tout langage
    > et lisible par tous,

    OK, ton "algorithme", disons ton automate, fonctionne, je l'ai vérifié point par point. Je te souhaite bien du plaisir à implémenter l'algorithme de Kruskal ou de Dijkstra comme ça.



    > Pour moi, un algorithme est pédagogiquement
    > supérieur à tout programme.


    Bof*10. Ce genre d'algorithme est du formalisme gratuit.

    D'abord, beaucoup de gens sont tout à fait capables de générer l'ensemble des solutions sans savoir le formuler de manière générique. Tout simplement parce qu'ils n'en sentiront même pas la nécessité. Ils sauront te générer toutes les instances du problème sans pour autant être capable de le décrire génériquement. Donc ils ont compris le problème mais ils seront sanctionné pour n'avoir pas su l'intellectualiser. Donc la notion est relativement facilement et sa formalisation est vaine si on en fait rien.


    Mais pire : quelqu'un peut très bien pondre cet ennuyeux listing d'instructions et être incapable de le programmer dans un quelconque quel langage. Autrement dit, cette personne ne saura pas rendre utiles cet algorithme trivial.


    Sinon, au cas où tu ne l'aurais pas remarqué, ton algorithme est exactement celui que j'ai donné. Tu ne fais qu'ajouter 1 (l'unité) en base k à un nombre de n chiffres et tu t'arrêtes quand le nombre a n+1 chiffres. Ton i=i-1 c'est le décalage pour la retenue. Et tu ne fais que générer les solutions dans l'ordre lexicographique (comme je l'avais proposé dès le départ).


    Histoire que ton algorithme ne soit pas vain, le voici implémenté en Python :

    MAX=3
    DEBUT =1
    NB_JETS=4
    t=[1]*NB_JETS
    k=NB_JETS-1
    while True:
        if t[k]<=MAX:
            print t
            t[k]+=1
            k=NB_JETS-1
        else:
            t[k]=DEBUT
            k-=1
            if k==-1:
                break
            else:
                t[k]+=1
    

    Le temps d'exécution est correct :
    $ time python saada.py > aa
    
    real    0m46.417s
    user    0m44.443s
    sys     0m1.316s
    

    mais moins bon que la conversion en base k.




    christophe chalons écrivait:

    > Soit dit en passant, je ne peux, avec toi, que
    > regretter les condamnations par les vertueux
    > pédagogues de l'informatique de l'outil "goto". A
    > ma connaissance, on ne le retrouve ni en caml, ni
    > en pascal, ni en C.

    Oui, ben encore un qui parle du C et ne le connait pas.



    > Leur motif était la lisibilité et la "bonne tenue"
    > du programme, mais tu viens de montrer que le
    > "goto", in fine, c'est quand-même bien pratique
    > dans les cas exotiques.


    Bof, cas exotiques ? on avait pas besoin de goto pour comprendre, un enfant de 10 ans comprend comment ça marche et peut te le répéter sur n'importe quelle instance du problème, preuve qu'il a compris.





    >
    > Et effectivement, voici une bonne raison de
    > chercher des programmes sans appels récursifs:
    > utiliser un langage qui ne les implémente pas
    > (assembleur, basic, et..?)

    Dans les langage actuels, tu n'en trouveras pas beaucoup. Java, C/C++, Python, javascript (sans parler de Ocaml bien sûr) et bp d'autres supportent la récursivité. Parler d'assembleur en général n'a aucun sens et dire que l'assembleur ne supporte pas la récursivité est faux, l'assembleur x86 le supporte mais je suppose d'autres assembleurs.
  • Original exception was:
      File "mot_suivant_mathsnet.py", line 13
        results = [  for i in range(1, diceSize) ]
                       ^
    SyntaxError: invalid syntax
    
    [Même remarque le [ i] a disparu car interprété comme bannière de départ d'italique. AD]
    

    Ah, OK merci, cela explique l'erreur de syntaxe que je croyais due à une histoire de version de Python. Bon, curieux quand même que la balise de code ne soit pas une balise verbatim.

    [Tant qu'a faire des citations, faisons des citations exactes. :) AD]
  • c.candide écrivait:
    > projetmbc écrivait:
    > > En tant qu'amateur, autant utiliser la dernière
    > > version, ou presque. Non ?
    >
    > Non. La plupart des grosses appli ne tournent pas
    > sous Python 3

    C'était le sens du "OU PRESQUE". Un peu de nuance... Pour mémoire, dans le message qui précédait, on parlait de la version 2.6 de Python.


    > Maintenant venons-en à ta réflexion "En Python, il
    > y a plus simple".
    >
    > Python n'a rien à voir dans ta solution
    > prétendumement simple.

    Pas besoin d'être agressif, c'était une remarque en l'air. Je sais que l'équipe de France a presque perdu toute chance mais de là à être agressif avec tout le monde...
    Sérieusement, il n'y avait aucun sous-entendu dans ma remarque "En Python, il y a plus simple".

    Pour ce qui est du code donné, il répondait à la question. Ceci fournit un algorithme non récursif, certes codé en Python, mais tel que présenté c'est un algorithme. Comme quoi programmation et algorithme ne sont pas deux concepts totalement identiques...

    > Ta méthode est très primaire : il suffit de stocker
    > en mémoire tous les résultats de n jets pour avoir
    > ceux correspondant à n+1 jets. Pas très
    > développement durable ton code.

    Ce n'était pas son propos... Mais avec une réponse pleine d'agressivité pour trois lignes de code qui se courent après, on peut se demander pourquoi une telle débauche d'énergie pour m'agresser de la sorte.

    > J'ai fait une petite expérience, on demande à ton
    > code de nous générer les 2**22 jets (22 lancer
    > d'une pièce) : ton code utilise 800 Mo de mémoire
    > !!! faut quand même le faire ça !! Il faut voir
    > que 2**22 n'est pas un nombre astronomique

    Parler de performance et mémoire en Python, c'est un peu de la rigolade... Sans "wrappers" pour des codes en Fortran ou en C, Python serait inutilisable dans de vrais projets.
    Mais je le répète, sans aucune agressivité, je n'ai fait que donner un ALGORITHME immédiat à comprendre.

    A quoi bon 2**22 jets... Cela frôle la mauvaise foi. En tout cas, tout ceci est bien rigolo.

    Performance dans quel cadre ? Pour quoi faire ?

    > Bref, tu aurais dû dire non pas "En Python, il y a
    > plus simple" mais "En Python, il y a plus
    > simpliste".

    Il y a ceux qui savent et qui méprisent, et les imbéciles heureux. Je me très sens bien dans la seconde catégorie, et en plus c'est bon pour la tension.

    De toute façon, on s'éloigne totalement du sujet de ce post.
  • > Ah, OK merci, cela explique l'erreur de syntaxe
    > que je croyais due à une histoire de version de
    > Python. Bon, curieux quand même que la balise de
    > code ne soit pas une balise verbatim.
    >
    >[Tant qu'a faire des citations, faisons des citations exactes. smiling smiley AD]


    Pas compris. Tu veux dire que j'ai inclus ton commentaire dans la balise de code, (ce qui est vrai en effet) ?


    projetmbc écrivait:
    > C'était le sens du "OU PRESQUE".

    Et bien ce n'était pas clair. Je ne vois pas ce que veut dire utiliser la version 3.0 "ou presque". Sois tu utilises la version 3.0 soit tu l'utilises, ce n'est pas un continuum.



    > nuance... Pour mémoire, dans le message qui
    > précédait, on parlait de la version 2.6 de
    > Python.

    Non pas avant que j'en ai parlé moi-même, relis le fil. D'ailleurs, tu m'as fait croire que ton code plantait chez moi pour une question de version alors qu'il s'agissait d'une question d'interprétation du texte par le parseur du bbcode du site. Ce n'est pas une question de version, sinon ton print aurait été une fonction (c'est ainsi en Python 3.0) et pas une instruction comme en Python 2.6.


    > Pas besoin d'être agressif, c'était une remarque
    > en l'air. Je sais que l'équipe de France a presque
    > perdu toute chance mais de là à être agressif avec
    > tout le monde...
    > Sérieusement, il n'y avait aucun sous-entendu dans
    > ma remarque "En Python, il y a plus simple".

    J'ai parfaitement compris ce que tu as dis. Je maintiens complètement ce que je dis même si je veux bien retirer la connotation agressive. En même temps, essaye d'être plus rigoureux dans ton expression.



    >
    > Pour ce qui est du code donné, il répondait à la
    > question. Ceci fournit un algorithme non récursif,
    > certes codé en Python, mais tel que présenté c'est
    > un algorithme. Comme quoi programmation et
    > algorithme ne sont pas deux concepts totalement
    > identiques...


    Absolument pas. Si je devais retranscrire à la main ton code, je passerais mon temps à recopier de longue liste sur du papier, il me faudrait une montagne de papier, c'est pour ça que je t'ai dit que ton code n'était pas écologique :)

    La différence entre algorithme et programmation n'est pas là. Un algorithme doit évidemment tenir compte des opérations de lecture et d'écriture.



    >
    > > Ta méthode est très primaire : il suffit de
    > stocker
    > > en mémoire tous les résultats de n jets pour
    > avoir
    > > ceux correspondant à n+1 jets. Pas très
    > > développement durable ton code.
    >
    > Ce n'était pas son propos...

    Et bien il ne fallait pas dire qu'en "Python, on peut faire plus simple [que mon code]" puisque finalement tu me dis que nos algorithmes n'étaient pas comparables.



    > Parler de performance et mémoire en Python, c'est
    > un peu de la rigolade... Sans "wrappers" pour des
    > codes en Fortran ou en C, Python serait
    > inutilisable dans de vrais projets.


    Faux encore. C'est juste une possibilité que le langage offre. Et si elle était obligatoire, crois-moi que le langage serait peu utilisé parce qu'il n'est pas trivial d'écrire une extension Python en C ou en C++, l'API étant relativement complexe. Les performances de Python sont excellentes pour ce qu'on lui demande de faire. Python sait gérer du graphisme directement sans passer par du C compilé. 99% des applications n'ont pas besoin de la vitesse du C.

    Et de toute façon, le problème n'était pas là : ton code utilisait 900 Mo octet de RAM juste pour afficher4 millions de nombres alors que ça ne nécessite RIEN.


    > Mais je le répète, sans aucune agressivité, je
    > n'ai fait que donner un ALGORITHME immédiat à
    > comprendre.

    C'est un algorithme très maladroit car son instantiation (avec ou sans langage de programmation) est très contraignante.


    >
    > A quoi bon 2**22 jets... Cela frôle la mauvaise
    > foi. En tout cas, tout ceci est bien rigolo.

    Qu'un programme informatique soit amené à examiner une par une 4 millions d'instance est assez banal. Si tu enseignes ça à tes élèves, tu leur donnes de mauvais réflexes. Un algorithme, indépendamment des questions d'implémentation, doit tenir compte des opérations de lecture et d'écriture. Un bon programmeur cherche à éviter les opérations de copie, car une copie c'est couteux en exécution et en mémoire, exactement comme pour un humain (un élève qui recopie le cours au tableau ou qui est puni de 100 lignes).

    >
    > Performance dans quel cadre ? Pour quoi faire ?
    >

    Parce que dans la réalité, si je veux obtenir tous les coups de dés possibles, je n'ai pas besoin d'une ramette de papier de 500 pages. Et donc mon algorithme doit traduire la simplicité de la procédure.

    > De toute façon, on s'éloigne totalement du sujet
    > de ce post.

    Non, pas tant que ça.
  • Tout ceci me fatigue...
Connectez-vous ou Inscrivez-vous pour répondre.