{"id":242,"date":"2022-06-06T07:54:46","date_gmt":"2022-06-06T06:54:46","guid":{"rendered":"https:\/\/blog.univ-angers.fr\/mathsinfo\/?p=242"},"modified":"2022-06-19T08:02:22","modified_gmt":"2022-06-19T07:02:22","slug":"kata5","status":"publish","type":"post","link":"https:\/\/blog.univ-angers.fr\/mathsinfo\/2022\/06\/06\/kata5\/","title":{"rendered":"Cinqui\u00e8me exercice en Python, JavaScript et APL"},"content":{"rendered":"\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/blog.univ-angers.fr\/mathsinfo\/files\/2022\/06\/image-4.png\"><img loading=\"lazy\" decoding=\"async\" width=\"870\" height=\"519\" src=\"https:\/\/blog.univ-angers.fr\/mathsinfo\/files\/2022\/06\/image-4.png\" alt=\"\" class=\"wp-image-243\" srcset=\"https:\/\/blog.univ-angers.fr\/mathsinfo\/files\/2022\/06\/image-4.png 870w, https:\/\/blog.univ-angers.fr\/mathsinfo\/files\/2022\/06\/image-4-300x179.png 300w, https:\/\/blog.univ-angers.fr\/mathsinfo\/files\/2022\/06\/image-4-768x458.png 768w, https:\/\/blog.univ-angers.fr\/mathsinfo\/files\/2022\/06\/image-4-500x298.png 500w\" sizes=\"auto, (max-width: 870px) 100vw, 870px\" \/><\/a><\/figure>\n\n\n\n<p><span style=\"text-decoration: underline\">Exemple 1<\/span> : <code>~O~O~O~OP<\/code> <br>Tous les rats vont bien vers le joueur de fl\u00fbte, donc aucun n&rsquo;est sourd. Valeur attendue = <strong>0<\/strong><\/p>\n\n\n\n<p><span style=\"text-decoration: underline\">Exemple 2<\/span> : <code>PO~O~<u>~O<\/u>O~<\/code><br>Le rat soulign\u00e9 va dans la mauvaise direction, il est donc sourd. Valeur attendue = <strong>1<\/strong><\/p>\n\n\n\n<p><span style=\"text-decoration: underline\">Exemple 3<\/span> : <code>~O<u>O~<\/u>~O~OP<u>~O<\/u>O~O~<\/code><br>Cette fois il y a 2 rats sourds. Valeur attendue = <strong>2<\/strong><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">S\u00e9parer les rats \u00e0 gauche et \u00e0 droite du joueur de fl\u00fbte<\/h2>\n\n\n\n<p>Une <span style=\"text-decoration: underline\">premi\u00e8re id\u00e9e<\/span> est de r\u00e9cup\u00e9rer les rats qui sont \u00e0 <strong>gauche<\/strong> et \u00e0 <strong>droite<\/strong> du joueur de fl\u00fbte. Pour cela on utilise <strong>split<\/strong> en Python\/JavaScript ou <strong>\u2286<\/strong> en APL.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Python &amp; Javascript<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>&gt;&gt; '~O~O~O~OP'.split('P')\n&#091;'~O~O~O~O', '']\n\n&gt;&gt; 'PO~O~~OO~'.split('P')\n&#091;'', 'O~O~~OO~']\n\n&gt;&gt; '~OO~~O~OP~OO~O~'.split('P')\n&#091;'~OO~~O~O', '~OO~O~']<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">APL<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>      {('P'\u2260\u2375) \u2286 \u2375} '~OO~~O~OP~OO~O~'\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502~OO~~O~O\u2502~OO~O~\u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/code><\/pre>\n\n\n\n<p>Ensuite, un rat sera sourd dans la partie <strong>gauche<\/strong> s&rsquo;il y a un &lsquo;O&rsquo; \u00e0 une position <strong>paire<\/strong> (puisque l&rsquo;on est cens\u00e9 avoir d\u00e9j\u00e0 la queue du rat puis la t\u00eate ~O et pas l&rsquo;inverse). De la m\u00eame fa\u00e7on, dans la partie <strong>droite<\/strong>, un rat est sourd si on trouve un &lsquo;O&rsquo; \u00e0 une position <strong>impaire<\/strong>. On pourrait donc imaginer faire 2 boucles, chacune ressemblant \u00e0 :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>for i in range(len(gauche)):\n  if gauche&#091;i] == 'O' and i%2 == 0:   # un 'O' \u00e0 une position paire\n    sourds += 1     <\/code><\/pre>\n\n\n\n<p>Une boucle suffit si on concat\u00e8ne <strong>gauche<\/strong> et <strong>droite<\/strong> (et que l&rsquo;on retourne une des 2 chaines). C&rsquo;est-\u00e0-dire passer de [&lsquo;<strong>~OO~~O~O<\/strong>&lsquo;, &lsquo;~OO~O~&rsquo;] \u00e0 l&rsquo;unique chaine &lsquo;<strong><strong>~OO~~O~O<\/strong><\/strong>~O~OO~&rsquo; (on a retourn\u00e9 tous les rats qui \u00e9taient dans la partie <strong>droite<\/strong>). Les rats sourds sont ceux o\u00f9 il y a un &lsquo;O&rsquo; \u00e0 une position paire (rappel, en Python et JavaScript, le premier \u00e9l\u00e9ment d&rsquo;une chaine ou d&rsquo;un tableau est \u00e0 la position <strong>0<\/strong>).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">retourner une chaine en Python<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>&gt;&gt; 'bonjour'&#091;::-1]\n'ruojnob'<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Retourner une chaine en javascript<\/h3>\n\n\n\n<p>Javascript sait inverser un tableau mais pas une chaine. On va donc convertir la chaine en tableau, inverser ce tableau puis revenir \u00e0 une chaine :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&gt;&gt;&#091;...'bonjour']\n&#091;'b', 'o', 'n', 'j', 'o', 'u', 'r']\n\n&gt;&gt; &#091;...'bonjour'].reverse()\n&#091;'r', 'u', 'o', 'j', 'n', 'o', 'b']\n\n&gt;&gt; &#091;...'bonjour'].reverse().join('')\n'ruojnob'<\/code><\/pre>\n\n\n\n<p>Si on a fr\u00e9quemment besoin d&rsquo;inverser une chaine en JavaScript, soit on trouve une biblioth\u00e8que (comme <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/mathiasbynens\/esrever\" target=\"_blank\">E<\/a><a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/mathiasbynens\/esrever\" target=\"_blank\">srever<\/a>) contenant cette fonctionnalit\u00e9, ou on cr\u00e9e un <strong>prototype<\/strong> :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&gt;&gt; String.prototype.reverse = function() {\n  return this.split(\"\").reverse().join(\"\");\n}\n\n&gt;&gt; 'bonjour'.reverse()\n'ruojnob'<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">en apl<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>      \u233d'bonjour'       \u235d Admirez le symbole utilis\u00e9\nruojnob<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">version finale en python<\/h3>\n\n\n\n<p>Il faut donc parcourir toutes les lettres de la chaine contenant les rats et regarder s&rsquo;il y a un &lsquo;O&rsquo; \u00e0 une position paire. Pour cela on utilise <strong>enumerate<\/strong> qui permettra de r\u00e9cup\u00e9rer \u00e0 la fois le caract\u00e8re et son rang :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&gt;&gt; list(enumerate('~OO~~O~O~O~OO~'))\n&#091;(0, '~'), (1, 'O'), (2, 'O'), (3, '~'), (4, '~'), (5, 'O'), (6, '~'), (7, 'O'), (8, '~'), (9, 'O'), (10, '~'), (11, 'O'), (12, 'O'), (13, '~')]<\/code><\/pre>\n\n\n\n<p>Vous avez tout pour comprendre <a href=\"https:\/\/tio.run\/##dY7LCoMwEEX3fsXdlCTUlj52gt8Q9yJFTKyBmkgelG78dZtoF120M5thzpnLTC8\/GH1dFiF72Na7mzPBCke9eWpWZIhV39vQDTKHsEZ52aBEokc3PZSnpCJs1dJ1RJuM\/ceui@JwbjZB@mA1XBhp3aEsQThBqwUUdrikxQm9sVB5B6UhdRhlDJU0JbOGZdlklfb0@00y863jF@wXrxKdOZ\/\/8ITW@zSs1rK8AQ\" target=\"_blank\" rel=\"noreferrer noopener\">cette version \u00e0 tester ici<\/a> :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>def rats_sourds(town):\n    &#091;gauche, droite] = town.split('P')\n    rats = gauche + droite&#091;::-1]\n    return sum(&#091;c == 'O' and i % 2 == 0 for i,c in enumerate(rats)])\n\n&gt;&gt; rats_sourds('~O~O~O~OP')\n0\n&gt;&gt; rats_sourds('PO~O~~OO~')\n1\n&gt;&gt; rats_sourds('~OO~~O~OP~OO~O~')\n2<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Javascript<\/h3>\n\n\n\n<p>Nous avons besoin de parcourir une chaine et accumuler le nombre de rats sourds, cela fait penser \u00e0 <strong>reduce<\/strong> que nous avons utilis\u00e9 au premier exercice. Notre accumulateur <strong>a<\/strong> sera le nombre de rats sourds (initialis\u00e9 \u00e0 <strong>0<\/strong>) qui incr\u00e9mentera de 1 au fur et \u00e0 mesure si besoin.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&gt;&gt; var rats_sourds = ville =&gt; {\n    &#091;gauche, droite] = ville.split('P');\n    rats = gauche + &#091;...droite].reverse().join('');\n    return &#091;...rats]\n       .reduce((a, c, i) =&gt; i%2 == 0 &amp;&amp; c == 'O' ? a + 1 : a, 0)}\n\n&gt;&gt; rats_sourds('~O~O~O~OP')\n0\n&gt;&gt; rats_sourds('PO~O~~OO~')\n1\n&gt;&gt; rats_sourds('~OO~~O~OP~OO~O~')\n2<\/code><\/pre>\n\n\n\n<p><span style=\"text-decoration: underline\">Remarque<\/span> : <strong>reduce<\/strong> existe aussi en Python, en utilisant la biblioth\u00e8que <strong>functools<\/strong>. Voici un exemple o\u00f9 l&rsquo;on compte par accumulation le nombre de &lsquo;e&rsquo; dans une liste de mots :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&gt;&gt; from functools import reduce\n&gt;&gt; mots = &#091;'hello', 'yes', 'no', 'eleve']   # Liste de mots\n\n&gt;&gt; reduce(lambda a, c : a + c.count('e'), mots, 0)\n5<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">A-t-on vraiment besoin de s\u00e9parer la gauche et la droite ?<\/h2>\n\n\n\n<p>En observant un peu plus attentivement la chaine repr\u00e9sentant une ville, par exemple &lsquo;~OO~~O~OP~OO~O~&rsquo;, on se rend compte que peu importe l&#8217;emplacement du joueur de fl\u00fbte, il y aura un rat sourd d\u00e8s qu&rsquo;un &lsquo;O&rsquo; est observ\u00e9 \u00e0 une position <strong>paire<\/strong>. Par exemple dans la ville &lsquo;P~<strong>O<\/strong>O~O~&rsquo;, la t\u00eate du rat sourd est bien \u00e0 une position paire.<\/p>\n\n\n\n<p><em>Finalement, il suffit de compter le nombre de &lsquo;O&rsquo; qu&rsquo;il y a dans la ville en n&rsquo;ayant r\u00e9cup\u00e9r\u00e9 que les lettres qui sont aux positions paires.<\/em><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Python<\/h3>\n\n\n\n<p>Il est tr\u00e8s facile de r\u00e9cup\u00e9rer une lettre sur 2 en Python :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&gt;&gt; 'UneLettreSurDeux'&#091;::2]\n'UeeteuDu'<\/code><\/pre>\n\n\n\n<p>Et le programme final, beaucoup plus court suite \u00e0 notre analyse : <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&gt;&gt; def rats_sourds(ville):\n    return ville&#091;::2].count('O')<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">javascript<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>&gt;&gt; var rats_sourds = ville =&gt; &#091;...ville]\n       .reduce((a, c, i) =&gt; i%2 == 0 &amp;&amp; c == 'O' ? a + 1 : a, 0)<\/code><\/pre>\n\n\n\n<p>On peut aussi utiliser un <strong>filtre<\/strong> pour ne garder que les &lsquo;O&rsquo; qui sont \u00e0 des positions paires puis <strong>compter<\/strong> le nombre d&rsquo;\u00e9l\u00e9ments (<strong>length<\/strong>) :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&gt;&gt; var rats_sourds = ville =&gt; &#091;...ville]\n       .filter((c, i) =&gt; i%2 == 0 &amp;&amp; c == 'O').length\n\n&gt;&gt; rats_sourds('~O~O~O~OP')\n0\n&gt;&gt; rats_sourds('PO~O~~OO~')\n1\n&gt;&gt; rats_sourds('~OO~~O~OP~OO~O~')\n2<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">apl<\/h3>\n\n\n\n<p>Pour s\u00e9lectionner, en APL, des \u00e9l\u00e9ments d&rsquo;une chaine, d&rsquo;un vecteur ou d&rsquo;une matrice, on utilise <strong>\/<\/strong> et un <strong>vecteur bool\u00e9en<\/strong> (constitu\u00e9 de <strong>1<\/strong> ou de <strong>0<\/strong>). Par exemple :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>      2 | \u23737               \u235d Restes des divisions de 1, 2..., 7 par 2\n1 0 1 0 1 0 1\n      (2 | \u23737) \/ 'bonjour' \u235d qui sert \u00e0 s\u00e9lectionner une lettre sur 2\nbnor<\/code><\/pre>\n\n\n\n<p>Au lieu de 7 comme dans l&rsquo;exemple, on utilisera \u2374\u2375 pour r\u00e9cup\u00e9rer la taille de la ville. On peut finalement rep\u00e9rer les &lsquo;O&rsquo; qui sont aux positions paires :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>      rats_sourds_version_0 \u2190 {'O' = (2|\u2373\u2374\u2375) \/ \u2375}\n\n      rats_sourds_version_0 '~OO~~O~OP~OO~O~'\n0 1 0 0 0 1 0 0         \u235d Les 1 correspondent aux t\u00eates des rats sourds<\/code><\/pre>\n\n\n\n<p>Et ensuite les compter, c&rsquo;est-\u00e0-dire faire une r\u00e9duction par la somme :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>      rats_sourds_version_1 \u2190 {+\/ 'O' = (2|\u2373\u2374\u2375) \/ \u2375}\n\n      rats_sourds_version_1 '~OO~~O~OP~OO~O~'\n2<\/code><\/pre>\n\n\n\n<p>Observez que l&rsquo;on a fait des tests ( &lsquo;O&rsquo; = &#8230;) qui donne des 0 ou des 1 puis l&rsquo;addition de ces valeurs. De fa\u00e7on analogue, la fonction <strong>SOMMEPROD<\/strong> d&rsquo;Excel fait des produits et ensuite leur somme. C&rsquo;est ce qu&rsquo;on appelle un <strong>produit interne<\/strong>. En voici quelques exemples (\u2308 permet de r\u00e9cup\u00e9rer le plus grand entre 2 nombres) :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>    +\/  2 6 \u00d7 4 5    \u235d (2 \u00d7 4) + (6 \u00d7 5) = 38 (somme des produits)\n38\n\n   2 6  +.\u00d7 4 5      \u235d M\u00eame r\u00e9sultat en utilisant un produit interne\n38\n\n    \u00d7\/  2 6 \u2308 4 5    \u235d (2 \u2308 4) \u00d7 (6 \u2308 5) = 4 \u00d7 6 = 24\n24\n\n   2 6 \u00d7.\u2308 4 5       \u235d Produit des plus grands termes\n24<\/code><\/pre>\n\n\n\n<p>Version finale en APL :<\/p>\n\n\n\n<p><a href=\"https:\/\/tio.run\/##SyzI0U2pTMzJT9dNzkksLs5M\/g8ERYklxfHF@aVFKcUKj9omKFSr@6sraOvZKmgY1Tzq3fyod8uj3q2aCvoKQKqWC1m1ep0\/BAaoo4oHgETr\/P3r1NHVg4SB6kEMoCwA\" target=\"_blank\" rel=\"noreferrer noopener\">Lien pour tester directement le code ci-dessous<\/a> :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>      rats_sourds \u2190 {'O' +.= (2|\u2373\u2374\u2375) \/ \u2375}\n\n      rats_sourds '~O~O~O~OP'\n0\n      rats_sourds 'PO~O~~OO~'\n1\n      rats_sourds '~OO~~O~OP~OO~O~'\n2<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Exemple 1 : ~O~O~O~OP Tous les rats vont bien vers le joueur de fl\u00fbte, donc aucun n&rsquo;est sourd. Valeur attendue = 0 Exemple 2 : PO~O~~OO~Le rat soulign\u00e9 va dans la mauvaise direction, il est donc sourd. Valeur attendue = &hellip; <a href=\"https:\/\/blog.univ-angers.fr\/mathsinfo\/2022\/06\/06\/kata5\/\">Continuer la lecture <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":4913,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6],"tags":[],"class_list":["post-242","post","type-post","status-publish","format-standard","hentry","category-twitter"],"_links":{"self":[{"href":"https:\/\/blog.univ-angers.fr\/mathsinfo\/wp-json\/wp\/v2\/posts\/242","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.univ-angers.fr\/mathsinfo\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.univ-angers.fr\/mathsinfo\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.univ-angers.fr\/mathsinfo\/wp-json\/wp\/v2\/users\/4913"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.univ-angers.fr\/mathsinfo\/wp-json\/wp\/v2\/comments?post=242"}],"version-history":[{"count":23,"href":"https:\/\/blog.univ-angers.fr\/mathsinfo\/wp-json\/wp\/v2\/posts\/242\/revisions"}],"predecessor-version":[{"id":654,"href":"https:\/\/blog.univ-angers.fr\/mathsinfo\/wp-json\/wp\/v2\/posts\/242\/revisions\/654"}],"wp:attachment":[{"href":"https:\/\/blog.univ-angers.fr\/mathsinfo\/wp-json\/wp\/v2\/media?parent=242"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.univ-angers.fr\/mathsinfo\/wp-json\/wp\/v2\/categories?post=242"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.univ-angers.fr\/mathsinfo\/wp-json\/wp\/v2\/tags?post=242"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}