{ "metadata": { "name": "Revisions" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "Revisions d'IPT" ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Th\u00e8me 1 : la r\u00e9cursivit\u00e9" ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "exercice 1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Un palindrome est une cha\u00eene de caract\u00e8res qui est identique lorsqu'on la lit de gauche \u00e0 droite ou de droite \u00e0 gauche.\n", "\n", "R\u00e9diger une fonction r\u00e9cursive *Palindrome(S)* permettant de savoir si la cha\u00eene *S* est un palindrome ou non." ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "exercice 2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "L'ensemble $\\mathbb{N}\\times \\mathbb{N}$ est un ensemble d\u00e9nombrable et le parcours de cantor donne une bijection entre $\\mathbb{N}\\times \\mathbb{N}$ et $\\mathbb{N}$ en associant \u00e0 chaque point de $\\mathbb{N}\\times \\mathbb{N}$ un entier naturel.\n", "\n", "Cette bijection $f:$\\mathbb{N}\\times \\mathbb{N} \\to \\mathbb{N}$ est construite de la fa\u00e7on suivante :\n", "\n", "$\\rhd$ $f(0,0)=0$\n", "\n", "$\\rhd$ pour tout point $M$ de $\\mathbb{N}\\times \\mathbb{N}$, associ\u00e9 \u00e0 $f(M)$, alors le point $M'$ tel que $f(M')=f(M)+1$ est soit le point $M'=M+(-1,1)$ si $M'$ reste dans $\\mathbb{N}\\times \\mathbb{N}$, soit le point $M'=(y_{M}+1,0)$ si $x_M=0$.\n", "\n", "Construire la fonction r\u00e9cursive *Cantor(x,y)* calculant $f(x,y)$." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Proposer une fonction it\u00e9rative permettant de calculer $f(x,y)$." ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Th\u00e8me 2 : les piles" ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "exercice 3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Un graphe $G$ est la donn\u00e9e d'un ensemble $S$ de sommets et d'un ensemble ${\\cal A}$ d'ar\u00e8tes, qui sont des couples de sommets. Dans toute la suite, on consid\u00e8re qu'une ar\u00e8te ne peut relier que deux sommets diff\u00e9rents.\n", "\n", "On peut associer \u00e0 chaque graphe, une matrice d'adjacence qui comporte toutes les informations du graphe. C'est une matrice $M$ de taille $n\\times n$, avec $n=len(S)$ le nombre de sommets et si $i$ et $j$ sont deux entiers dans $[0,n-1]$, alors $M[i,j]=1$ si $(i,j)\\in {\\cal A}$ et $M[i,j]=0$ sinon.\n", "\n", "Le but de l'exercice est, \u00e9tant donn\u00e9e une matrice d'adjacence $M\\in {\\cal M}_n(\\mathbb{R})$ et deux entiers $i$ et $j$, de trouver un chemin $s=(s_0=i,s_1,\\cdots,s_{r-1},s_r=j)$, avec pour tout $k$ entre $0$ et $r-1$, le couple $(s_k,s_{k+1})$ qui est une ar\u00e8te du graphe.\n", "\n", "**question 1)** : parcours en profondeur\n", "\n", "On mod\u00e9lise dans cette question la recherche par une pile. Initialement, la pile comporte le sommet $i$ et les assiettes sont tous les sommets sauf $i$.\n", "\n", "A chaque \u00e9tape, on consid\u00e8re le sommet $k=Pile[-1]$ et on teste s'il y a des sommets non encore test\u00e9s (les assiettes) qui peuvent \u00eatre adjacents \u00e0 $k$. Si oui, on empile une telle assiette et sinon, on d\u00e9sempile.\n", "\n", "Lorsque $Pile$ devient vide, c'est qu'il n'y avait aucune solution au probl\u00e8me pos\u00e9 et lorsque $Pile[-1]=j$, la solution au probl\u00e8me pos\u00e9 est $Pile$.\n", "\n", "Impl\u00e9menter cette recherche par pile sous Python.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**question 2)** : parcours en largeur\n", "\n", "On d\u00e9finit une distance sur un graphe de la mani\u00e8re suivante : si $s$ et $r$ sont deux sommets, soit il existe un chemin reliant $s$ \u00e0 $r$, et dans ce cas, on note $d(s,r)$ la longueur minimale d'un tel chemin, soit il n'existe aucun chemin reliant $s$ \u00e0 $r$ et dans ce cas, on pose $d(s,r)=+\\infty$.\n", "\n", "Si $i\\in S$ et $\\rho\\in\\mathbb{N}$, la sph\u00e8re de centre $i$ et de rayon $r$ est l'ensemble :\n", "$\\Bigl\\lbrace j\\in S~|~d(i,j)=\\rho\\Bigr\\rbrace.$\n", "\n", "R\u00e9diger une fonction *Spheres(Mat,i)* donnant la liste de toutes les sph\u00e8res de centre $i$.\n", "\n", "R\u00e9diger une fonction *Connexe(Mat,i)* indiquant si l'on peut atteindre tous les points du graphe par un chemin \u00e0 partir du point $i$ et dans le cas contraire, donnant la liste des points non atteignables.\n", "\n", "R\u00e9diger une fonction de recherche du chemin de longueur minimale partant de $i$ et allant vers $j$, lorsque cela est possible.\n", " \n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**question 3)**" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "R\u00e9diger une fonction Graphe_Alea(n,p) renvoyant une matrice $Mat$ de taille $n\\times n$ telle que $Mat[i,j]=1$ avec une probabilit\u00e9 \u00e9gale \u00e0 $p$.\n", "\n", "Faire ensuite des tests des deux recherches en profondeur et en largeur." ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "exercice 4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "On consid\u00e8re une image $M$ de format $(p,q,3)$ puis une courbe param\u00e9tr\u00e9e de $[0,1]$ \u00e0 valeurs dans $[0,p-1]\\times[0,q-1]\\cap \\mathbb{N}\\times \\mathbb{N}$.\n", "\n", "R\u00e9diger une fonction *Voisins(M,point)* donnant la liste des cases adjacentes \u00e0 la case *point*, \u00e9tant entendu que si la case est \u00e0 l'int\u00e9rieur de l'image, il y a quatre voisins et seulement deux lorsqu'il s'agit d'un coin.\n", "\n", "Incorporer cette fonction dans une fonction *Composante(M,contour,depart)*, o\u00f9 $M$ est une matrice, $contour$ est une courbe param\u00e9tr\u00e9e de $[0,1]$ \u00e0 valeurs enti\u00e8res et $depart$ est un point de la matrice. Cette fonction renverra une matrice de m\u00eame taille que $M$, o\u00f9 les pixels de $contour$ sont noirs, ainsi que la composante connexe par arcs du pixel $depart$ dans le compl\u00e9mentaire de $contour$ dans l'image $M$.\n", "\n", "On importera les modules pylab et os, puis on effectuera des essais sur des images converties en .png.\n" ] }, { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "Th\u00e8me 3 : la mod\u00e9lisation num\u00e9rique" ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "exercice 5" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "On consid\u00e8re un pendule articul\u00e9 $OAB$, o\u00f9 le point $O$ est fixe, la longueur $OA$ vaut $1m$, ainsi que la longueur $OB$.\n", "\n", "Deux masses ponctuelles de m\u00eame masse $m$ sont plac\u00e9es aux points $A$ et $B$. \n", "\n", "A l'instant initial $t=0$, les points $A$ et $B$ sont en position $p_A$ et $p_B$ avec des vitesses initiales nulles.\n", "\n", "Le tout \u00e9volue sans frottement dans le champ uniforme de pesanteur que l'on prend \u00e9gal \u00e0 $g=10~m\\cdot s^{-2}$. On donne les \u00e9quations du mouvement, \u00e0 l'aide des deux variables $\\theta_1$ et $\\theta_2$ \u00e9gales respectivement aux angles entre la verticale dirig\u00e9e vers le bas et le vecteur $\\overrightarrow{OA}$ (resp. le vecteur $\\overrightarrow{AB}$) :\n", "\n", "\n", "$\\displaystyle \\theta_1''=\\frac{-(\\theta'_1)^2\\sin(\\theta_1-\\theta_2)\\cos(\\theta_1-\\theta_2)-{\\theta_2'}^{2}\\sin(\\theta_1-\\theta_2)-10\\sin\\theta_1-10\\sin(\\theta_1-\\theta_2)\\cos\\theta_2}{2-\\cos^2(\\theta_1-\\theta_2)}$\n", "\n", "$\\displaystyle \\theta_2''=\\frac{2(\\theta_1')^2\\sin(\\theta_1-\\theta_2)+(\\theta'_2)^2\\sin(\\theta_1-\\theta_2)\\cos(\\theta_1-\\theta_2)+20\\sin(\\theta_1-\\theta_2)\\cos\\theta_1}{2-\\cos^2(\\theta_1-\\theta_2)}$\n", "\n", "\n", "En important le module scipy.integrate, faire r\u00e9soudre le syst\u00e8me diff\u00e9rentiel par Python sur l'intervalle $[0,20]$.\n", "\n", "Faire ensuite tracer l'animation en modifiant le script suivant donnant l'animation d'une onde " ] }, { "cell_type": "code", "collapsed": false, "input": [ "from pylab import *\n", "from matplotlib import animation\n", "\n", "k = 2*pi\n", "w = 2*pi\n", "dt = 0.01\n", "\n", "xmin = 0\n", "xmax = 3\n", "nbx = 1000\n", "\n", "x = linspace(xmin, xmax, nbx)\n", "\n", "fig = figure() # initialise la figure\n", "line1, = plot([],[],color=\"blue\") \n", "line2, = plot([],[],color=\"red\")\n", "xlim(xmin, xmax)\n", "ylim(-1,1)\n", "\n", "\n", "# cr\u00e9e l'arri\u00e8re de l'animation qui sera pr\u00e9sent sur chaque image\n", "def init():\n", " line1.set_data([],[])\n", " line2.set_data([],[])\n", " return line1,line2,\n", "\n", "def animate(i): \n", " t = i * dt\n", " y = cos(k*x - w*t)\n", " z=cos(2*k*x-w*t)\n", " line1.set_data(x, y)\n", " line2.set_data(y+1, z)\n", " return line1,line2,\n", " \n", "ani = animation.FuncAnimation(fig, animate, init_func=init, frames=100, blit=True, interval=20, repeat=True)\n", "# frames : plage temporelle\n", "# interval : temps en millisecondes entre deux mises \u00e0 jour\n", "\n", "show()" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "display_data", "png": "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\n87xZLWa244tNW1vb017CnJnPe5PYX7Gb7/ubrceG/8KFC76ePBgMKp1Oj99Op9MKhUJTjnXO+ZoL\nAJCbJ3KpZ7pob9iwQX19ferv79fo6KhOnTqleDz+JKYEAOQp7/CfOXNG4XBY3d3d2rx5sxobGyVJ\nt27d0ubNmyVJJSUlam9vV0NDg6qrq7V161a+sAsAT5sroPPnz7sXXnjBRSIRt3///inHfPjhhy4S\nibi1a9e6q1evFnJ5vs20v4sXL7olS5a42tpaV1tb6z777LOnsMr87Nixw61YscK9+OKL044p5rOb\naX/FfHbOOXfz5k0Xi8VcdXW1W716tTt48OCU44r1DHPZX7Ge4f37993LL7/sampqXDQadR9//PGU\n42ZzdgUL/4MHD9xzzz3nfv/9dzc6Oupqampcb2/vhDHnzp1zjY2Nzjnnuru7XV1dXaGW51su+7t4\n8aLbsmXLU1qhPz/++KO7evXqtGEs5rNzbub9FfPZOefc0NCQ6+npcc45d/fuXff888/Pqz9/ueyv\nmM/w3r17zjnnxsbGXF1dnfvpp58mPD7bsyvYj2z473v6S0tLx9/T/18dHR1KJBKSpLq6Oo2MjCiT\nyRRqib7ksj+peL+IvXHjRi1btmzax4v57KSZ9ycV79lJ0sqVK1VbWytJWrRokaLRqG7dujVhTDGf\nYS77k4r3DMvKyiRJo6OjymazWr58+YTHZ3t2BQt/Lu/pn2rMwMBAoZboSy778zxPly9fVk1NjZqa\nmtTb21voZc6ZYj67XMyns+vv71dPT4/q6uom3D9fznC6/RXzGT58+FC1tbUKBAJ67bXXVF1dPeHx\n2Z5d3t+5O1u5vkf/0b+Ri+W9/bmsc/369Uqn0yorK9P58+fV3Nys69evF2B1hVGsZ5eL+XJ2//zz\nj95++20dPHhQixYtmvR4sZ/h4/ZXzGf4zDPP6Ndff9Xff/+thoYGJZNJxWKxCWNmc3YFe8Wfy3v6\nHx0zMDCgYDBYqCX6ksv+Fi9ePP5PtsbGRo2NjWl4eLig65wrxXx2uZgPZzc2Nqa33npL7733npqb\nmyc9XuxnONP+5sMZLl26VJs3b9Yvv/wy4f7Znl3Bwp/Le/rj8biOHz8uSeru7lZ5ebkCgUChluhL\nLvvLZDLjfyunUik55yZdqytWxXx2uSj2s3POqaWlRdXV1froo4+mHFPMZ5jL/or1DO/cuaORkRFJ\n0v3793XhwgWtW7duwpjZnl3BLvX89z392WxWLS0tikajOnz4sCSptbVVTU1N6uzsVCQS0cKFC3X0\n6NFCLc+3XPZ3+vRpHTp0SCUlJSorK9PJkyef8qpzt337dl26dEl37txROBxWW1ubxsbGJBX/2Ukz\n76+Yz06Sfv75Z3399ddau3bteDT27dunmzdvSir+M8xlf8V6hkNDQ0okEnr48KEePnyo999/X5s2\nbfLVTs8V65e5AQB54X/gAgBjCD8AGEP4AcAYwg8AxhB+ADCG8AOAMf8DZNR6/yLd36kAAAAASUVO\nRK5CYII=\n" } ], "prompt_number": 2 }, { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "Th\u00e8me 4 : les tris" ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "exercice 6" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "Etant donn\u00e9 une liste $L$ de nombres r\u00e9els et une fonction $F:\\mathbb{R}\\to \\mathbb{R}$, on veut trier la liste $L$ selon la fonction $F$, c'est-\u00e0-dire produire une liste $M$ \u00e9gale \u00e0 la liste $L$ \u00e0 ordre pr\u00e8s, avec pour tout $k$ entre $0$ et $len(M)-1$, $F(M[k])\\leq F(M[k+1])$.\n", "\n", "**question 1)**\n", "\n", "Impl\u00e9menter une fonction permettant le tri de la liste $L$ selon la fonction $F$, par le tri insertion.\n", "\n", "**question 2)**\n", "\n", "Impl\u00e9menter une fonction permettant le tri de la liste $L$ selon la fonction $F$, par le tri fusion r\u00e9cursif.\n", "\n", "**question 3)**\n", "\n", "Impl\u00e9menter une fonction permettant le tri de la liste $L$ selon la fonction $F$, par le tri rapide r\u00e9cursif.\n", "\n" ] }, { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "Th\u00e8me 5 : les tableaux" ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "exercice 7" ] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": [ "question 1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "R\u00e9diger une fonction d'argument $n$, construisant la matrice de taille $n\\times n$, comportant tous les entiers entre $0$ et $n^2-1$, les entiers \u00e9tant pris dans l'ordre croissant et l'ordre de remplissage \u00e9tant :\n", "\n", "$\\bullet$ commencer la premi\u00e8re ligne dans le sens de la lecture\n", "\n", "$\\bullet$ remplir la deuxi\u00e8me ligne de droite \u00e0 gauche\n", "\n", "$\\bullet$ remplir la troisi\u00e8me ligne de gauche \u00e0 droite\n", "\n", "$\\bullet$ etc. d'une ligne \u00e0 l'autre, inverser le sens de remplissage.\n", "\n", "Par exemple, pour $n=2$, on obtient $\\left(\\begin{array}{cc}\n", "0&1\\cr\n", "3&2\\cr\n", "\\end{array}\\right)$ et pour $n=3$, on obtient $\\left(\\begin{array}{ccc}\n", "0&1&2\\cr\n", "5&4&3\\cr\n", "6&7&8\\cr\n", "\\end{array}\\right)$." ] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": [ "question 2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "R\u00e9diger une fonction d'argument $n$, construisant la matrice de taille $n\\times n$, comportant tous les entiers entre $0$ et $n^2-1$, les entiers \u00e9tant pris dans l'ordre croissant et l'ordre de remplissage \u00e9tant en spirale tournant \u00e0 partir de la position $(0,0)$ dans le sens trigonom\u00e9trique.\n", "\n", "Par exemple, pour $n=2$, on obtient $\\left(\\begin{array}{cc}\n", "0&3\\cr\n", "1&2\\cr\n", "\\end{array}\\right)$ et pour $n=3$, on obtient $\\left(\\begin{array}{ccc}\n", "0&7&6\\cr\n", "1&8&5\\cr\n", "2&3&4\\cr\n", "\\end{array}\\right)$." ] }, { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "Th\u00e8me 6 : les bases de donn\u00e9es" ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "exercice 8" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "On consid\u00e8re une base de donn\u00e9es comportant trois tables :\n", " \n", " $\\rhd$ la table **pays** comportant deux colonnes : **nom** et **capitale**, indiquant le nom du pays et sa capitale\n", "\n", " $\\rhd$ la table **villes** avec deux colonnes : **nom** et **etat**, indiquant le nom de la ville et son pays \n", "\n", " $\\rhd$ la table **pop** comportant deux colonnes : **nom** et **hab**, indiquant le nom de la ville et son nombre d'habitants." ] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": [ "question 1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Donner la requ\u00eate **SQL** renvoyant les villes de plus d'un million d'habitants. Retranscrire cette requ\u00eate en langage relationnel.\n", "\n", "Donner la requ\u00eate **SQL** indiquant le nombre des villes de plus d'un million d'habitants, par pays." ] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": [ "question 2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Donner la requ\u00eate **SQL** indiquant la ville la plus peupl\u00e9e, par pays." ] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": [ "question 3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Dans la table **pop**, donner un exemple de cl\u00e9 primaire." ] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": [ "question 4)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Que signifie la phrase suivante \u00e9crite en langage relationnelle :\n", "\n", "${\\Large \\pi_{villes.nom}\\Bigl(\\sigma_{pop.hab\\leqslant 500000}(\\sigma_{villes.etat ~ LIKE ~\" F\\% \"}(villes \\hspace{1.3cm}\\Join_{_{\\hspace{-1.8cm} villes.nom=pop.nom}} pop))\\Bigr)}$.\n", "\n", "La retranscrire en langage **SQL**." ] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": [ "question 5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Donner la r\u00e9qu\u00eate **SQL** permettant d'avoir par pays la liste des villes plus peupl\u00e9es que la capitale." ] }, { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "Corrig\u00e9s" ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Th\u00e8me 1 : la r\u00e9cursivit\u00e9" ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "exercice 1" ] }, { "cell_type": "code", "collapsed": false, "input": [ "def Palindrome(s):\n", " if len(s) <= 1:\n", " return True\n", " else:\n", " if s[0] != s[-1]:\n", " return False\n", " else:\n", " return Palindrome(s[1:-1])" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 3 }, { "cell_type": "code", "collapsed": false, "input": [ "print(Palindrome(\"Ceci est un essai\"))" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "False\n" ] } ], "prompt_number": 4 }, { "cell_type": "code", "collapsed": false, "input": [ "print(Palindrome(\"palindrome emordnilap\"))" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "True\n" ] } ], "prompt_number": 5 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "exercice 2" ] }, { "cell_type": "code", "collapsed": false, "input": [ "def Cantor(x,y) :\n", " if [x,y]==[0,0] :\n", " return 0\n", " else :\n", " if y!=0 :\n", " return 1+Cantor(x+1,y-1)\n", " else :\n", " return 1+Cantor(0,x-1)\n", "\n" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 6 }, { "cell_type": "code", "collapsed": false, "input": [ "print(Cantor(5,7))" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "85\n" ] } ], "prompt_number": 7 }, { "cell_type": "code", "collapsed": false, "input": [ "#print(Cantor(9,90)) # Remarque : on voit les limites de la r\u00e9cursivit\u00e9 gourmande en m\u00e9moire. \n", "#Temps d'ex\u00e9cution trop long" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 8 }, { "cell_type": "code", "collapsed": false, "input": [ "def Cantor_Ite(x,y) :\n", " d=x+y\n", " s=0\n", " for k in range(1,d+1) :\n", " s+=k\n", " return s+y" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 9 }, { "cell_type": "code", "collapsed": false, "input": [ "print(Cantor_Ite(5,7))\n", "print(Cantor_Ite(9,90))" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "85\n", "5040\n" ] } ], "prompt_number": 10 }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Th\u00e8me 2 : les piles" ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "exercice 3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**question 1)**" ] }, { "cell_type": "code", "collapsed": false, "input": [ "\n", "def Chemin(Mat,i,j) :\n", " \"\"\" calcule un chemin permettant d'aller de i vers j, en un chemin s tel que M[s[k],s[k+1]]=1 pour tout k \"\"\"\n", " \"\"\" recherche en profondeur par pile \"\"\"\n", " Pile=[i]\n", " Assiettes=[k for k in range(Mat.shape[0]) if k!=i]\n", " while Pile!=[] and Pile[-1]!=j :\n", " \n", " k=Pile[-1]\n", " Test=False \n", " for l in Assiettes :\n", " if Mat[k,l]==1 :\n", " Test=True\n", " Pile.append(l)\n", " Assiettes.remove(l)\n", " break\n", " if not(Test) :\n", " Pile.pop()\n", " if Pile==[] :\n", " return \"pas de chemin possible \"\n", " else :\n", " return Pile\n", " " ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 11 }, { "cell_type": "markdown", "metadata": {}, "source": [ "**question 2)**" ] }, { "cell_type": "code", "collapsed": false, "input": [ "def Spheres(Mat,i) :\n", " S=list(range(Mat.shape[0])).copy()\n", " Spheres=[[i]]\n", " S.remove(i)\n", " Test=True\n", " while Test :\n", " Nlle_Sphere=[]\n", " for x in Spheres[-1] :\n", " for y in S :\n", " if Mat[x,y]==1 :\n", " Nlle_Sphere.append(y)\n", " \n", " S=[z for z in S if not(z in Nlle_Sphere)] \n", " \n", " if Nlle_Sphere!=[] :\n", " Spheres.append(Nlle_Sphere.copy())\n", " else :\n", " Test=False\n", " return Spheres\n", " " ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 12 }, { "cell_type": "code", "collapsed": false, "input": [ "def Connexe(Mat,i) :\n", " L_Spheres=Spheres(Mat,i)\n", " S=list(range(Mat.shape[0])).copy()\n", " for X in L_Spheres :\n", " for y in X :\n", " S.remove(y)\n", " return S\n", " " ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 13 }, { "cell_type": "code", "collapsed": false, "input": [ "\n", "def Chemin_Bis(Mat,i,j) :\n", " S=list(range(Mat.shape[0])).copy()\n", " Spheres=[[i]]\n", " S.remove(i)\n", " k=0\n", " Test=False\n", " while 1 :\n", " k+=1\n", " Nlle_Sphere=[]\n", " for x in Spheres[-1] :\n", " for y in S :\n", " if Mat[x,y]==1 :\n", " Nlle_Sphere.append(y)\n", " \n", " if y==j :\n", " Test=True\n", " S=[z for z in S if not(z in Nlle_Sphere)] \n", "\n", " if Nlle_Sphere!=[] :\n", " Spheres.append(Nlle_Sphere.copy())\n", " else :\n", " break\n", " if Test :\n", " break\n", " \n", " if not(Test) :\n", " return \"pas de chemin possible\"\n", " else :\n", " Res=[j]\n", " while k!=0 :\n", " k-=1\n", " sphere=Spheres[k]\n", " l=0\n", " while Mat[sphere[l],Res[0]]==0 :\n", " l+=1\n", " Res=[sphere[l]]+Res\n", " return Res" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 14 }, { "cell_type": "markdown", "metadata": {}, "source": [ "**question 3)**" ] }, { "cell_type": "code", "collapsed": false, "input": [ "def Graphe_Alea(n,p):\n", " M=zeros((n,n))\n", " for i in range(n) :\n", " for j in range(n) :\n", " if i!=j and binomial(1,p) :\n", " M[i,j]=1\n", " return M" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 15 }, { "cell_type": "code", "collapsed": false, "input": [ "n=200\n", "p=0.01\n", "M=Graphe_Alea(n,p)\n", "\n", "print(\"liste des points non atteignable \u00e0 partir de 0 :\",Connexe(M,0))\n", "print(\" chemin en profondeur :\",Chemin(M,0,20)) \n", "print(\" chemin en largeur optimal :\",Chemin_Bis(M,0,20))" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "liste des points non atteignable \u00e0 partir de 0 : [1, 11, 17, 25, 36, 39, 44, 46, 50, 56, 59, 68, 74, 78, 80, 89, 92, 93, 100, 119, 122, 136, 138, 146, 149, 153, 159, 163, 166, 169, 176, 186, 196, 197, 198]\n", " chemin en profondeur : [0, 22, 38, 151, 125, 19, 28, 165, 195, 40, 26, 45, 58, 3, 9, 47, 106, 4, 63, 10, 85, 16, 144, 177, 70, 53, 76, 18, 84, 172, 160, 65, 114, 15, 112, 23, 124, 64, 141, 164, 20]\n", " chemin en largeur optimal : [0, 97, 52, 141, 164, 20]\n" ] } ], "prompt_number": 16 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "exercice 4" ] }, { "cell_type": "code", "collapsed": false, "input": [ "def Composante(M,contour,depart) :\n", " M_Temp=M.copy()\n", " for t in linspace(0,1,1000) :\n", " x,y=contour(t)\n", " M_Temp[x,y]=(0,0,0)\n", " \n", " dx,dy=M.shape[:2]\n", " def Voisins(M,point) :\n", " i,j=point\n", " Res=[]\n", " if i>0 :\n", " Res.append([i-1,j])\n", " if i0 :\n", " Res.append([i,j-1])\n", " if j=F(a)]\n", " return Tri_Rapide(L1,F)+[a]+Tri_Rapide(L2,F)\n", " \n", " " ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 22 }, { "cell_type": "code", "collapsed": false, "input": [ "L=[7,8,-1,3,-5,5,1,2,3,1,1,2,1,1,0,0,1,2,-2,-2,-3]\n", "\n", "def H(t) :\n", " return t**2\n", "\n", "print(Tri_Insertion(L,H))\n", "print(Tri_Fusion(L,H))\n", "print(Tri_Rapide(L,H))\n" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[0, 0, -1, 1, 1, 1, 1, 1, 1, 2, 2, 2, -2, -2, 3, 3, -3, -5, 5, 7, 8]\n", "[0, 0, -1, 1, 1, 1, 1, 1, 1, 2, 2, 2, -2, -2, 3, 3, -3, -5, 5, 7, 8]\n", "[0, 0, -1, 1, 1, 1, 1, 1, 1, 2, 2, 2, -2, -2, 3, 3, -3, -5, 5, 7, 8]\n" ] } ], "prompt_number": 23 }, { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "Th\u00e8me 5 : les tableaux" ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "exercice 7" ] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": [ "question 1)" ] }, { "cell_type": "code", "collapsed": false, "input": [ "def Mat(n) :\n", " M=zeros((n,n))\n", " Dir=1\n", " k=0\n", " i,j=0,0\n", " while k!=n**2 :\n", " M[i,j]=k\n", " if Dir==1 and j==0 :\n", " j+=1\n", " elif Dir==-1 and j==0 :\n", " Dir=1\n", " i+=1\n", " elif Dir==1 and j==n-1 :\n", " Dir=-1\n", " i+=1\n", " else :\n", " j+=Dir\n", " k+=1\n", " return M\n", " " ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 24 }, { "cell_type": "code", "collapsed": false, "input": [ "print(Mat(10))" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[[ 0. 1. 2. 3. 4. 5. 6. 7. 8. 9.]\n", " [ 19. 18. 17. 16. 15. 14. 13. 12. 11. 10.]\n", " [ 20. 21. 22. 23. 24. 25. 26. 27. 28. 29.]\n", " [ 39. 38. 37. 36. 35. 34. 33. 32. 31. 30.]\n", " [ 40. 41. 42. 43. 44. 45. 46. 47. 48. 49.]\n", " [ 59. 58. 57. 56. 55. 54. 53. 52. 51. 50.]\n", " [ 60. 61. 62. 63. 64. 65. 66. 67. 68. 69.]\n", " [ 79. 78. 77. 76. 75. 74. 73. 72. 71. 70.]\n", " [ 80. 81. 82. 83. 84. 85. 86. 87. 88. 89.]\n", " [ 99. 98. 97. 96. 95. 94. 93. 92. 91. 90.]]\n" ] } ], "prompt_number": 25 }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": [ "question 2)" ] }, { "cell_type": "code", "collapsed": false, "input": [ "def Spirale(n):\n", " M=(-1)*ones((n,n))\n", " Curseur=array([[0],[0]])\n", " Dir=array([[1],[0]])\n", " Rot=array([[0,-1],[1,0]])\n", " k=0\n", " while k!=n**2 :\n", " \n", " M[Curseur[0,0],Curseur[1,0]]=k\n", " New_Curseur=Curseur+Dir\n", " x,y=New_Curseur[:,0]\n", "\n", " if not(x==-1 or x==n or y==-1 or y==n or M[x,y]!=-1) :\n", " Curseur=New_Curseur\n", " \n", " else :\n", " Dir=dot(Rot,Dir)\n", " Curseur=Curseur+Dir\n", " k+=1\n", " return M" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 26 }, { "cell_type": "code", "collapsed": false, "input": [ "print(Spirale(10))" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[[ 0. 35. 34. 33. 32. 31. 30. 29. 28. 27.]\n", " [ 1. 36. 63. 62. 61. 60. 59. 58. 57. 26.]\n", " [ 2. 37. 64. 83. 82. 81. 80. 79. 56. 25.]\n", " [ 3. 38. 65. 84. 95. 94. 93. 78. 55. 24.]\n", " [ 4. 39. 66. 85. 96. 99. 92. 77. 54. 23.]\n", " [ 5. 40. 67. 86. 97. 98. 91. 76. 53. 22.]\n", " [ 6. 41. 68. 87. 88. 89. 90. 75. 52. 21.]\n", " [ 7. 42. 69. 70. 71. 72. 73. 74. 51. 20.]\n", " [ 8. 43. 44. 45. 46. 47. 48. 49. 50. 19.]\n", " [ 9. 10. 11. 12. 13. 14. 15. 16. 17. 18.]]\n" ] } ], "prompt_number": 27 }, { "cell_type": "code", "collapsed": false, "input": [ "def Visualisation(M) :\n", " figure()\n", " axis('off')\n", " imshow(M)\n", " colorbar()\n", " show()\n", "\n", "\n", "Visualisation(Mat(500))\n", "Visualisation(Spirale(500))" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "display_data", "png": "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\nTkSuQmCC\n" }, { "output_type": "display_data", "png": "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\nLdy9qqbM9AAAAABJRU5ErkJggg==\n" } ], "prompt_number": 28 }, { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "Th\u00e8me 6 : les bases de donn\u00e9es" ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "exercice 8" ] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": [ "question 1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "SELECT villes.nom FROM ( villes JOIN pop ON villes.nom=pop.nom) WHERE pop.hab>1000000 ;\n", "\n", "En langage relationnel :\n", "\n", "$\\Large \\pi_{villes.nom}\\Bigl(\\sigma_{pop.hab>1000000}\\Bigl(villes \\hspace{1.3cm} \\Join_{_{\\hspace{-1.8cm} villes.nom=pop.nom}} pop\\Bigr)\\Bigr)$\n", "\n", "SELECT COUNT(*) FROM ( SELECT villes.nom FROM ( villes JOIN pop ON villes.nom=pop.nom) WHERE pop.hab>1000000 ) GROUP BY villes.etat ;" ] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": [ "question 2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "SELECT pop.nom,MAX(pop.hab) FROM (villes JOIN pop ON villes.nom=pop.nom) GROUP BY villes.etat ;" ] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": [ "question 3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Une cl\u00e9 primaire est \u00e9videmment le couple (**nom** , **hab**) et on peut l\u00e9gitimement penser que l'attribut **hab** est \u00e9galement une cl\u00e9 primaire, car il est improbable que deux villes diff\u00e9rentes comptent exactement le m\u00eame nombre d'habitants.\n", "\n", "L'attribut **nom** n'est pas une cl\u00e9 primaire, \u00e0 cause des villes homonymes." ] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": [ "question 4)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "La phrase :\n", " \n", " \n", "${\\Large \\pi_{villes.nom}\\Bigl(\\sigma_{pop.hab\\leqslant 500000}(\\sigma_{villes.etat ~ LIKE ~\" F\\% \"}(villes \\hspace{1.3cm}\\Join_{_{\\hspace{-1.8cm} villes.nom=pop.nom}} pop))\\Bigr)}$ \n", "\n", "revient \u00e0 trouver les noms des villes de moins de 500000 habitants et dont le pays commence par la lettre \"F\".\n", "\n", "La requ\u00eate **SQL** associ\u00e9e est :\n", "\n", "SELECT villes.nom FROM (villes JOIN pop ON villes.nom=pop.nom) WHERE (pop.hab<= 500000 ~AND ~villes.etat~LIKE~\"F\\%\") ;\n" ] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": [ "question 5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Il faut ici faire des jointures de toutes les tables, car on a besoin de l'information dans chaque table.\n", "\n", "\n", "On proc\u00e8de par \u00e9tapes :\n", "\n", "$\\rhd$ table des populations par capitale\n", "\n", "SELECT pays.capitale,pop.hab FROM pays JOIN pop ON pays.capitale=pop.nom\n", "\n", "$\\rhd$ table des villes plus peupl\u00e9es que la capitale\n", "\n", "SELECT villes.noms FROM ((SELECT pays.capitale,pop.hab AS pop_cap FROM pays JOIN pop ON pays.capitale=pop.nom AS TAB1) JOIN villes ON pays.nom=villes.etat) WHERE pop.hab>pop_cap ;" ] }, { "cell_type": "code", "collapsed": false, "input": [], "language": "python", "metadata": {}, "outputs": [] } ], "metadata": {} } ] }