diff --git a/recursivite/recursivite.ipynb b/recursivite/recursivite.ipynb index a3733829e07cd19231983e1ba0bbc843800380f0..490abf1d37628c859941bce90aaf74e83986a12d 100644 --- a/recursivite/recursivite.ipynb +++ b/recursivite/recursivite.ipynb @@ -1 +1 @@ -{"cells":[{"metadata":{},"cell_type":"markdown","source":"<h1 class=\"alert alert-success\">Récursivité </h2>"},{"metadata":{},"cell_type":"markdown","source":"<h2 class=\"alert alert-info\"> 1. Introduction </h2>\n\nLa **récursivité** est un concept qui est très proche de la notion mathématiques de la récurrence. On dit qu’une fonction est récursive si elle s’appelle elle-même.\nPour résoudre un problème ou effectuer un calcul, on se ramène à la résolution d’un problème similaire mais de complexité moindre. On recommence ainsi jusqu’à obtenir un problème élémentaire que l’on sait résoudre. \n\n!!! note Définition\nOn qualifie de **récursive** toute fonction qui s'appelle elle-même.\n!!!\n\nLa plus-part des langages de programmation actuels permettent de mettre en œuvre directement cette réduction du problème, en autorisant une fonction à s’appeler elle-même : on parle alors de fonction récursive. On trouvera souvent deux versions possibles d'un même programme : itérative et récursive.\n\nCependant deux éléments sont indispensables à la terminaison d’une fonction récursive :\n\n- il est nécessaire qu’il y ait une condition d’arrêt ;\n- il ne doit pas y avoir de suite infinie d’appels récursifs.\n\n### Exemple\nOn souhaite calculer la somme $S=\\sum_{i=1}^n i =1 +2+3+\\cdots+(n-1) + n$. Ci-dessous une fonction recursive qui calcule la somme des $n$ premiers termes dont on peut visualiser les appels"},{"metadata":{"trusted":true},"cell_type":"code","source":"from rcviz import viz # pour visualiser les appels \n@viz\ndef somme(n):\n if n < 1:\n return 0\n else:\n return n + somme(n - 1)\n\nsomme(4) # calcule 1 + 2 + 3 + 4","execution_count":1,"outputs":[{"output_type":"stream","text":"Traceback (most recent call last):\n File \"<input>\", line 1, in <module>\nModuleNotFoundError: The module 'rcviz' is included in the Pyodide distribution, but it is not installed.\nYou can install it by calling:\n await micropip.install(\"rcviz\") in Python, or\n await pyodide.loadPackage(\"rcviz\") in JavaScript\nSee https://pyodide.org/en/stable/usage/loading-packages.html for more details.\n","name":"stderr"},{"output_type":"error"}]},{"metadata":{},"cell_type":"markdown","source":"Un sous-programme est dit récursif s’il fait appel à lui-même, comme ici.\nDétaillons la procédure compte :\n\n- Pour calculer la somme des `n` termes, on dépcompose le problème comme calculer la somme des `n-1` termes plus `n`;\n- le test `n < 0` est une condition d’arrêt, obligatoire sinon le sous-programme peut boucler indéfiniment;\n- les appels récursifs continuent jusqu’à ce que le paramètre passé à la procédure prenne la valeur 0;\n- la dernière valeur retournée est donc 0.\n\nOn peut visualiser les appels avec :"},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"somme.callgraph() # pour visualiser les appels récusifs","execution_count":2,"outputs":[{"output_type":"stream","text":"Traceback (most recent call last):\n File \"<input>\", line 1, in <module>\nNameError: name 'somme' is not defined\n","name":"stderr"},{"output_type":"error"}]},{"metadata":{},"cell_type":"markdown","source":"On remarque qu'il est possible d'exécuter cette fonction avec un paramètre qui n'est pas un entier positif. Pour interdire ce cas de figure on peut utiliser l'instruction `assert` :"},{"metadata":{"trusted":true},"cell_type":"code","source":"def somme(n):\n assert n >= 0 and isinstance(n, int), \"n doit être un entier naturel\"\n if n < 1:\n return 0\n else:\n return n + somme(n - 1)","execution_count":20,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"somme(-2)","execution_count":21,"outputs":[{"output_type":"stream","text":"Traceback (most recent call last):\n File \"<input>\", line 1, in <module>\n File \"<input>\", line 2, in somme\nAssertionError: n doit être un entier naturel\n","name":"stderr"},{"output_type":"error"}]},{"metadata":{"trusted":true,"scrolled":true},"cell_type":"code","source":"somme(2.8)","execution_count":22,"outputs":[{"output_type":"stream","text":"Traceback (most recent call last):\n File \"<input>\", line 1, in <module>\n File \"<input>\", line 2, in somme\nAssertionError: n doit être un entier naturel\n","name":"stderr"},{"output_type":"error"}]},{"metadata":{"trusted":true},"cell_type":"code","source":"somme(8)","execution_count":23,"outputs":[{"output_type":"execute_result","execution_count":23,"data":{"text/plain":"36"},"metadata":{}}]},{"metadata":{},"cell_type":"markdown","source":"<h3 style=\"color:teal;background-color:azure;\" > <i class=\"fa fa-pencil\" aria-hidden=\"true\"> </i> Exercice 1 : Somme des éléments d'une liste </h3>\n\nEcrire une fonction récursive ```somme_liste``` qui :\n\n- prend en paramètre une liste d'entiers `L`\n- retourne la somme des éléments de la liste `L`\n\n\n**Coup de pouce :** \n\n*Condition d'arrêt* : si la liste contient un seul élément, la somme de ses élément vaut la valeur de cet élément : donc la fonction renvoie ce nombre.\n\n*Récursion* : renvoyer la valeur du 1er élément additionnée de la somme du reste de la liste."},{"metadata":{"trusted":true},"cell_type":"code","source":"# VOTRE CODE CI-DESSOUS\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# test \ntab = [5, 4, 7, 2]\nsomme(tab)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<h3 style=\"color:teal;background-color:azure;\" > <i class=\"fa fa-pencil\" aria-hidden=\"true\"> </i> Exercice 2 : Miroir d’une chaîne de caractère </h3>\n\nÉcrire une fonction ```miroir``` récursive qui :\n\n- prend comme paramètre une chaîne de caractères `s`\n- renvoie le « miroir » de la chaîne; par exemple, le miroir de \"abcde\" est \"edcba\".\n\n\n**Coup de pouce :** \n\n*Condition d'arrêt* : si la chaine contient un seul caractère ou aucun, son miroir est elle-même.\n\n*Récursion* : Le principe consiste à permutter le 1er et le dernier carcatère, et à recopier le miroir de la sous-chaine interne (entre le 2ème caractère et l'avant-dernier) au milieu de ces 2 caractères. Il faut donc renvoyer une chaine qui est la concaténation du dernier caratère, du miroir de la sous-chaine interne, et du 1er caractère.\n\n**Aide** : on pourra utiliser la syntaxe ```s[1:-1]``` qui permet d'extraire une sous-chaine de caractères entre le second élément de l'avant dernier."},{"metadata":{"trusted":true},"cell_type":"code","source":"# VOTRE CODE CI-DESSOUS","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# test\nchaine = 'quelle belle chaine'\nmiroir(chaine)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<h2 class=\"alert alert-info\">2. Rappels sur Turtle</h2>\n\nTurtle est un module Python permettant de dessiner sur un canevas. Le crayon est dirigé par une tortue !\n\nJupyter propose une implémentation de ce module (très légèrement modifié). Les commandes principales consistent à positionner la tortue, lever ou baisser le crayon (pour écrire ou non lorsque la tortue se déplace) et à commander les mouvements de la tortue (avancer/reculer, tourner à gauche/droite d'un certain angle).\n\nPour mieux comprendre et découvrir les commandes accessibles, étudier l'exemple de démonstration ci-dessous :"},{"metadata":{"trusted":false},"cell_type":"code","source":"import turtle as tt # import du module turtle\n\ntt.speed(3) # vitesse moyenne (maxi = 10)\n\ntt.penup() # lève le crayon (pour ne pas écrire pendant le déplacement)\ntt.setposition(-100, 100) \n# origine (0, 0) au centre du cadre de dessin (dimensions 600x600)\ntt.pendown() # abaisse le crayon (pour voir la trace de la tortue)\n\ntt.forward(20) # avance de 20\ntt.left(60) # virage de 60° vers la gauche\ntt.forward(100) \ntt.right(120) # virage de 120° vers la droite\ntt.pencolor(\"red\") # couleurs autorisées \"blue\", \"yellow\", \"brown\", \"black\", \"purple\", \"green\"\ntt.forward(100) \ntt.left(60) \ntt.forward(100) # recule de 100\ntt.backward(70) \ntt.right(90) \ntt.pencolor(\"green\") \ntt.forward(300) \n\ntt.penup()\ntt.home() # retour à l'origine\n\ntt.done() # indispensable pour activer la tortue dans Basthon","execution_count":3,"outputs":[{"output_type":"display_data","data":{"image/svg+xml":"<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"640\" height=\"480\" preserveaspectratio=\"xMidYMid meet\" viewbox=\"0 0 640 480\"><animate id=\"af_834c721b65114680add0597f36cbe268_0\" attributename=\"opacity\" attributetype=\"CSS\" from=\"1\" to=\"1\" begin=\"0s\" dur=\"1ms\" fill=\"freeze\"></animate><g transform=\"translate(320 240)\"></g><g transform=\"translate(320 240)\"><line x1=\"0\" y1=\"0\" x2=\"0\" y2=\"0\" style=\"stroke: black;stroke-width: 1\"><animate id=\"af_834c721b65114680add0597f36cbe268_2\" attributename=\"x2\" attributetype=\"XML\" from=\"0\" to=\"0\" dur=\"1ms\" fill=\"freeze\" begin=\"af_834c721b65114680add0597f36cbe268_1.end\"></animate><animate attributename=\"y2\" attributetype=\"XML\" begin=\"af_834c721b65114680add0597f36cbe268_1.end\" from=\"0\" to=\"0\" dur=\"1ms\" fill=\"freeze\"></animate></line><line x1=\"0\" y1=\"0\" x2=\"0\" y2=\"0\" style=\"stroke: black;stroke-width: 1\" opacity=\"0\"><animate id=\"af_834c721b65114680add0597f36cbe268_5\" attributename=\"x2\" attributetype=\"XML\" from=\"0\" to=\"-100\" dur=\" 1.070s\" fill=\"freeze\" begin=\"af_834c721b65114680add0597f36cbe268_4.end\"></animate></line><line x1=\"-100\" y1=\"-100\" x2=\"-100\" y2=\"-100\" style=\"stroke: black;stroke-width: 1\"><animate id=\"af_834c721b65114680add0597f36cbe268_6\" attributename=\"x2\" attributetype=\"XML\" from=\"-100\" to=\"-80\" dur=\" 0.107s\" fill=\"freeze\" begin=\"af_834c721b65114680add0597f36cbe268_5.end\"></animate><animate attributename=\"y2\" attributetype=\"XML\" begin=\"af_834c721b65114680add0597f36cbe268_5.end\" from=\"-100\" to=\"-100\" dur=\" 0.107s\" fill=\"freeze\"></animate></line><line x1=\"-80\" y1=\"-100\" x2=\"-80\" y2=\"-100\" style=\"stroke: black;stroke-width: 1\"><animate id=\"af_834c721b65114680add0597f36cbe268_8\" attributename=\"x2\" attributetype=\"XML\" from=\"-80\" to=\"-29.999999999999986\" dur=\" 0.535s\" fill=\"freeze\" begin=\"af_834c721b65114680add0597f36cbe268_7.end\"></animate><animate attributename=\"y2\" attributetype=\"XML\" begin=\"af_834c721b65114680add0597f36cbe268_7.end\" from=\"-100\" to=\"-186.60254037844385\" dur=\" 0.535s\" fill=\"freeze\"></animate></line><line x1=\"-29.999999999999986\" y1=\"-186.60254037844385\" x2=\"-29.999999999999986\" y2=\"-186.60254037844385\" style=\"stroke: red;stroke-width: 1\"><animate id=\"af_834c721b65114680add0597f36cbe268_11\" attributename=\"x2\" attributetype=\"XML\" from=\"-29.999999999999986\" to=\"20.00000000000003\" dur=\" 0.535s\" fill=\"freeze\" begin=\"af_834c721b65114680add0597f36cbe268_10.end\"></animate><animate attributename=\"y2\" attributetype=\"XML\" begin=\"af_834c721b65114680add0597f36cbe268_10.end\" from=\"-186.60254037844385\" to=\"-99.99999999999999\" dur=\" 0.535s\" fill=\"freeze\"></animate></line><line x1=\"20.00000000000003\" y1=\"-99.99999999999999\" x2=\"20.00000000000003\" y2=\"-99.99999999999999\" style=\"stroke: red;stroke-width: 1\"><animate id=\"af_834c721b65114680add0597f36cbe268_13\" attributename=\"x2\" attributetype=\"XML\" from=\"20.00000000000003\" to=\"120.00000000000003\" dur=\" 0.535s\" fill=\"freeze\" begin=\"af_834c721b65114680add0597f36cbe268_12.end\"></animate><animate attributename=\"y2\" attributetype=\"XML\" begin=\"af_834c721b65114680add0597f36cbe268_12.end\" from=\"-99.99999999999999\" to=\"-99.99999999999999\" dur=\" 0.535s\" fill=\"freeze\"></animate></line><line x1=\"120.00000000000003\" y1=\"-99.99999999999999\" x2=\"120.00000000000003\" y2=\"-99.99999999999999\" style=\"stroke: red;stroke-width: 1\"><animate id=\"af_834c721b65114680add0597f36cbe268_14\" attributename=\"x2\" attributetype=\"XML\" from=\"120.00000000000003\" to=\"50.00000000000003\" dur=\" 0.375s\" fill=\"freeze\" begin=\"af_834c721b65114680add0597f36cbe268_13.end\"></animate><animate attributename=\"y2\" attributetype=\"XML\" begin=\"af_834c721b65114680add0597f36cbe268_13.end\" from=\"-99.99999999999999\" to=\"-99.99999999999999\" dur=\" 0.375s\" fill=\"freeze\"></animate></line><line x1=\"50.00000000000003\" y1=\"-99.99999999999999\" x2=\"50.00000000000003\" y2=\"-99.99999999999999\" style=\"stroke: green;stroke-width: 1\"><animate id=\"af_834c721b65114680add0597f36cbe268_17\" attributename=\"x2\" attributetype=\"XML\" from=\"50.00000000000003\" to=\"50.00000000000005\" dur=\" 1.605s\" fill=\"freeze\" begin=\"af_834c721b65114680add0597f36cbe268_16.end\"></animate><animate attributename=\"y2\" attributetype=\"XML\" begin=\"af_834c721b65114680add0597f36cbe268_16.end\" from=\"-99.99999999999999\" to=\"200\" dur=\" 1.605s\" fill=\"freeze\"></animate></line><line x1=\"50.00000000000005\" y1=\"200\" x2=\"50.00000000000005\" y2=\"200\" style=\"stroke: green;stroke-width: 1\" opacity=\"0\"><animate id=\"af_834c721b65114680add0597f36cbe268_18\" attributename=\"x2\" attributetype=\"XML\" from=\"50.00000000000005\" to=\"0\" dur=\" 1.338s\" fill=\"freeze\" begin=\"af_834c721b65114680add0597f36cbe268_17.end\"></animate></line></g><g transform=\"translate(320 240)\"></g><g transform=\"translate(320 240)\"><polygon points=\"0,16 -2,14 -1,10 -4,7 -7,9 -9,8 -6,5 -7,1 -5,-3 -8,-6 -6,-8 -4,-5 0,-7 4,-5 6,-8 8,-6 5,-3 7,1 6,5 9,8 7,9 4,7 1,10 2,14\" stroke=\"black\" fill=\"black\" stroke-width=\"1\" opacity=\"0\"><animate id=\"af_834c721b65114680add0597f36cbe268_1\" begin=\"af_834c721b65114680add0597f36cbe268_0.end\" dur=\"1ms\" fill=\"freeze\" attributename=\"opacity\" attributetype=\"XML\" from=\"0\" to=\"1\"></animate><animateMotion begin=\"af_834c721b65114680add0597f36cbe268_2.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateTransform attributename=\"transform\" id=\"af_834c721b65114680add0597f36cbe268_3\" type=\"rotate\" from=\"0,0,0\" to=\"0.0,0,0\" begin=\"af_834c721b65114680add0597f36cbe268_2.end\" dur=\"1ms\" fill=\"freeze\"></animateTransform><animateMotion begin=\"af_834c721b65114680add0597f36cbe268_3.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateTransform attributename=\"transform\" id=\"af_834c721b65114680add0597f36cbe268_4\" type=\"rotate\" from=\"-90.0,0,0\" to=\"-90.0,0,0\" begin=\"af_834c721b65114680add0597f36cbe268_3.end\" dur=\"1ms\" fill=\"freeze\"></animateTransform><animateMotion begin=\"af_834c721b65114680add0597f36cbe268_4.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"0.0,-0.0\" to=\"-100,-100\" dur=\" 1.070s\" begin=\"af_834c721b65114680add0597f36cbe268_4.end\" fill=\"freeze\"></animateMotion><animateMotion begin=\"af_834c721b65114680add0597f36cbe268_5.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"-100,-100\" to=\"-80.0,-100.0\" dur=\" 0.107s\" begin=\"af_834c721b65114680add0597f36cbe268_5.end\" fill=\"freeze\"></animateMotion><animateMotion begin=\"af_834c721b65114680add0597f36cbe268_6.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateTransform attributename=\"transform\" id=\"af_834c721b65114680add0597f36cbe268_7\" type=\"rotate\" from=\"-90.0,0,0\" to=\"-150.0,0,0\" begin=\"af_834c721b65114680add0597f36cbe268_6.end\" dur=\" 0.056s\" fill=\"freeze\"></animateTransform><animateMotion begin=\"af_834c721b65114680add0597f36cbe268_7.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"-80.0,-100.0\" to=\"-29.999999999999986,-186.60254037844385\" dur=\" 0.535s\" begin=\"af_834c721b65114680add0597f36cbe268_7.end\" fill=\"freeze\"></animateMotion><animateMotion begin=\"af_834c721b65114680add0597f36cbe268_8.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateTransform attributename=\"transform\" id=\"af_834c721b65114680add0597f36cbe268_9\" type=\"rotate\" from=\"-150.0,0,0\" to=\"-30.0,0,0\" begin=\"af_834c721b65114680add0597f36cbe268_8.end\" dur=\" 0.111s\" fill=\"freeze\"></animateTransform><animate id=\"af_834c721b65114680add0597f36cbe268_10\" begin=\"af_834c721b65114680add0597f36cbe268_9.end\" dur=\"1ms\" fill=\"freeze\" attributename=\"stroke\" attributetype=\"XML\" from=\"black\" to=\"red\"></animate><animateMotion begin=\"af_834c721b65114680add0597f36cbe268_10.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"-29.999999999999986,-186.60254037844385\" to=\"20.00000000000003,-99.99999999999999\" dur=\" 0.535s\" begin=\"af_834c721b65114680add0597f36cbe268_10.end\" fill=\"freeze\"></animateMotion><animateMotion begin=\"af_834c721b65114680add0597f36cbe268_11.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateTransform attributename=\"transform\" id=\"af_834c721b65114680add0597f36cbe268_12\" type=\"rotate\" from=\"-30.0,0,0\" to=\"-90.0,0,0\" begin=\"af_834c721b65114680add0597f36cbe268_11.end\" dur=\" 0.056s\" fill=\"freeze\"></animateTransform><animateMotion begin=\"af_834c721b65114680add0597f36cbe268_12.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"20.00000000000003,-99.99999999999999\" to=\"120.00000000000003,-99.99999999999999\" dur=\" 0.535s\" begin=\"af_834c721b65114680add0597f36cbe268_12.end\" fill=\"freeze\"></animateMotion><animateMotion begin=\"af_834c721b65114680add0597f36cbe268_13.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"120.00000000000003,-99.99999999999999\" to=\"50.00000000000003,-99.99999999999999\" dur=\" 0.375s\" begin=\"af_834c721b65114680add0597f36cbe268_13.end\" fill=\"freeze\"></animateMotion><animateMotion begin=\"af_834c721b65114680add0597f36cbe268_14.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateTransform attributename=\"transform\" id=\"af_834c721b65114680add0597f36cbe268_15\" type=\"rotate\" from=\"-90.0,0,0\" to=\"0.0,0,0\" begin=\"af_834c721b65114680add0597f36cbe268_14.end\" dur=\" 0.083s\" fill=\"freeze\"></animateTransform><animate id=\"af_834c721b65114680add0597f36cbe268_16\" begin=\"af_834c721b65114680add0597f36cbe268_15.end\" dur=\"1ms\" fill=\"freeze\" attributename=\"stroke\" attributetype=\"XML\" from=\"red\" to=\"green\"></animate><animateMotion begin=\"af_834c721b65114680add0597f36cbe268_16.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"50.00000000000003,-99.99999999999999\" to=\"50.00000000000005,200.0\" dur=\" 1.605s\" begin=\"af_834c721b65114680add0597f36cbe268_16.end\" fill=\"freeze\"></animateMotion><animateMotion begin=\"af_834c721b65114680add0597f36cbe268_17.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"50.00000000000005,200.0\" to=\"0,0\" dur=\" 1.338s\" begin=\"af_834c721b65114680add0597f36cbe268_17.end\" fill=\"freeze\"></animateMotion><animateMotion begin=\"af_834c721b65114680add0597f36cbe268_18.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateTransform attributename=\"transform\" id=\"af_834c721b65114680add0597f36cbe268_19\" type=\"rotate\" from=\"0.0,0,0\" to=\"-90.0,0,0\" begin=\"af_834c721b65114680add0597f36cbe268_18.end\" dur=\" 0.083s\" fill=\"freeze\"></animateTransform></polygon></g></svg>"},"metadata":{}}]},{"metadata":{"trusted":false},"cell_type":"code","source":"# 2ème exemple :\n\nimport turtle as tt # import du module turtle\n\n\ncouleurs = [\"red\", \"blue\", \"yellow\", \"brown\", \"black\", \"purple\", \"green\"]\n\ntt.speed(10)\n\nfor i in range(7):\n tt.penup()\n tt.setposition(-200+50*i, 0)\n tt.pendown()\n tt.pencolor(couleurs[i])\n for j in range(4):\n tt.forward(30)\n tt.left(90)\n \ntt.done()","execution_count":4,"outputs":[{"output_type":"display_data","data":{"image/svg+xml":"<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"640\" height=\"480\" preserveaspectratio=\"xMidYMid meet\" viewbox=\"0 0 640 480\"><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_0\" attributename=\"opacity\" attributetype=\"CSS\" from=\"1\" to=\"1\" begin=\"0s\" dur=\"1ms\" fill=\"freeze\"></animate><g transform=\"translate(320 240)\"></g><g transform=\"translate(320 240)\"><line x1=\"0\" y1=\"0\" x2=\"0\" y2=\"0\" style=\"stroke: black;stroke-width: 1\"><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_2\" attributename=\"x2\" attributetype=\"XML\" from=\"0\" to=\"0\" dur=\"1ms\" fill=\"freeze\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_1.end\"></animate><animate attributename=\"y2\" attributetype=\"XML\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_1.end\" from=\"0\" to=\"0\" dur=\"1ms\" fill=\"freeze\"></animate></line><line x1=\"0\" y1=\"0\" x2=\"0\" y2=\"0\" style=\"stroke: black;stroke-width: 1\" opacity=\"0\"><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_5\" attributename=\"x2\" attributetype=\"XML\" from=\"0\" to=\"-200\" dur=\" 0.252s\" fill=\"freeze\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_4.end\"></animate></line><line x1=\"-200\" y1=\"0\" x2=\"-200\" y2=\"0\" style=\"stroke: red;stroke-width: 1\"><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_7\" attributename=\"x2\" attributetype=\"XML\" from=\"-200\" to=\"-170\" dur=\" 0.038s\" fill=\"freeze\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_6.end\"></animate><animate attributename=\"y2\" attributetype=\"XML\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_6.end\" from=\"0\" to=\"0\" dur=\" 0.038s\" fill=\"freeze\"></animate></line><line x1=\"-170\" y1=\"0\" x2=\"-170\" y2=\"0\" style=\"stroke: red;stroke-width: 1\"><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_9\" attributename=\"x2\" attributetype=\"XML\" from=\"-170\" to=\"-170\" dur=\" 0.038s\" fill=\"freeze\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_8.end\"></animate><animate attributename=\"y2\" attributetype=\"XML\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_8.end\" from=\"0\" to=\"-30\" dur=\" 0.038s\" fill=\"freeze\"></animate></line><line x1=\"-170\" y1=\"-30\" x2=\"-170\" y2=\"-30\" style=\"stroke: red;stroke-width: 1\"><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_11\" attributename=\"x2\" attributetype=\"XML\" from=\"-170\" to=\"-200\" dur=\" 0.038s\" fill=\"freeze\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_10.end\"></animate><animate attributename=\"y2\" attributetype=\"XML\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_10.end\" from=\"-30\" to=\"-30.000000000000004\" dur=\" 0.038s\" fill=\"freeze\"></animate></line><line x1=\"-200\" y1=\"-30.000000000000004\" x2=\"-200\" y2=\"-30.000000000000004\" style=\"stroke: red;stroke-width: 1\"><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_13\" attributename=\"x2\" attributetype=\"XML\" from=\"-200\" to=\"-200\" dur=\" 0.038s\" fill=\"freeze\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_12.end\"></animate><animate attributename=\"y2\" attributetype=\"XML\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_12.end\" from=\"-30.000000000000004\" to=\"-3.552713678800501e-15\" dur=\" 0.038s\" fill=\"freeze\"></animate></line><line x1=\"-200\" y1=\"-3.552713678800501e-15\" x2=\"-200\" y2=\"-3.552713678800501e-15\" style=\"stroke: red;stroke-width: 1\" opacity=\"0\"><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_15\" attributename=\"x2\" attributetype=\"XML\" from=\"-200\" to=\"-150\" dur=\" 0.063s\" fill=\"freeze\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_14.end\"></animate></line><line x1=\"-150\" y1=\"0\" x2=\"-150\" y2=\"0\" style=\"stroke: blue;stroke-width: 1\"><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_17\" attributename=\"x2\" attributetype=\"XML\" from=\"-150\" to=\"-120\" dur=\" 0.038s\" fill=\"freeze\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_16.end\"></animate><animate attributename=\"y2\" attributetype=\"XML\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_16.end\" from=\"0\" to=\"7.34788079488412e-15\" dur=\" 0.038s\" fill=\"freeze\"></animate></line><line x1=\"-120\" y1=\"7.34788079488412e-15\" x2=\"-120\" y2=\"7.34788079488412e-15\" style=\"stroke: blue;stroke-width: 1\"><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_19\" attributename=\"x2\" attributetype=\"XML\" from=\"-120\" to=\"-119.99999999999999\" dur=\" 0.038s\" fill=\"freeze\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_18.end\"></animate><animate attributename=\"y2\" attributetype=\"XML\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_18.end\" from=\"7.34788079488412e-15\" to=\"-29.999999999999993\" dur=\" 0.038s\" fill=\"freeze\"></animate></line><line x1=\"-119.99999999999999\" y1=\"-29.999999999999993\" x2=\"-119.99999999999999\" y2=\"-29.999999999999993\" style=\"stroke: blue;stroke-width: 1\"><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_21\" attributename=\"x2\" attributetype=\"XML\" from=\"-119.99999999999999\" to=\"-150\" dur=\" 0.038s\" fill=\"freeze\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_20.end\"></animate><animate attributename=\"y2\" attributetype=\"XML\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_20.end\" from=\"-29.999999999999993\" to=\"-30.000000000000004\" dur=\" 0.038s\" fill=\"freeze\"></animate></line><line x1=\"-150\" y1=\"-30.000000000000004\" x2=\"-150\" y2=\"-30.000000000000004\" style=\"stroke: blue;stroke-width: 1\"><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_23\" attributename=\"x2\" attributetype=\"XML\" from=\"-150\" to=\"-150\" dur=\" 0.038s\" fill=\"freeze\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_22.end\"></animate><animate attributename=\"y2\" attributetype=\"XML\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_22.end\" from=\"-30.000000000000004\" to=\"-3.552713678800501e-15\" dur=\" 0.038s\" fill=\"freeze\"></animate></line><line x1=\"-150\" y1=\"-3.552713678800501e-15\" x2=\"-150\" y2=\"-3.552713678800501e-15\" style=\"stroke: blue;stroke-width: 1\" opacity=\"0\"><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_25\" attributename=\"x2\" attributetype=\"XML\" from=\"-150\" to=\"-100\" dur=\" 0.063s\" fill=\"freeze\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_24.end\"></animate></line><line x1=\"-100\" y1=\"0\" x2=\"-100\" y2=\"0\" style=\"stroke: yellow;stroke-width: 1\"><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_27\" attributename=\"x2\" attributetype=\"XML\" from=\"-100\" to=\"-70\" dur=\" 0.038s\" fill=\"freeze\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_26.end\"></animate><animate attributename=\"y2\" attributetype=\"XML\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_26.end\" from=\"0\" to=\"1.469576158976824e-14\" dur=\" 0.038s\" fill=\"freeze\"></animate></line><line x1=\"-70\" y1=\"1.469576158976824e-14\" x2=\"-70\" y2=\"1.469576158976824e-14\" style=\"stroke: yellow;stroke-width: 1\"><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_29\" attributename=\"x2\" attributetype=\"XML\" from=\"-70\" to=\"-69.99999999999999\" dur=\" 0.038s\" fill=\"freeze\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_28.end\"></animate><animate attributename=\"y2\" attributetype=\"XML\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_28.end\" from=\"1.469576158976824e-14\" to=\"-29.999999999999986\" dur=\" 0.038s\" fill=\"freeze\"></animate></line><line x1=\"-69.99999999999999\" y1=\"-29.999999999999986\" x2=\"-69.99999999999999\" y2=\"-29.999999999999986\" style=\"stroke: yellow;stroke-width: 1\"><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_31\" attributename=\"x2\" attributetype=\"XML\" from=\"-69.99999999999999\" to=\"-99.99999999999999\" dur=\" 0.038s\" fill=\"freeze\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_30.end\"></animate><animate attributename=\"y2\" attributetype=\"XML\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_30.end\" from=\"-29.999999999999986\" to=\"-30.000000000000004\" dur=\" 0.038s\" fill=\"freeze\"></animate></line><line x1=\"-99.99999999999999\" y1=\"-30.000000000000004\" x2=\"-99.99999999999999\" y2=\"-30.000000000000004\" style=\"stroke: yellow;stroke-width: 1\"><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_33\" attributename=\"x2\" attributetype=\"XML\" from=\"-99.99999999999999\" to=\"-99.99999999999996\" dur=\" 0.038s\" fill=\"freeze\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_32.end\"></animate><animate attributename=\"y2\" attributetype=\"XML\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_32.end\" from=\"-30.000000000000004\" to=\"-3.552713678800501e-15\" dur=\" 0.038s\" fill=\"freeze\"></animate></line><line x1=\"-99.99999999999996\" y1=\"-3.552713678800501e-15\" x2=\"-99.99999999999996\" y2=\"-3.552713678800501e-15\" style=\"stroke: yellow;stroke-width: 1\" opacity=\"0\"><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_35\" attributename=\"x2\" attributetype=\"XML\" from=\"-99.99999999999996\" to=\"-50\" dur=\" 0.063s\" fill=\"freeze\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_34.end\"></animate></line><line x1=\"-50\" y1=\"0\" x2=\"-50\" y2=\"0\" style=\"stroke: brown;stroke-width: 1\"><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_37\" attributename=\"x2\" attributetype=\"XML\" from=\"-50\" to=\"-20\" dur=\" 0.038s\" fill=\"freeze\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_36.end\"></animate><animate attributename=\"y2\" attributetype=\"XML\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_36.end\" from=\"0\" to=\"2.2043642384652355e-14\" dur=\" 0.038s\" fill=\"freeze\"></animate></line><line x1=\"-20\" y1=\"2.2043642384652355e-14\" x2=\"-20\" y2=\"2.2043642384652355e-14\" style=\"stroke: brown;stroke-width: 1\"><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_39\" attributename=\"x2\" attributetype=\"XML\" from=\"-20\" to=\"-20.00000000000003\" dur=\" 0.038s\" fill=\"freeze\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_38.end\"></animate><animate attributename=\"y2\" attributetype=\"XML\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_38.end\" from=\"2.2043642384652355e-14\" to=\"-29.99999999999998\" dur=\" 0.038s\" fill=\"freeze\"></animate></line><line x1=\"-20.00000000000003\" y1=\"-29.99999999999998\" x2=\"-20.00000000000003\" y2=\"-29.99999999999998\" style=\"stroke: brown;stroke-width: 1\"><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_41\" attributename=\"x2\" attributetype=\"XML\" from=\"-20.00000000000003\" to=\"-50.00000000000003\" dur=\" 0.038s\" fill=\"freeze\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_40.end\"></animate><animate attributename=\"y2\" attributetype=\"XML\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_40.end\" from=\"-29.99999999999998\" to=\"-30.000000000000004\" dur=\" 0.038s\" fill=\"freeze\"></animate></line><line x1=\"-50.00000000000003\" y1=\"-30.000000000000004\" x2=\"-50.00000000000003\" y2=\"-30.000000000000004\" style=\"stroke: brown;stroke-width: 1\"><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_43\" attributename=\"x2\" attributetype=\"XML\" from=\"-50.00000000000003\" to=\"-50\" dur=\" 0.038s\" fill=\"freeze\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_42.end\"></animate><animate attributename=\"y2\" attributetype=\"XML\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_42.end\" from=\"-30.000000000000004\" to=\"-3.552713678800501e-15\" dur=\" 0.038s\" fill=\"freeze\"></animate></line><line x1=\"-50\" y1=\"-3.552713678800501e-15\" x2=\"-50\" y2=\"-3.552713678800501e-15\" style=\"stroke: brown;stroke-width: 1\" opacity=\"0\"><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_45\" attributename=\"x2\" attributetype=\"XML\" from=\"-50\" to=\"0\" dur=\" 0.063s\" fill=\"freeze\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_44.end\"></animate></line><line x1=\"0\" y1=\"0\" x2=\"0\" y2=\"0\" style=\"stroke: black;stroke-width: 1\"><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_47\" attributename=\"x2\" attributetype=\"XML\" from=\"0\" to=\"30\" dur=\" 0.038s\" fill=\"freeze\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_46.end\"></animate><animate attributename=\"y2\" attributetype=\"XML\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_46.end\" from=\"0\" to=\"2.939152317953648e-14\" dur=\" 0.038s\" fill=\"freeze\"></animate></line><line x1=\"30\" y1=\"2.939152317953648e-14\" x2=\"30\" y2=\"2.939152317953648e-14\" style=\"stroke: black;stroke-width: 1\"><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_49\" attributename=\"x2\" attributetype=\"XML\" from=\"30\" to=\"29.99999999999998\" dur=\" 0.038s\" fill=\"freeze\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_48.end\"></animate><animate attributename=\"y2\" attributetype=\"XML\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_48.end\" from=\"2.939152317953648e-14\" to=\"-29.99999999999997\" dur=\" 0.038s\" fill=\"freeze\"></animate></line><line x1=\"29.99999999999998\" y1=\"-29.99999999999997\" x2=\"29.99999999999998\" y2=\"-29.99999999999997\" style=\"stroke: black;stroke-width: 1\"><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_51\" attributename=\"x2\" attributetype=\"XML\" from=\"29.99999999999998\" to=\"-2.1316282072803006e-14\" dur=\" 0.038s\" fill=\"freeze\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_50.end\"></animate><animate attributename=\"y2\" attributetype=\"XML\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_50.end\" from=\"-29.99999999999997\" to=\"-30.000000000000004\" dur=\" 0.038s\" fill=\"freeze\"></animate></line><line x1=\"-2.1316282072803006e-14\" y1=\"-30.000000000000004\" x2=\"-2.1316282072803006e-14\" y2=\"-30.000000000000004\" style=\"stroke: black;stroke-width: 1\"><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_53\" attributename=\"x2\" attributetype=\"XML\" from=\"-2.1316282072803006e-14\" to=\"-2.928010666495056e-15\" dur=\" 0.038s\" fill=\"freeze\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_52.end\"></animate><animate attributename=\"y2\" attributetype=\"XML\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_52.end\" from=\"-30.000000000000004\" to=\"-3.552713678800501e-15\" dur=\" 0.038s\" fill=\"freeze\"></animate></line><line x1=\"-2.928010666495056e-15\" y1=\"-3.552713678800501e-15\" x2=\"-2.928010666495056e-15\" y2=\"-3.552713678800501e-15\" style=\"stroke: black;stroke-width: 1\" opacity=\"0\"><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_55\" attributename=\"x2\" attributetype=\"XML\" from=\"-2.928010666495056e-15\" to=\"50\" dur=\" 0.063s\" fill=\"freeze\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_54.end\"></animate></line><line x1=\"50\" y1=\"0\" x2=\"50\" y2=\"0\" style=\"stroke: purple;stroke-width: 1\"><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_57\" attributename=\"x2\" attributetype=\"XML\" from=\"50\" to=\"80\" dur=\" 0.038s\" fill=\"freeze\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_56.end\"></animate><animate attributename=\"y2\" attributetype=\"XML\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_56.end\" from=\"0\" to=\"3.6739403974420595e-14\" dur=\" 0.038s\" fill=\"freeze\"></animate></line><line x1=\"80\" y1=\"3.6739403974420595e-14\" x2=\"80\" y2=\"3.6739403974420595e-14\" style=\"stroke: purple;stroke-width: 1\"><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_59\" attributename=\"x2\" attributetype=\"XML\" from=\"80\" to=\"79.99999999999999\" dur=\" 0.038s\" fill=\"freeze\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_58.end\"></animate><animate attributename=\"y2\" attributetype=\"XML\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_58.end\" from=\"3.6739403974420595e-14\" to=\"-29.999999999999964\" dur=\" 0.038s\" fill=\"freeze\"></animate></line><line x1=\"79.99999999999999\" y1=\"-29.999999999999964\" x2=\"79.99999999999999\" y2=\"-29.999999999999964\" style=\"stroke: purple;stroke-width: 1\"><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_61\" attributename=\"x2\" attributetype=\"XML\" from=\"79.99999999999999\" to=\"49.999999999999986\" dur=\" 0.038s\" fill=\"freeze\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_60.end\"></animate><animate attributename=\"y2\" attributetype=\"XML\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_60.end\" from=\"-29.999999999999964\" to=\"-29.999999999999897\" dur=\" 0.038s\" fill=\"freeze\"></animate></line><line x1=\"49.999999999999986\" y1=\"-29.999999999999897\" x2=\"49.999999999999986\" y2=\"-29.999999999999897\" style=\"stroke: purple;stroke-width: 1\"><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_63\" attributename=\"x2\" attributetype=\"XML\" from=\"49.999999999999986\" to=\"49.99999999999989\" dur=\" 0.038s\" fill=\"freeze\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_62.end\"></animate><animate attributename=\"y2\" attributetype=\"XML\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_62.end\" from=\"-29.999999999999897\" to=\"1.0302869668521453e-13\" dur=\" 0.038s\" fill=\"freeze\"></animate></line><line x1=\"49.99999999999989\" y1=\"1.0302869668521453e-13\" x2=\"49.99999999999989\" y2=\"1.0302869668521453e-13\" style=\"stroke: purple;stroke-width: 1\" opacity=\"0\"><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_65\" attributename=\"x2\" attributetype=\"XML\" from=\"49.99999999999989\" to=\"100\" dur=\" 0.063s\" fill=\"freeze\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_64.end\"></animate></line><line x1=\"100\" y1=\"0\" x2=\"100\" y2=\"0\" style=\"stroke: green;stroke-width: 1\"><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_67\" attributename=\"x2\" attributetype=\"XML\" from=\"100\" to=\"130\" dur=\" 0.038s\" fill=\"freeze\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_66.end\"></animate><animate attributename=\"y2\" attributetype=\"XML\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_66.end\" from=\"0\" to=\"4.408728476930471e-14\" dur=\" 0.038s\" fill=\"freeze\"></animate></line><line x1=\"130\" y1=\"4.408728476930471e-14\" x2=\"130\" y2=\"4.408728476930471e-14\" style=\"stroke: green;stroke-width: 1\"><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_69\" attributename=\"x2\" attributetype=\"XML\" from=\"130\" to=\"130\" dur=\" 0.038s\" fill=\"freeze\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_68.end\"></animate><animate attributename=\"y2\" attributetype=\"XML\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_68.end\" from=\"4.408728476930471e-14\" to=\"-29.999999999999957\" dur=\" 0.038s\" fill=\"freeze\"></animate></line><line x1=\"130\" y1=\"-29.999999999999957\" x2=\"130\" y2=\"-29.999999999999957\" style=\"stroke: green;stroke-width: 1\"><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_71\" attributename=\"x2\" attributetype=\"XML\" from=\"130\" to=\"100\" dur=\" 0.038s\" fill=\"freeze\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_70.end\"></animate><animate attributename=\"y2\" attributetype=\"XML\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_70.end\" from=\"-29.999999999999957\" to=\"-29.999999999999897\" dur=\" 0.038s\" fill=\"freeze\"></animate></line><line x1=\"100\" y1=\"-29.999999999999897\" x2=\"100\" y2=\"-29.999999999999897\" style=\"stroke: green;stroke-width: 1\"><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_73\" attributename=\"x2\" attributetype=\"XML\" from=\"100\" to=\"99.9999999999999\" dur=\" 0.038s\" fill=\"freeze\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_72.end\"></animate><animate attributename=\"y2\" attributetype=\"XML\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_72.end\" from=\"-29.999999999999897\" to=\"1.0302869668521453e-13\" dur=\" 0.038s\" fill=\"freeze\"></animate></line></g><g transform=\"translate(320 240)\"></g><g transform=\"translate(320 240)\"><polygon points=\"0,16 -2,14 -1,10 -4,7 -7,9 -9,8 -6,5 -7,1 -5,-3 -8,-6 -6,-8 -4,-5 0,-7 4,-5 6,-8 8,-6 5,-3 7,1 6,5 9,8 7,9 4,7 1,10 2,14\" stroke=\"black\" fill=\"black\" stroke-width=\"1\" opacity=\"0\"><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_1\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_0.end\" dur=\"1ms\" fill=\"freeze\" attributename=\"opacity\" attributetype=\"XML\" from=\"0\" to=\"1\"></animate><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_2.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateTransform attributename=\"transform\" id=\"af_f90a583c18a44726b835a12e24bb9bdd_3\" type=\"rotate\" from=\"0,0,0\" to=\"0.0,0,0\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_2.end\" dur=\"1ms\" fill=\"freeze\"></animateTransform><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_3.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateTransform attributename=\"transform\" id=\"af_f90a583c18a44726b835a12e24bb9bdd_4\" type=\"rotate\" from=\"-90.0,0,0\" to=\"-90.0,0,0\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_3.end\" dur=\"1ms\" fill=\"freeze\"></animateTransform><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_4.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"0.0,-0.0\" to=\"-200,0\" dur=\" 0.252s\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_4.end\" fill=\"freeze\"></animateMotion><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_6\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_5.end\" dur=\"1ms\" fill=\"freeze\" attributename=\"stroke\" attributetype=\"XML\" from=\"black\" to=\"red\"></animate><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_6.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"-200,0\" to=\"-170.0,-0.0\" dur=\" 0.038s\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_6.end\" fill=\"freeze\"></animateMotion><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_7.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateTransform attributename=\"transform\" id=\"af_f90a583c18a44726b835a12e24bb9bdd_8\" type=\"rotate\" from=\"-90.0,0,0\" to=\"-180.0,0,0\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_7.end\" dur=\" 0.025s\" fill=\"freeze\"></animateTransform><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_8.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"-170.0,-0.0\" to=\"-170.0,-30.0\" dur=\" 0.038s\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_8.end\" fill=\"freeze\"></animateMotion><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_9.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateTransform attributename=\"transform\" id=\"af_f90a583c18a44726b835a12e24bb9bdd_10\" type=\"rotate\" from=\"-180.0,0,0\" to=\"-270.0,0,0\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_9.end\" dur=\" 0.025s\" fill=\"freeze\"></animateTransform><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_10.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"-170.0,-30.0\" to=\"-200.0,-30.000000000000004\" dur=\" 0.038s\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_10.end\" fill=\"freeze\"></animateMotion><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_11.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateTransform attributename=\"transform\" id=\"af_f90a583c18a44726b835a12e24bb9bdd_12\" type=\"rotate\" from=\"-270.0,0,0\" to=\"-360.0,0,0\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_11.end\" dur=\" 0.025s\" fill=\"freeze\"></animateTransform><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_12.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"-200.0,-30.000000000000004\" to=\"-200.0,-3.552713678800501e-15\" dur=\" 0.038s\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_12.end\" fill=\"freeze\"></animateMotion><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_13.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateTransform attributename=\"transform\" id=\"af_f90a583c18a44726b835a12e24bb9bdd_14\" type=\"rotate\" from=\"-360.0,0,0\" to=\"-450.0,0,0\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_13.end\" dur=\" 0.025s\" fill=\"freeze\"></animateTransform><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_14.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"-200.0,-3.552713678800501e-15\" to=\"-150,0\" dur=\" 0.063s\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_14.end\" fill=\"freeze\"></animateMotion><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_16\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_15.end\" dur=\"1ms\" fill=\"freeze\" attributename=\"stroke\" attributetype=\"XML\" from=\"red\" to=\"blue\"></animate><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_16.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"-150,0\" to=\"-120.0,7.34788079488412e-15\" dur=\" 0.038s\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_16.end\" fill=\"freeze\"></animateMotion><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_17.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateTransform attributename=\"transform\" id=\"af_f90a583c18a44726b835a12e24bb9bdd_18\" type=\"rotate\" from=\"-450.0,0,0\" to=\"-540.0,0,0\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_17.end\" dur=\" 0.025s\" fill=\"freeze\"></animateTransform><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_18.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"-120.0,7.34788079488412e-15\" to=\"-119.99999999999999,-29.999999999999993\" dur=\" 0.038s\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_18.end\" fill=\"freeze\"></animateMotion><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_19.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateTransform attributename=\"transform\" id=\"af_f90a583c18a44726b835a12e24bb9bdd_20\" type=\"rotate\" from=\"-540.0,0,0\" to=\"-630.0,0,0\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_19.end\" dur=\" 0.025s\" fill=\"freeze\"></animateTransform><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_20.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"-119.99999999999999,-29.999999999999993\" to=\"-150.0,-30.000000000000004\" dur=\" 0.038s\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_20.end\" fill=\"freeze\"></animateMotion><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_21.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateTransform attributename=\"transform\" id=\"af_f90a583c18a44726b835a12e24bb9bdd_22\" type=\"rotate\" from=\"-630.0,0,0\" to=\"-720.0,0,0\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_21.end\" dur=\" 0.025s\" fill=\"freeze\"></animateTransform><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_22.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"-150.0,-30.000000000000004\" to=\"-150.0,-3.552713678800501e-15\" dur=\" 0.038s\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_22.end\" fill=\"freeze\"></animateMotion><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_23.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateTransform attributename=\"transform\" id=\"af_f90a583c18a44726b835a12e24bb9bdd_24\" type=\"rotate\" from=\"-720.0,0,0\" to=\"-810.0,0,0\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_23.end\" dur=\" 0.025s\" fill=\"freeze\"></animateTransform><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_24.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"-150.0,-3.552713678800501e-15\" to=\"-100,0\" dur=\" 0.063s\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_24.end\" fill=\"freeze\"></animateMotion><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_26\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_25.end\" dur=\"1ms\" fill=\"freeze\" attributename=\"stroke\" attributetype=\"XML\" from=\"blue\" to=\"yellow\"></animate><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_26.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"-100,0\" to=\"-70.0,1.469576158976824e-14\" dur=\" 0.038s\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_26.end\" fill=\"freeze\"></animateMotion><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_27.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateTransform attributename=\"transform\" id=\"af_f90a583c18a44726b835a12e24bb9bdd_28\" type=\"rotate\" from=\"-810.0,0,0\" to=\"-900.0,0,0\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_27.end\" dur=\" 0.025s\" fill=\"freeze\"></animateTransform><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_28.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"-70.0,1.469576158976824e-14\" to=\"-69.99999999999999,-29.999999999999986\" dur=\" 0.038s\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_28.end\" fill=\"freeze\"></animateMotion><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_29.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateTransform attributename=\"transform\" id=\"af_f90a583c18a44726b835a12e24bb9bdd_30\" type=\"rotate\" from=\"-900.0,0,0\" to=\"-990.0,0,0\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_29.end\" dur=\" 0.025s\" fill=\"freeze\"></animateTransform><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_30.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"-69.99999999999999,-29.999999999999986\" to=\"-99.99999999999999,-30.000000000000004\" dur=\" 0.038s\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_30.end\" fill=\"freeze\"></animateMotion><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_31.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateTransform attributename=\"transform\" id=\"af_f90a583c18a44726b835a12e24bb9bdd_32\" type=\"rotate\" from=\"-990.0,0,0\" to=\"-1080.0,0,0\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_31.end\" dur=\" 0.025s\" fill=\"freeze\"></animateTransform><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_32.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"-99.99999999999999,-30.000000000000004\" to=\"-99.99999999999996,-3.552713678800501e-15\" dur=\" 0.038s\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_32.end\" fill=\"freeze\"></animateMotion><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_33.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateTransform attributename=\"transform\" id=\"af_f90a583c18a44726b835a12e24bb9bdd_34\" type=\"rotate\" from=\"-1080.0,0,0\" to=\"-1170.0,0,0\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_33.end\" dur=\" 0.025s\" fill=\"freeze\"></animateTransform><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_34.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"-99.99999999999996,-3.552713678800501e-15\" to=\"-50,0\" dur=\" 0.063s\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_34.end\" fill=\"freeze\"></animateMotion><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_36\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_35.end\" dur=\"1ms\" fill=\"freeze\" attributename=\"stroke\" attributetype=\"XML\" from=\"yellow\" to=\"brown\"></animate><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_36.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"-50,0\" to=\"-20.0,2.2043642384652355e-14\" dur=\" 0.038s\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_36.end\" fill=\"freeze\"></animateMotion><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_37.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateTransform attributename=\"transform\" id=\"af_f90a583c18a44726b835a12e24bb9bdd_38\" type=\"rotate\" from=\"-1170.0,0,0\" to=\"-1260.0,0,0\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_37.end\" dur=\" 0.025s\" fill=\"freeze\"></animateTransform><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_38.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"-20.0,2.2043642384652355e-14\" to=\"-20.00000000000003,-29.99999999999998\" dur=\" 0.038s\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_38.end\" fill=\"freeze\"></animateMotion><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_39.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateTransform attributename=\"transform\" id=\"af_f90a583c18a44726b835a12e24bb9bdd_40\" type=\"rotate\" from=\"-1260.0,0,0\" to=\"-1350.0,0,0\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_39.end\" dur=\" 0.025s\" fill=\"freeze\"></animateTransform><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_40.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"-20.00000000000003,-29.99999999999998\" to=\"-50.00000000000003,-30.000000000000004\" dur=\" 0.038s\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_40.end\" fill=\"freeze\"></animateMotion><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_41.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateTransform attributename=\"transform\" id=\"af_f90a583c18a44726b835a12e24bb9bdd_42\" type=\"rotate\" from=\"-1350.0,0,0\" to=\"-1440.0,0,0\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_41.end\" dur=\" 0.025s\" fill=\"freeze\"></animateTransform><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_42.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"-50.00000000000003,-30.000000000000004\" to=\"-50.0,-3.552713678800501e-15\" dur=\" 0.038s\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_42.end\" fill=\"freeze\"></animateMotion><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_43.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateTransform attributename=\"transform\" id=\"af_f90a583c18a44726b835a12e24bb9bdd_44\" type=\"rotate\" from=\"-1440.0,0,0\" to=\"-1530.0,0,0\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_43.end\" dur=\" 0.025s\" fill=\"freeze\"></animateTransform><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_44.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"-50.0,-3.552713678800501e-15\" to=\"0,0\" dur=\" 0.063s\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_44.end\" fill=\"freeze\"></animateMotion><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_46\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_45.end\" dur=\"1ms\" fill=\"freeze\" attributename=\"stroke\" attributetype=\"XML\" from=\"brown\" to=\"black\"></animate><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_46.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"0,0\" to=\"30.0,2.939152317953648e-14\" dur=\" 0.038s\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_46.end\" fill=\"freeze\"></animateMotion><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_47.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateTransform attributename=\"transform\" id=\"af_f90a583c18a44726b835a12e24bb9bdd_48\" type=\"rotate\" from=\"-1530.0,0,0\" to=\"-1620.0,0,0\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_47.end\" dur=\" 0.025s\" fill=\"freeze\"></animateTransform><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_48.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"30.0,2.939152317953648e-14\" to=\"29.99999999999998,-29.99999999999997\" dur=\" 0.038s\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_48.end\" fill=\"freeze\"></animateMotion><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_49.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateTransform attributename=\"transform\" id=\"af_f90a583c18a44726b835a12e24bb9bdd_50\" type=\"rotate\" from=\"-1620.0,0,0\" to=\"-1710.0,0,0\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_49.end\" dur=\" 0.025s\" fill=\"freeze\"></animateTransform><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_50.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"29.99999999999998,-29.99999999999997\" to=\"-2.1316282072803006e-14,-30.000000000000004\" dur=\" 0.038s\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_50.end\" fill=\"freeze\"></animateMotion><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_51.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateTransform attributename=\"transform\" id=\"af_f90a583c18a44726b835a12e24bb9bdd_52\" type=\"rotate\" from=\"-1710.0,0,0\" to=\"-1800.0,0,0\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_51.end\" dur=\" 0.025s\" fill=\"freeze\"></animateTransform><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_52.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"-2.1316282072803006e-14,-30.000000000000004\" to=\"-2.928010666495056e-15,-3.552713678800501e-15\" dur=\" 0.038s\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_52.end\" fill=\"freeze\"></animateMotion><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_53.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateTransform attributename=\"transform\" id=\"af_f90a583c18a44726b835a12e24bb9bdd_54\" type=\"rotate\" from=\"-1800.0,0,0\" to=\"-1890.0,0,0\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_53.end\" dur=\" 0.025s\" fill=\"freeze\"></animateTransform><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_54.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"-2.928010666495056e-15,-3.552713678800501e-15\" to=\"50,0\" dur=\" 0.063s\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_54.end\" fill=\"freeze\"></animateMotion><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_56\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_55.end\" dur=\"1ms\" fill=\"freeze\" attributename=\"stroke\" attributetype=\"XML\" from=\"black\" to=\"purple\"></animate><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_56.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"50,0\" to=\"80.0,3.6739403974420595e-14\" dur=\" 0.038s\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_56.end\" fill=\"freeze\"></animateMotion><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_57.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateTransform attributename=\"transform\" id=\"af_f90a583c18a44726b835a12e24bb9bdd_58\" type=\"rotate\" from=\"-1890.0,0,0\" to=\"-1980.0,0,0\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_57.end\" dur=\" 0.025s\" fill=\"freeze\"></animateTransform><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_58.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"80.0,3.6739403974420595e-14\" to=\"79.99999999999999,-29.999999999999964\" dur=\" 0.038s\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_58.end\" fill=\"freeze\"></animateMotion><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_59.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateTransform attributename=\"transform\" id=\"af_f90a583c18a44726b835a12e24bb9bdd_60\" type=\"rotate\" from=\"-1980.0,0,0\" to=\"-2070.0,0,0\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_59.end\" dur=\" 0.025s\" fill=\"freeze\"></animateTransform><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_60.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"79.99999999999999,-29.999999999999964\" to=\"49.999999999999986,-29.999999999999897\" dur=\" 0.038s\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_60.end\" fill=\"freeze\"></animateMotion><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_61.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateTransform attributename=\"transform\" id=\"af_f90a583c18a44726b835a12e24bb9bdd_62\" type=\"rotate\" from=\"-2070.0,0,0\" to=\"-2160.0,0,0\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_61.end\" dur=\" 0.025s\" fill=\"freeze\"></animateTransform><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_62.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"49.999999999999986,-29.999999999999897\" to=\"49.99999999999989,1.0302869668521453e-13\" dur=\" 0.038s\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_62.end\" fill=\"freeze\"></animateMotion><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_63.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateTransform attributename=\"transform\" id=\"af_f90a583c18a44726b835a12e24bb9bdd_64\" type=\"rotate\" from=\"-2160.0,0,0\" to=\"-2250.0,0,0\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_63.end\" dur=\" 0.025s\" fill=\"freeze\"></animateTransform><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_64.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"49.99999999999989,1.0302869668521453e-13\" to=\"100,0\" dur=\" 0.063s\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_64.end\" fill=\"freeze\"></animateMotion><animate id=\"af_f90a583c18a44726b835a12e24bb9bdd_66\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_65.end\" dur=\"1ms\" fill=\"freeze\" attributename=\"stroke\" attributetype=\"XML\" from=\"purple\" to=\"green\"></animate><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_66.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"100,0\" to=\"130.0,4.408728476930471e-14\" dur=\" 0.038s\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_66.end\" fill=\"freeze\"></animateMotion><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_67.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateTransform attributename=\"transform\" id=\"af_f90a583c18a44726b835a12e24bb9bdd_68\" type=\"rotate\" from=\"-2250.0,0,0\" to=\"-2340.0,0,0\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_67.end\" dur=\" 0.025s\" fill=\"freeze\"></animateTransform><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_68.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"130.0,4.408728476930471e-14\" to=\"130.0,-29.999999999999957\" dur=\" 0.038s\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_68.end\" fill=\"freeze\"></animateMotion><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_69.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateTransform attributename=\"transform\" id=\"af_f90a583c18a44726b835a12e24bb9bdd_70\" type=\"rotate\" from=\"-2340.0,0,0\" to=\"-2430.0,0,0\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_69.end\" dur=\" 0.025s\" fill=\"freeze\"></animateTransform><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_70.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"130.0,-29.999999999999957\" to=\"100.0,-29.999999999999897\" dur=\" 0.038s\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_70.end\" fill=\"freeze\"></animateMotion><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_71.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateTransform attributename=\"transform\" id=\"af_f90a583c18a44726b835a12e24bb9bdd_72\" type=\"rotate\" from=\"-2430.0,0,0\" to=\"-2520.0,0,0\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_71.end\" dur=\" 0.025s\" fill=\"freeze\"></animateTransform><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_72.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateMotion from=\"100.0,-29.999999999999897\" to=\"99.9999999999999,1.0302869668521453e-13\" dur=\" 0.038s\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_72.end\" fill=\"freeze\"></animateMotion><animateMotion begin=\"af_f90a583c18a44726b835a12e24bb9bdd_73.end\" dur=\"1ms\" fill=\"remove\"></animateMotion><animateTransform attributename=\"transform\" id=\"af_f90a583c18a44726b835a12e24bb9bdd_74\" type=\"rotate\" from=\"-2520.0,0,0\" to=\"-2610.0,0,0\" begin=\"af_f90a583c18a44726b835a12e24bb9bdd_73.end\" dur=\" 0.025s\" fill=\"freeze\"></animateTransform></polygon></g></svg>"},"metadata":{}}]},{"metadata":{},"cell_type":"markdown","source":"**Pour résumer:**\n\n| Fonction |Exemple|Commentaire|\n|:-------- |:------|:----------|\n|forward(x)|forward(150)|Trace un trait de 150 points|\n|backward(x)|backward(150)|Trace un trait “à reculons” de 150 points|\n|left(n)|left(60)|Tourne sur place la tortue de 60° à gauche|\n|right(n)|right(60)|Tourne sur place la tortue de 60° à droite|\n|setposition(x, y) |setposition(-100, 100)|va à la position (-100,100) sachant que l'origine (0;0) est au centre du cadre de dessin (dimensions 600x600)|\n|width(x)|width(5)|Change l’épaisseur à 5 points|\n|color(\"c\")|color(\"yellow\")|Change la couleur du trait (mais aucun trait n’est tracé à ce moment). Notez les guillemets !|\n|penup()|penup()|Lève la tortue (permet de se déplacer sans dessiner)|\n|pendown()|pendown()|Baisse le stylo|\n|home()|home()|retour à l'origine|"},{"metadata":{},"cell_type":"markdown","source":"<h2 class=\"alert alert-info\">3. Fractales : courbe de Koch</h2>\n\nLa courbe de Koch est une fractale reposant sur la construction récursive suviante :\n1. Étape 1 : Tracer un segment de longueur a. \n\n\n\n2. Étape 2 : Diviser le segment en 3 parties de même longueur. Construire un triangle équilatéral ayant pour base le segment médian de la première étape, et en supprimer la base.\n\n\n3. Étape 3 : Reprendre l'étape 2 sur chacun des segments créés.\n\n\n4. Et ainsi de suite...\n\n"},{"metadata":{},"cell_type":"markdown","source":"On peut construire récursivement cette courbe. \n\nLa fonction de tracer prend deux paramètres en entrée :\n* la longeur $a$ du segment.\n* l'étape $n$ de \"profondeur\" de récursivité. \n\nPar exemple, à la profondeur $n=0$, on trace un simple segment : ceci constituera la condition d'arrêt des appels récursifs. À la profondeur $n=1$, le tracé donne la figure de l'étape 2."},{"metadata":{},"cell_type":"markdown","source":"<h3 style=\"color:teal;background-color:azure;\" > <i class=\"fa fa-pencil\" aria-hidden=\"true\"> </i> Exercice 3 : Faire l'étape 2 </h3>\n\n\n1. Écrire une fonction `etape2(a)` qui permet de dessiner avec la tortue (pas de récursivité ici) la figure correspondant à l'étape 2 (décrite ci-avant).\n"},{"metadata":{"trusted":false},"cell_type":"code","source":"import turtle as tt # import du module turtle\ntt.speed(10) # pour dessiner plus rapidement\n\ndef etape2(a):\n # VOTRE CODE CI-DESSOUS\n #...\n \n# test:\na = 50\netape2(a)\n\ntt.done()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"2. En vous inspirant de la logique du code de la fonction précédente (en la \"rendant récursive\"), écrire une fonction koch(a, n) récursive qui :\n\n - prend comme paramètres un nombre entier a représentant la longueur du segment et un entier n égal au nombre de récursions souhaité.\n - construit la courbe de Koch en divisant récursivement chacun des segments\n\n *Rappel* : si n=0, le tracé est un simplement segment de longueur a."},{"metadata":{"trusted":false},"cell_type":"code","source":"import turtle as tt # import du module turtle\n\ntt.speed(10)\ntt.penup()\ntt.setposition(-300, 0) \ntt.pendown()\n\ndef koch(a, n):\n # VOTRE CODE CI-DESSOUS\n #...\n\nkoch(360, 3)\n\ntt.done()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<h2 class=\"alert alert-info\">Et pour s'amuser encore un peu...</h2>\nExécuter le code ci-dessous :"},{"metadata":{"trusted":false},"cell_type":"code","source":"a = 180\n\ntt.speed(10)\ntt.penup()\ntt.setposition(-a/2, a/3) \ntt.pendown()\n\ndef koch(a, n):\n if n == 0:\n tt.forward(a)\n else:\n koch(a/3, n-1)\n tt.left(60)\n koch(a/3, n-1)\n tt.right(120)\n koch(a/3, n-1)\n tt.left(60)\n koch(a/3, n-1)\n\ndef flocon(a, n):\n for i in range(3):\n koch(a, n)\n tt.right(120)\n \nflocon(a, 3)\n\ntt.penup()\ntt.home()\n\ntt.done()","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"markdown","source":"---\n\n#### Remarque générale\n\nUne partie de ce notebook reprend le cours sur la récursivité du lycée Faustin Flerettiré http://nsinfo.yo.fr/nsi_term_programmation_recursivite.html. Le notebook est sous license Creative Commons [BY-NC-SA](https://creativecommons.org/licenses/?lang=fr)\n"}],"metadata":{"kernelspec":{"display_name":"Python 3.8.1 64-bit ('python38': conda)","language":"python","name":"python38164bitpython38conda56991d5ad1414e06a4dcd344400cf456"}},"nbformat":4,"nbformat_minor":2} \ No newline at end of file +{"cells":[{"metadata":{},"cell_type":"markdown","source":"<h1 class=\"alert alert-success\">Récursivité </h2>"},{"metadata":{},"cell_type":"markdown","source":"<h2 class=\"alert alert-info\"> 1. Introduction </h2>\n\nLa **récursivité** est un concept qui est très proche de la notion mathématiques de la récurrence. On dit qu’une fonction est récursive si elle s’appelle elle-même.\nPour résoudre un problème ou effectuer un calcul, on se ramène à la résolution d’un problème similaire mais de complexité moindre. On recommence ainsi jusqu’à obtenir un problème élémentaire que l’on sait résoudre. \n\n!!! note Définition\nOn qualifie de **récursive** toute fonction qui s'appelle elle-même.\n!!!\n\nLa plus-part des langages de programmation actuels permettent de mettre en œuvre directement cette réduction du problème, en autorisant une fonction à s’appeler elle-même : on parle alors de fonction récursive. On trouvera souvent deux versions possibles d'un même programme : itérative et récursive.\n\nCependant deux éléments sont indispensables à la terminaison d’une fonction récursive :\n\n- il est nécessaire qu’il y ait une condition d’arrêt ;\n- il ne doit pas y avoir de suite infinie d’appels récursifs.\n\n### Exemple\nOn souhaite calculer la somme $S=\\sum_{i=1}^n i =1 +2+3+\\cdots+(n-1) + n$. Ci-dessous une fonction recursive qui calcule la somme des $n$ premiers termes dont on peut visualiser les appels"},{"metadata":{"trusted":false,"scrolled":true},"cell_type":"code","source":"from rcviz import viz # pour visualiser les appels \n@viz\ndef somme(n):\n if n < 1:\n return 0\n else:\n return n + somme(n - 1)\n\nsomme(4) # calcule 1 + 2 + 3 + 4","execution_count":1,"outputs":[{"output_type":"execute_result","execution_count":1,"data":{"text/plain":"10"},"metadata":{}}]},{"metadata":{},"cell_type":"markdown","source":"Un sous-programme est dit récursif s’il fait appel à lui-même, comme ici.\nDétaillons la procédure compte :\n\n- Pour calculer la somme des `n` termes, on dépcompose le problème comme calculer la somme des `n-1` termes plus `n`;\n- le test `n < 0` est une condition d’arrêt, obligatoire sinon le sous-programme peut boucler indéfiniment;\n- les appels récursifs continuent jusqu’à ce que le paramètre passé à la procédure prenne la valeur 0;\n- la dernière valeur retournée est donc 0.\n\nOn peut visualiser les appels avec :"},{"metadata":{"trusted":false,"scrolled":false},"cell_type":"code","source":"somme.callgraph() # pour visualiser les appels récusifs","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"!!! danger Attention\nOn remarque qu'il est possible d'exécuter cette fonction avec un paramètre qui n'est pas un entier positif. Pour interdire ce cas de figure on peut utiliser l'instruction `assert` :\n!!!\n"},{"metadata":{"trusted":false,"scrolled":true},"cell_type":"code","source":"def somme(n):\n assert n >= 0 and isinstance(n, int), \"n doit être un entier naturel\"\n if n < 1:\n return 0\n else:\n return n + somme(n - 1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":false,"scrolled":true},"cell_type":"code","source":"somme(-2)","execution_count":null,"outputs":[]},{"metadata":{"trusted":false,"scrolled":false},"cell_type":"code","source":"somme(2.8)","execution_count":null,"outputs":[]},{"metadata":{"trusted":false,"scrolled":true},"cell_type":"code","source":"somme(8)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<h3 style=\"color:teal;background-color:azure;\" > <i class=\"fa fa-pencil\" aria-hidden=\"true\"> </i> Exercice 1 : Somme des éléments d'une liste </h3>\n\nEcrire une fonction récursive ```somme_liste``` qui :\n\n- prend en paramètre une liste d'entiers `L`\n- retourne la somme des éléments de la liste `L`\n\n\n**Coup de pouce :** \n\n*Condition d'arrêt* : si la liste contient un seul élément, la somme de ses élément vaut la valeur de cet élément : donc la fonction renvoie ce nombre.\n\n*Récursion* : renvoyer la valeur du 1er élément additionnée de la somme du reste de la liste."},{"metadata":{"trusted":false,"scrolled":true},"cell_type":"code","source":"# VOTRE CODE CI-DESSOUS\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":false,"scrolled":true},"cell_type":"code","source":"# test \ntab = [5, 4, 7, 2]\nsomme_liste(tab) # la fonction doit renvoyer : 18","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<h3 style=\"color:teal;background-color:azure;\" > <i class=\"fa fa-pencil\" aria-hidden=\"true\"> </i> Exercice 2 : Miroir d’une chaîne de caractère </h3>\n\nÉcrire une fonction ```miroir``` récursive qui :\n\n- prend comme paramètre une chaîne de caractères `s`\n- renvoie le « miroir » de la chaîne; par exemple, le miroir de \"abcde\" est \"edcba\".\n\n\n**Coup de pouce :** \n\n*Condition d'arrêt* : si la chaine contient un seul caractère ou aucun, son miroir est elle-même.\n\n*Récursion* : Le principe consiste à permutter le 1er et le dernier carcatère, et à recopier le miroir de la sous-chaine interne (entre le 2ème caractère et l'avant-dernier) au milieu de ces 2 caractères. Il faut donc renvoyer une chaine qui est la concaténation du dernier caratère, du miroir de la sous-chaine interne, et du 1er caractère.\n\n**Aide** : on pourra utiliser la syntaxe `s[1:-1]` qui permet d'extraire une sous-chaine de caractères entre le second élément de l'avant dernier, et `s[0]`, respectivement `s[-1]`, pour accéder au premier, respectivement dernier, élément"},{"metadata":{"trusted":false,"scrolled":true},"cell_type":"code","source":"# VOTRE CODE CI-DESSOUS","execution_count":null,"outputs":[]},{"metadata":{"trusted":false,"scrolled":true},"cell_type":"code","source":"# test\nchaine = 'quelle belle chaine'\nmiroir(chaine) # la fonction doit renvoyer : 'eniahc ellleb elleu'\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<h2 class=\"alert alert-info\">2. Rappels sur Turtle</h2>\n\nTurtle est un module Python permettant de dessiner sur un canevas. Le crayon est dirigé par une tortue !\n\nJupyter propose une implémentation de ce module (très légèrement modifié). Les commandes principales consistent à positionner la tortue, lever ou baisser le crayon (pour écrire ou non lorsque la tortue se déplace) et à commander les mouvements de la tortue (avancer/reculer, tourner à gauche/droite d'un certain angle).\n\nPour mieux comprendre et découvrir les commandes accessibles, étudier l'exemple de démonstration ci-dessous :"},{"metadata":{"trusted":false,"scrolled":true},"cell_type":"code","source":"import turtle as tt # import du module turtle\n\ntt.speed(3) # vitesse moyenne (maxi = 10)\n\ntt.penup() # lève le crayon (pour ne pas écrire pendant le déplacement)\ntt.setposition(-100, 100) \n# origine (0, 0) au centre du cadre de dessin (dimensions 600x600)\ntt.pendown() # abaisse le crayon (pour voir la trace de la tortue)\n\ntt.forward(20) # avance de 20\ntt.left(60) # virage de 60° vers la gauche\ntt.forward(100) \ntt.right(120) # virage de 120° vers la droite\ntt.pencolor(\"red\") # couleurs autorisées \"blue\", \"yellow\", \"brown\", \"black\", \"purple\", \"green\"\ntt.forward(100) \ntt.left(60) \ntt.forward(100) # recule de 100\ntt.backward(70) \ntt.right(90) \ntt.pencolor(\"green\") \ntt.forward(300) \n\ntt.penup()\ntt.home() # retour à l'origine\n\ntt.done() # indispensable pour activer la tortue dans Basthon","execution_count":null,"outputs":[]},{"metadata":{"trusted":false,"scrolled":true},"cell_type":"code","source":"# 2ème exemple :\n\nimport turtle as tt # import du module turtle\n\n\ncouleurs = [\"red\", \"blue\", \"yellow\", \"brown\", \"black\", \"purple\", \"green\"]\n\ntt.speed(10)\n\nfor i in range(7):\n tt.penup()\n tt.setposition(-200+50*i, 0)\n tt.pendown()\n tt.pencolor(couleurs[i])\n for j in range(4):\n tt.forward(30)\n tt.left(90)\n \ntt.done()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Pour résumer:**\n\n| Fonction |Exemple|Commentaire|\n|:-------- |:------|:----------|\n|forward(x)|forward(150)|Trace un trait de 150 points|\n|backward(x)|backward(150)|Trace un trait “à reculons” de 150 points|\n|left(n)|left(60)|Tourne sur place la tortue de 60° à gauche|\n|right(n)|right(60)|Tourne sur place la tortue de 60° à droite|\n|setposition(x, y) |setposition(-100, 100)|va à la position (-100,100) sachant que l'origine (0;0) est au centre du cadre de dessin (dimensions 600x600)|\n|width(x)|width(5)|Change l’épaisseur à 5 points|\n|color(\"c\")|color(\"yellow\")|Change la couleur du trait (mais aucun trait n’est tracé à ce moment). Notez les guillemets !|\n|penup()|penup()|Lève la tortue (permet de se déplacer sans dessiner)|\n|pendown()|pendown()|Baisse le stylo|\n|home()|home()|retour à l'origine|"},{"metadata":{},"cell_type":"markdown","source":"<h2 class=\"alert alert-info\">3. Fractales : courbe de Koch</h2>\n\nLa courbe de Koch est une fractale reposant sur la construction récursive suviante :\n1. Étape 1 : Tracer un segment de longueur a. \n\n\n\n2. Étape 2 : Diviser le segment en 3 parties de même longueur. Construire un triangle équilatéral ayant pour base le segment médian de la première étape, et en supprimer la base.\n\n\n3. Étape 3 : Reprendre l'étape 2 sur chacun des segments créés.\n\n\n4. Et ainsi de suite...\n\n"},{"metadata":{},"cell_type":"markdown","source":"On peut construire récursivement cette courbe. \n\nLa fonction de tracer prend deux paramètres en entrée :\n* la longeur $a$ du segment.\n* l'étape $n$ de \"profondeur\" de récursivité. \n\nPar exemple, à la profondeur $n=0$, on trace un simple segment : ceci constituera la condition d'arrêt des appels récursifs. À la profondeur $n=1$, le tracé donne la figure de l'étape 2."},{"metadata":{},"cell_type":"markdown","source":"<h3 style=\"color:teal;background-color:azure;\" > <i class=\"fa fa-pencil\" aria-hidden=\"true\"> </i> Exercice 3 : Faire l'étape 2 </h3>\n\n\n1. Écrire une fonction `etape2(a)` qui permet de dessiner avec la tortue (pas de récursivité ici) la figure correspondant à l'étape 2 (décrite ci-avant).\n"},{"metadata":{"trusted":false,"scrolled":true},"cell_type":"code","source":"import turtle as tt # import du module turtle\ntt.speed(10) # pour dessiner plus rapidement\n\ndef etape2(a):\n # VOTRE CODE CI-DESSOUS\n #...\n \n# test:\na = 50\netape2(a)\n\ntt.done()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"2. En vous inspirant de la logique du code de la fonction précédente (en la \"rendant récursive\"), écrire une fonction koch(a, n) récursive qui :\n\n - prend comme paramètres un nombre entier a représentant la longueur du segment et un entier n égal au nombre de récursions souhaité.\n - construit la courbe de Koch en divisant récursivement chacun des segments\n\n *Rappel* : si n=0, le tracé est un simplement segment de longueur a."},{"metadata":{"trusted":false,"scrolled":true},"cell_type":"code","source":"import turtle as tt # import du module turtle\n\ntt.speed(10)\ntt.penup()\ntt.setposition(-300, 0) \ntt.pendown()\n\ndef koch(a, n):\n # VOTRE CODE CI-DESSOUS\n #...\n\nkoch(360, 3)\n\ntt.done()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<h2 class=\"alert alert-info\">Et pour s'amuser encore un peu...</h2>\nExécuter le code ci-dessous :"},{"metadata":{"trusted":false,"scrolled":true},"cell_type":"code","source":"a = 180\n\ntt.speed(10)\ntt.penup()\ntt.setposition(-a/2, a/3) \ntt.pendown()\n\ndef flocon(a, n):\n for i in range(3):\n koch(a, n)\n tt.right(120)\n \nflocon(a, 3)\n\ntt.penup()\ntt.home()\n\ntt.done()","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"markdown","source":"---\n\n#### Remarque générale\n\nUne partie de ce notebook reprend le cours sur la récursivité du lycée Faustin Flerettiré http://nsinfo.yo.fr/nsi_term_programmation_recursivite.html. Le notebook est sous license Creative Commons [BY-NC-SA](https://creativecommons.org/licenses/?lang=fr)\n"}],"metadata":{"kernelspec":{"display_name":"Python 3.8.1 64-bit ('python38': conda)","language":"python","name":"python38164bitpython38conda56991d5ad1414e06a4dcd344400cf456"}},"nbformat":4,"nbformat_minor":2} \ No newline at end of file diff --git a/recursivite/recursivite_corrige.ipynb b/recursivite/recursivite_corrige.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..26b02f29f18896a99074ff2a6b39615faf4a1235 --- /dev/null +++ b/recursivite/recursivite_corrige.ipynb @@ -0,0 +1 @@ +{"cells":[{"metadata":{},"cell_type":"markdown","source":"<h1 class=\"alert alert-success\">Récursivité </h2>"},{"metadata":{},"cell_type":"markdown","source":"<h2 class=\"alert alert-info\"> 1. Introduction </h2>\n\nLa **récursivité** est un concept qui est très proche de la notion mathématiques de la récurrence. On dit qu’une fonction est récursive si elle s’appelle elle-même.\nPour résoudre un problème ou effectuer un calcul, on se ramène à la résolution d’un problème similaire mais de complexité moindre. On recommence ainsi jusqu’à obtenir un problème élémentaire que l’on sait résoudre. \n\n!!! note Définition\nOn qualifie de **récursive** toute fonction qui s'appelle elle-même.\n!!!\n\nLa plus-part des langages de programmation actuels permettent de mettre en œuvre directement cette réduction du problème, en autorisant une fonction à s’appeler elle-même : on parle alors de fonction récursive. On trouvera souvent deux versions possibles d'un même programme : itérative et récursive.\n\nCependant deux éléments sont indispensables à la terminaison d’une fonction récursive :\n\n- il est nécessaire qu’il y ait une condition d’arrêt ;\n- il ne doit pas y avoir de suite infinie d’appels récursifs.\n\n### Exemple\nOn souhaite calculer la somme $S=\\sum_{i=1}^n i =1 +2+3+\\cdots+(n-1) + n$. Ci-dessous une fonction recursive qui calcule la somme des $n$ premiers termes dont on peut visualiser les appels"},{"metadata":{"trusted":true,"scrolled":false},"cell_type":"code","source":"from rcviz import viz # pour visualiser les appels \n@viz\ndef somme(n):\n if n < 1:\n return 0\n else:\n return n + somme(n - 1)\n\nsomme(4) # calcule 1 + 2 + 3 + 4","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Un sous-programme est dit récursif s’il fait appel à lui-même, comme ici.\nDétaillons la procédure compte :\n\n- Pour calculer la somme des `n` termes, on dépcompose le problème comme calculer la somme des `n-1` termes plus `n`;\n- le test `n < 0` est une condition d’arrêt, obligatoire sinon le sous-programme peut boucler indéfiniment;\n- les appels récursifs continuent jusqu’à ce que le paramètre passé à la procédure prenne la valeur 0;\n- la dernière valeur retournée est donc 0.\n\nOn peut visualiser les appels avec :"},{"metadata":{"trusted":true,"scrolled":false},"cell_type":"code","source":"somme.callgraph() # pour visualiser les appels récusifs","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"!!! danger Attention\nOn remarque qu'il est possible d'exécuter cette fonction avec un paramètre qui n'est pas un entier positif. Pour interdire ce cas de figure on peut utiliser l'instruction `assert` :\n!!!\n"},{"metadata":{"trusted":true,"scrolled":false},"cell_type":"code","source":"def somme(n):\n assert n >= 0 and isinstance(n, int), \"n doit être un entier naturel\"\n if n < 1:\n return 0\n else:\n return n + somme(n - 1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"scrolled":false},"cell_type":"code","source":"somme(-2)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"scrolled":false},"cell_type":"code","source":"somme(2.8)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"scrolled":false},"cell_type":"code","source":"somme(8)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<h3 style=\"color:teal;background-color:azure;\" > <i class=\"fa fa-pencil\" aria-hidden=\"true\"> </i> Exercice 1 : Somme des éléments d'une liste </h3>\n\nEcrire une fonction récursive ```somme_liste``` qui :\n\n- prend en paramètre une liste d'entiers `L`\n- retourne la somme des éléments de la liste `L`\n\n\n**Coup de pouce :** \n\n*Condition d'arrêt* : si la liste est vide, la somme de ses élément vaut 0 : donc la fonction renvoie 0.\n\n*Récursion* : renvoyer la valeur du 1er élément additionnée de la somme du reste de la liste."},{"metadata":{"trusted":true,"scrolled":false},"cell_type":"code","source":"def somme_liste(L):\n if len(L) <= 0:\n return 0\n else:\n return L[0] + somme_liste(L[1:])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"scrolled":false},"cell_type":"code","source":"# test \ntab = [5, 4, 7, 2]\nsomme_liste(tab)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<h3 style=\"color:teal;background-color:azure;\" > <i class=\"fa fa-pencil\" aria-hidden=\"true\"> </i> Exercice 2 : Miroir d’une chaîne de caractère </h3>\n\nÉcrire une fonction ```miroir``` récursive qui :\n\n- prend comme paramètre une chaîne de caractères `s`\n- renvoie le « miroir » de la chaîne; par exemple, le miroir de \"abcde\" est \"edcba\".\n\n\n**Coup de pouce :** \n\n*Condition d'arrêt* : si la chaine contient un seul caractère ou aucun, son miroir est elle-même.\n\n*Récursion* : Le principe consiste à permutter le 1er et le dernier carcatère, et à recopier le miroir de la sous-chaine interne (entre le 2ème caractère et l'avant-dernier) au milieu de ces 2 caractères. Il faut donc renvoyer une chaine qui est la concaténation du dernier caratère, du miroir de la sous-chaine interne, et du 1er caractère.\n\n**Aide** : on pourra utiliser la syntaxe `s[1:-1]` qui permet d'extraire une sous-chaine de caractères entre le second élément de l'avant dernier, et `s[0]`, respectivement `s[-1]`, pour accéder au premier, respectivement dernier, élément"},{"metadata":{"trusted":true,"scrolled":false},"cell_type":"code","source":"def miroir(s):\n if len(s) <= 1:\n return s\n else:\n return s[-1] + miroir(s[1:-1]) + s[1]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"scrolled":false},"cell_type":"code","source":"# test\nchaine = 'quelle belle chaine'\nmiroir(chaine)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<h2 class=\"alert alert-info\">2. Rappels sur Turtle</h2>\n\nTurtle est un module Python permettant de dessiner sur un canevas. Le crayon est dirigé par une tortue !\n\nJupyter propose une implémentation de ce module (très légèrement modifié). Les commandes principales consistent à positionner la tortue, lever ou baisser le crayon (pour écrire ou non lorsque la tortue se déplace) et à commander les mouvements de la tortue (avancer/reculer, tourner à gauche/droite d'un certain angle).\n\nPour mieux comprendre et découvrir les commandes accessibles, étudier l'exemple de démonstration ci-dessous :"},{"metadata":{"trusted":true,"scrolled":false},"cell_type":"code","source":"import turtle as tt # import du module turtle\n\ntt.speed(3) # vitesse moyenne (maxi = 10)\n\ntt.penup() # lève le crayon (pour ne pas écrire pendant le déplacement)\ntt.setposition(-100, 100) \n# origine (0, 0) au centre du cadre de dessin (dimensions 600x600)\ntt.pendown() # abaisse le crayon (pour voir la trace de la tortue)\n\ntt.forward(20) # avance de 20\ntt.left(60) # virage de 60° vers la gauche\ntt.forward(100) \ntt.right(120) # virage de 120° vers la droite\ntt.pencolor(\"red\") # couleurs autorisées \"blue\", \"yellow\", \"brown\", \"black\", \"purple\", \"green\"\ntt.forward(100) \ntt.left(60) \ntt.forward(100) # recule de 100\ntt.backward(70) \ntt.right(90) \ntt.pencolor(\"green\") \ntt.forward(300) \n\ntt.penup()\ntt.home() # retour à l'origine\n\ntt.done() # indispensable pour activer la tortue dans Basthon","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"scrolled":false},"cell_type":"code","source":"# 2ème exemple :\n\nimport turtle as tt # import du module turtle\n\n\ncouleurs = [\"red\", \"blue\", \"yellow\", \"brown\", \"black\", \"purple\", \"green\"]\n\ntt.speed(10)\n\nfor i in range(7):\n tt.penup()\n tt.setposition(-200+50*i, 0)\n tt.pendown()\n tt.pencolor(couleurs[i])\n for j in range(4):\n tt.forward(30)\n tt.left(90)\n \ntt.done()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Pour résumer:**\n\n| Fonction |Exemple|Commentaire|\n|:-------- |:------|:----------|\n|forward(x)|forward(150)|Trace un trait de 150 points|\n|backward(x)|backward(150)|Trace un trait “à reculons” de 150 points|\n|left(n)|left(60)|Tourne sur place la tortue de 60° à gauche|\n|right(n)|right(60)|Tourne sur place la tortue de 60° à droite|\n|setposition(x, y) |setposition(-100, 100)|va à la position (-100,100) sachant que l'origine (0;0) est au centre du cadre de dessin (dimensions 600x600)|\n|width(x)|width(5)|Change l’épaisseur à 5 points|\n|color(\"c\")|color(\"yellow\")|Change la couleur du trait (mais aucun trait n’est tracé à ce moment). Notez les guillemets !|\n|penup()|penup()|Lève la tortue (permet de se déplacer sans dessiner)|\n|pendown()|pendown()|Baisse le stylo|\n|home()|home()|retour à l'origine|"},{"metadata":{},"cell_type":"markdown","source":"<h2 class=\"alert alert-info\">3. Fractales : courbe de Koch</h2>\n\nLa courbe de Koch est une fractale reposant sur la construction récursive suviante :\n1. Étape 1 : Tracer un segment de longueur a. \n\n\n\n2. Étape 2 : Diviser le segment en 3 parties de même longueur. Construire un triangle équilatéral ayant pour base le segment médian de la première étape, et en supprimer la base.\n\n\n3. Étape 3 : Reprendre l'étape 2 sur chacun des segments créés.\n\n\n4. Et ainsi de suite...\n\n"},{"metadata":{},"cell_type":"markdown","source":"On peut construire récursivement cette courbe. \n\nLa fonction de tracer prend deux paramètres en entrée :\n* la longeur $a$ du segment.\n* l'étape $n$ de \"profondeur\" de récursivité. \n\nPar exemple, à la profondeur $n=0$, on trace un simple segment : ceci constituera la condition d'arrêt des appels récursifs. À la profondeur $n=1$, le tracé donne la figure de l'étape 2."},{"metadata":{},"cell_type":"markdown","source":"<h3 style=\"color:teal;background-color:azure;\" > <i class=\"fa fa-pencil\" aria-hidden=\"true\"> </i> Exercice 3 : Faire l'étape 2 </h3>\n\n\n1. Écrire une fonction `etape2(a)` qui permet de dessiner avec la tortue (pas de récursivité ici) la figure correspondant à l'étape 2 (décrite ci-avant).\n"},{"metadata":{"trusted":true,"scrolled":false},"cell_type":"code","source":"import turtle as tt # import du module turtle\ntt.speed(10) # pour dessiner plus rapidement\n\ndef etape2(a):\n tt.forward(a)\n tt.left(60)\n tt.forward(a)\n tt.right(120)\n tt.forward(a)\n tt.left(60)\n tt.forward(a)\n \n# test:\na = 50\netape2(a)\n\ntt.done()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"2. En vous inspirant de la logique du code de la fonction précédente (en la \"rendant récursive\"), écrire une fonction koch(a, n) récursive qui :\n\n - prend comme paramètres un nombre entier a représentant la longueur du segment et un entier n égal au nombre de récursions souhaité.\n - construit la courbe de Koch en divisant récursivement chacun des segments\n\n *Rappel* : si n=0, le tracé est un simplement segment de longueur a."},{"metadata":{"trusted":true,"scrolled":false},"cell_type":"code","source":"import turtle as tt # import du module turtle\n\ntt.speed(10)\ntt.penup()\ntt.setposition(-300, 0) \ntt.pendown()\n\ndef koch(a, n):\n if n == 0 :\n tt.forward(a)\n else:\n koch(a/3, n-1)\n tt.left(60)\n koch(a/3, n-1)\n tt.right(120)\n koch(a/3, n-1)\n tt.left(60)\n koch(a/3, n-1)\n\nkoch(360, 4)\n\ntt.done()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<h2 class=\"alert alert-info\">Et pour s'amuser encore un peu...</h2>\nExécuter le code ci-dessous :"},{"metadata":{"trusted":true,"scrolled":false},"cell_type":"code","source":"a = 180\n\ntt.speed(10)\ntt.penup()\ntt.setposition(-a/2, a/3) \ntt.pendown()\n\ndef flocon(a, n):\n for i in range(3):\n koch(a, n)\n tt.right(120)\n \nflocon(a, 3)\n\ntt.penup()\ntt.home()\n\ntt.done()","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"markdown","source":"---\n\n#### Remarque générale\n\nUne partie de ce notebook reprend le cours sur la récursivité du lycée Faustin Flerettiré http://nsinfo.yo.fr/nsi_term_programmation_recursivite.html. Le notebook est sous license Creative Commons [BY-NC-SA](https://creativecommons.org/licenses/?lang=fr)\n"}],"metadata":{"kernelspec":{"display_name":"Python 3.8.1 64-bit ('python38': conda)","language":"python","name":"python38164bitpython38conda56991d5ad1414e06a4dcd344400cf456"}},"nbformat":4,"nbformat_minor":2} \ No newline at end of file