IPT : Sujet 0 Mines-Ponts

Le Sujet 0 d'IPT du concours Mines-Ponts vient d'être publié.

C'est un sujet pour toutes les spécialités confondues et il est caractéristique du mauvais traitement de l'informatique en CPGE.
La première partie sur les automates cellulaires impose une programmation remplie d'effets de bord ce qui est source de nombreux bugs, surtout quand on débute.

Voici une proposition qui colle à peu près aux questions posées de manière souvent peu claire. J'ai rajouté une petite animation Pygal pour voir quand même comment évoluent ces tas:

Python
from random import random
from pygal import StackedLine
from pygal.style import DarkGreenStyle
 
if __name__ == "__main__":
    P = input("Taille du support : ")
    P = int(P)
    piles = [0 for k in range(P)]
    perdus = 0
    
    def calcul_n(h):
        if h > 1:
            return int((h + 2.0)/2 * random()) + 1
        else:
            return 0
        
    def actualise():
        global P,piles,perdus
        for k in range(1,P):
            diff = calcul_n(piles[k-1] - piles[k])
            piles[k]     += diff
            piles[k - 1] -= diff
        perdus_cette_fois =  calcul_n(piles[P-1])
        perdus += perdus_cette_fois
        piles[P - 1] -= perdus_cette_fois
 
    cpt = 0
    while perdus < 1000:
        piles[0] +=1
        for k in range(10):
            actualise()
            tas = StackedLine(fill = True, interpolate='cubic', style=DarkGreenStyle, range = (0,15))
            tas.add("perdus = " + str(perdus),piles)
            tas.render_to_png(filename = "tas" + str(cpt) + ".png")
            cpt += 1
    print(str(piles),str(perdus))

On crée la simulation:

Python
In [4]: %run Mines0_2014.py
Taille du support : 20

Ensuite, on anime ces fichiers png avec apngasm déjà évoqué ici

Python
In [5]: !apngasm animTas.png tas*.png 1 10 && firefox animTas.png

IMAGE(<a href="http://download.tuxfamily.org/tehessinmath/les_images/animTas.png" rel="nofollow">http://download.tuxfamily.org/tehessinmath/les_images/animTas.png</a>)

Même si les automates cellulaires permettent de modéliser les tas de sable de manière très efficace, ça ne fait pas « sérieux » car il manque l'essentiel aux yeux des concepteurs de sujets : une équation différentielle à résoudre avec une méthode d'Euler quelconque ! C'est à peu près l'alpha et l'oméga de la programmation apparemment ! Demandez à un(e) informaticen(ne) ce qu'il(elle) en pense...


Et à ceci s'ajoute l'usage de python par des néophytes qui éloigne des fondements nécessaires à l'apprentissage d'une informatique moderne et rigoureuse. Python est une boîte de Pandore. Il faut une certaine expérience pour l'utiliser sans risque de prendre l'informatique pour un bricolage obscur.


On aurait pu se concentrer sur une programmation plus simple car plus rigoureuse, avec un langage compilé, un typage statique qui permettent de prouver les programmes de manière beaucoup plus simple et d'accéder à un niveau d'abstraction plus facilement qu'à travers la programmation objet. Puisque Caml est utilisé en option info, pourquoi ne pas l'avoir gardé en IPT ?...


Décidemment, comme le disait Gérard Berry à Nantes il y a deux jours, la France a du mal à prendre l'informatique au sérieux et n'a pas fini d'accuser un retard inquiétant sur de nombreuses nations.


Pourtant, comme rappelé par Gérard Berry, notre cerveau est naturellement porté vers l'abstraction et les probabilités dès la naissance : je vous invite à regarder les cours passionnants de Stanislas Dehaene au Collège de France.




On peut se passer des variables globales très naturellement avec le code suivant:

Python
from numpy.random import random
from pygal import StackedLine
from pygal.style import DarkGreenStyle
 
def calcul_n(h):
        if h > 1:
            return int((h + 2.0)/2 * random()) + 1
        else:
            return 0
 
def initialisation(P):
    return [0 for k in range(P)]
 
def actualise(P, piles, perdus):
    for k in range(1,P):
        diff = calcul_n(piles[k-1] - piles[k])
        piles[k]      += diff
        piles[k - 1] -= diff
    perdus +=  calcul_n(piles[P-1])
    return piles, perdus
 
def principal(P, n):
    piles              = initialisation(P)
    perdus          = 0
    cpt_images = 0
    while perdus < n:
        piles[0] += 1
        for k in range(10):
            piles, perdus = actualise(P,piles,perdus)
            tas = StackedLine(fill = True, interpolate='cubic', style=DarkGreenStyle, range = (0,15))
            tas.add("perdus = " + str(perdus),piles)
            tas.render_to_png(filename = "tas" + str(cpt_images) + ".png")
            cpt_images += 1

Il suffit alors de lancer:

Python
In [1]: principal(20,1000)

C'est quand même plus simple....