{"id":195,"date":"2022-06-04T07:14:52","date_gmt":"2022-06-04T06:14:52","guid":{"rendered":"https:\/\/blog.univ-angers.fr\/mathsinfo\/?p=195"},"modified":"2022-06-19T08:02:01","modified_gmt":"2022-06-19T07:02:01","slug":"kata3","status":"publish","type":"post","link":"https:\/\/blog.univ-angers.fr\/mathsinfo\/2022\/06\/04\/kata3\/","title":{"rendered":"Troisi\u00e8me exercice Python \/ JavaScript \/ APL"},"content":{"rendered":"\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/blog.univ-angers.fr\/mathsinfo\/files\/2022\/06\/image-2.png\"><img loading=\"lazy\" decoding=\"async\" width=\"731\" height=\"374\" src=\"https:\/\/blog.univ-angers.fr\/mathsinfo\/files\/2022\/06\/image-2.png\" alt=\"\" class=\"wp-image-196\" srcset=\"https:\/\/blog.univ-angers.fr\/mathsinfo\/files\/2022\/06\/image-2.png 731w, https:\/\/blog.univ-angers.fr\/mathsinfo\/files\/2022\/06\/image-2-300x153.png 300w, https:\/\/blog.univ-angers.fr\/mathsinfo\/files\/2022\/06\/image-2-500x256.png 500w\" sizes=\"auto, (max-width: 731px) 100vw, 731px\" \/><\/a><\/figure>\n\n\n\n<p><u>R\u00e9sum\u00e9 en fran\u00e7ais<\/u> : un <strong>isogram<\/strong> (En fran\u00e7ais on parle d&rsquo;<strong>heterogramme<\/strong>) est un mot qui ne contient aucune lettre r\u00e9p\u00e9t\u00e9e. Ecrire une fonction qui renvoie <strong>vrai<\/strong> ou <strong>faux<\/strong> suivant que le mot est un heterogramme, sans tenir compte de la casse (majuscule\/minuscule)<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Les ensembles<\/h2>\n\n\n\n<p>Que ce soit en Python, JavaScript ou APL, on peut cr\u00e9er des <strong>ensembles<\/strong>.<\/p>\n\n\n\n<p>Commen\u00e7ons par <strong>Python<\/strong>, en plus des listes [ ], tuples ( ) et dictionnaires { }, les ensembles sont des listes non ordonn\u00e9es sans \u00e9l\u00e9ments r\u00e9p\u00e9t\u00e9s :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&gt;&gt; set({5, 5, 1, 5, 1})\n{1, 5}\n\n&gt;&gt; set('abracadabra')\n{'d', 'a', 'b', 'c', 'r'}<\/code><\/pre>\n\n\n\n<p>En <strong>JavaScript<\/strong>, on d\u00e9finit un ensemble de fa\u00e7on assez semblable :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&gt;&gt; new Set(&#091;5, 5, 1, 5, 1])\n{5, 1}\n\n&gt;&gt; new Set('abracadabra')\n{'a', 'b', 'r', 'c', 'd'}<\/code><\/pre>\n\n\n\n<p>Et en <strong>APL<\/strong> le symbole est celui de l&rsquo;union comme en math\u00e9matique :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>      \u222a 5 5 1 5 1\n5 1\n      \u222a 'abracadabra'\nabrcd<\/code><\/pre>\n\n\n\n<p><u>L&rsquo;id\u00e9e principale<\/u> : On aura un heterogramme si la taille de l&rsquo;ensemble des lettres utilis\u00e9es pour \u00e9crire le mot est \u00e9gal \u00e0 la taille du mot initial. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Python<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>def isogram(mot):\n    return len(mot) == len(set(mot.lower()))\n\n&gt;&gt; isogram('Dermatoglyphics')\nTrue\n&gt;&gt; isogram('aba')\nFalse\n&gt;&gt; isogram('moOse')\nFalse<\/code><\/pre>\n\n\n\n<p>Remarquez que le mot a besoin d&rsquo;\u00eatre mis en minuscule (ou majuscule) uniquement pour cr\u00e9er l&rsquo;ensemble des lettres, pas pour trouver sa taille initiale. <strong>len<\/strong> permet en Python de donner la taille d&rsquo;une chaine, d&rsquo;une liste ou d&rsquo;un dictionnaire.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">javascript<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>isogram = mot =&gt; mot.length == new Set(mot.toLowerCase()).size<\/code><\/pre>\n\n\n\n<p><strong>length<\/strong> pour la taille d&rsquo;une chaine ou d&rsquo;un tableau, <strong>size<\/strong> pour les ensembles.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">APL<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>isogram \u2190 \u2374 = (\u2374\u222a\u2218\u2395C)\n\n      isogram'Dermatoglyphics'\n1\n      isogram'aba'\n0\n      isogram'moOse'\n0<\/code><\/pre>\n\n\n\n<p>\u2395C permet de convertir une chaine en minuscule, on cherche ensuite avec \u222a l&rsquo;ensemble des lettres utilis\u00e9es et on calcule sa taille \u2374. Finalement, on teste si elle est \u00e9gale \u00e0 celle du mot initial.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Recherche d&rsquo;au moins une lettre en double<\/h2>\n\n\n\n<p>Une autre id\u00e9e peut \u00eatre de rechercher s&rsquo;il existe <strong>au moins une lettre en double<\/strong>, par exemple en utilisant 2 boucles, en voici une version g\u00e9n\u00e9rique \u00e9crite en JavaScript mais facilement traduisible en Python :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>function isogram(mot) {\n  mot = mot.toLowerCase();\n  for (i = 0; i &lt; mot.length - 1; i++) {\n    for (j = i + 1; j &lt; mot.length; j++) {\n      if (mot&#091;i] == mot&#091;j]) return false;\n    }\n  }\n  return true;\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">D&rsquo;autres pistes&#8230;<\/h2>\n\n\n\n<p>Voici d&rsquo;autres pistes pour aborder ce probl\u00e8me dans chacun des langages :<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">javascript<\/h3>\n\n\n\n<p>Ecrivons une <strong>expression r\u00e9guli\u00e8re<\/strong> (<strong>Regex<\/strong>) qui va tester si une correspondance (<strong>match<\/strong> en anglais) existe entre un caract\u00e8re (not\u00e9 \u00ab\u00a0<strong>.<\/strong>\u00a0\u00bb en Regex) et ce m\u00eame caract\u00e8re un peu plus loin. <\/p>\n\n\n\n<p>L&rsquo;expression r\u00e9guli\u00e8re est (<a href=\"https:\/\/regex101.com\/r\/TjZRjh\/1\" target=\"_blank\" rel=\"noreferrer noopener\">exemple ici avec le mot <strong>couleur<\/strong><\/a>):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>(.).*\\1<\/code><\/pre>\n\n\n\n<p>le <strong>(.)<\/strong> permet de chercher un caract\u00e8re et de le m\u00e9moriser dans un groupe (les parenth\u00e8ses). Ensuite <strong>.*<\/strong> signifie 0 ou plusieurs caract\u00e8res quelconques et le <strong>\\1<\/strong> rappelle le premier groupe, donc pour trouver un \u00e9ventuel doublon. On ajoute le param\u00e8tre <strong>i<\/strong> pour que la recherche soit ind\u00e9pendante de la casse :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>isogram = mot =&gt; !\/(.).*\\1\/i.test(mot.toLowerCase())\n\n&gt;&gt; isogram('Dermatoglyphics')\ntrue<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Python<\/h3>\n\n\n\n<p>Pour savoir si une lettre est en double, on peut compter (<strong>count<\/strong>) combien de fois elle apparait dans le mot. Si toutes (<strong>all<\/strong>) les lettres n&rsquo;apparaissent qu&rsquo;une seule fois, c&rsquo;est un heterogramme.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&gt;&gt; 'abracadabra'.count('a')\n5\n\ndef isogram(mot):\n    mot = mot.lower()\n    return all(mot.count(c) == 1 for c in mot)<\/code><\/pre>\n\n\n\n<p>Ou utiliser le module <strong>collections<\/strong> qui contient la classe <strong>Counter<\/strong> permettant de faire du d\u00e9nombrement.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&gt;&gt; from collections import Counter\n&gt;&gt; Counter('abracadabra')\nCounter({'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1})\n&gt;&gt; Counter('abracadabra').values()\ndict_values(&#091;5, 2, 2, 1, 1])<\/code><\/pre>\n\n\n\n<p>On a alors l&rsquo;alternative :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>from collections import Counter\n\ndef isogram(mot):    \n return all(v == 1 for v in Counter(mot.lower()).values())<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">APL<\/h3>\n\n\n\n<p>Le symbole \u2338 (<strong>key<\/strong>) permet de cr\u00e9er des sortes de tableaux crois\u00e9s dynamiques comme sur Excel. Par exemple :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>      {\u237a,\u2375}\u2338 'abracadabra'\na 1  4 6 8 11\nb 2  9       \nr 3 10       \nc 5          \nd 7 <\/code><\/pre>\n\n\n\n<p>Pour chaque \u00e9l\u00e9ment distinct \u237a de la chaine (c&rsquo;est-\u00e0-dire les lettres a, b, r, c et d), il affiche les positions trouv\u00e9es \u2375. La lettre &lsquo;a&rsquo; a \u00e9t\u00e9 vue aux positions 1, 4, 6&#8230; On peut lui demander de n&rsquo;afficher que le nombre de positions trouv\u00e9es, avec ou sans pr\u00e9ciser \u237a :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>      {\u237a,\u2262\u2375}\u2338 'abracadabra'\na 5\nb 2\nr 2\nc 1\nd 1\n\n      {\u2262\u2375}\u2338 'abracadabra'       \u235d ou encore \u22a2\u2218\u2262\u2338 'abracadabra'\n5 2 2 1 1<\/code><\/pre>\n\n\n\n<p>Si c&rsquo;est un heterogramme, toutes ces valeurs doivent \u00eatre \u00e9gales \u00e0 1 :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>      {\u2262\u2375}\u2338 \u2395C 'Dermatoglyphics'\n1 1 1 1 1 1 1 1 1 1 1 1 1 1 1<\/code><\/pre>\n\n\n\n<p>On va comparer tous les \u00e9l\u00e9ments avec 1 puis faire une r\u00e9duction avec un ET. Ce qui signifie : Est-ce que le premier \u00e9l\u00e9ment vaut 1 ET est-ce que le second terme vaut 1 etc. Pour cela 2 notations :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>      ^\/ 1 = \u222a{\u2262\u2375}\u2338 \u2395C 'aba'      \u235d Test 1 = ... puis r\u00e9duction ^\/\n0\n\n      1 ^.= \u222a{\u2262\u2375}\u2338 \u2395C 'aba'       \u235d Ecriture \u00e9quivalente avec 1 ^.=\n0\n      1 ^.= \u222a{\u2262\u2375}\u2338 \u2395C 'Dermatoglyphics'\n1<\/code><\/pre>\n\n\n\n<p>Ce qui donne finalement :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>      isogram \u2190 1 ^.= \u222a{\u2262\u2375}\u2338 \u2395C\n\n      isogram 'aba'\n0\n      isogram 'Dermatoglyphics'\n1\n\n\u235d ou encore :\n\n      isogram \u2190 1 ^.= (\u222a(\u22a2\u2218\u2262\u2338 \u2395C))<\/code><\/pre>\n\n\n\n<p>Pour finir, autre version qui signifie litt\u00e9ralement \u00ab\u00a0<em>mettre le mot en minuscule, compter le nombre de d&rsquo;occurrences de chaque lettre (sans r\u00e9p\u00e9tition), prendre la plus grande de ces valeurs et tester si c&rsquo;est 1<\/em>\u00ab\u00a0), limpide diront certains \ud83d\ude05<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>isogram \u2190 1 = (\u2308\/ (\u22a2\u2218\u2262 \u2338 \u2395C))<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>R\u00e9sum\u00e9 en fran\u00e7ais : un isogram (En fran\u00e7ais on parle d&rsquo;heterogramme) est un mot qui ne contient aucune lettre r\u00e9p\u00e9t\u00e9e. Ecrire une fonction qui renvoie vrai ou faux suivant que le mot est un heterogramme, sans tenir compte de la &hellip; <a href=\"https:\/\/blog.univ-angers.fr\/mathsinfo\/2022\/06\/04\/kata3\/\">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-195","post","type-post","status-publish","format-standard","hentry","category-twitter"],"_links":{"self":[{"href":"https:\/\/blog.univ-angers.fr\/mathsinfo\/wp-json\/wp\/v2\/posts\/195","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=195"}],"version-history":[{"count":30,"href":"https:\/\/blog.univ-angers.fr\/mathsinfo\/wp-json\/wp\/v2\/posts\/195\/revisions"}],"predecessor-version":[{"id":652,"href":"https:\/\/blog.univ-angers.fr\/mathsinfo\/wp-json\/wp\/v2\/posts\/195\/revisions\/652"}],"wp:attachment":[{"href":"https:\/\/blog.univ-angers.fr\/mathsinfo\/wp-json\/wp\/v2\/media?parent=195"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.univ-angers.fr\/mathsinfo\/wp-json\/wp\/v2\/categories?post=195"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.univ-angers.fr\/mathsinfo\/wp-json\/wp\/v2\/tags?post=195"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}