Petits exercices de programmation (niveau Lycée) en Python, JavaScript ou… APL

Page Twitter où j’ai mis quelques challenges que je vous propose de résoudre en Python, Javascript ou APL.


Python est le langage officiel enseigné dans les lycées français, donc pas le choix 😅
Lien pour taper en Python

JavaScript est un langage permettant de faire des interactions avec une page web. Indispensable si vous voulez devenir développeur web 🤓

APL n’est rien de tout ça ! Peu ou pas connu des informaticiens, critiqué pour son aspect ésotérique, il existe et résiste depuis plus de 50 ans (60 ans de façon théorique) ! 🏆
Ce langage développe une certaine façon de penser et vous donnera souvent des idées que vous pourrez ensuite réinterpréter en Python ou JavaScript. Son apprentissage n’est pas aisé mais sa beauté compense tous ses vilains défauts 🥰
Lien pour taper en APL

Les énoncés et corrigés sont aussi disponibles en version Notebook

Premier exercice (tiré de codewars.com)

Résumé en français : 2 paramètres entiers vous sont donnés, par exemple 1 et 9, le premier étant toujours inférieur au second (mais ils peuvent être négatifs). Vous devez trouver combien de nombres sont entre les 2 sachant qu’ils ne doivent pas contenir de ‘5’.

Python & Javascript

Testez cette version en ligne ici :

def dont_give_me_five(debut, fin):
 compteur = 0
 for v in range(debut, fin+1):
  if '5' not in str(v):
   compteur += 1
 return compteur

Cette version a le mérite d’être simple à comprendre. On initialise un compteur à zéro et on parcourt la liste complète des nombres entre debut et fin (avec un +1 pour inclure la valeur fin).
Pour savoir si 5 est ou n’est pas dans le nombre, on transforme le nombre v en chaine de caractères (str) et on teste si le caractère ‘5’ n’est pas dans cette chaine. C’est beaucoup plus facile que de le faire avec des formules mathématiques !
Si c’est vrai que ‘5’ n’est pas dans la chaine, le compteur augmente de 1.

Son équivalent en JavaScript que vous pouvez tester ici :

function dont_give_me_five(debut, fin) {
    let compteur = 0;
    for (let i = debut; i <= fin; i++)
        if (!i.toString().includes("5"))
            compteur++;
    return compteur;
}

En JavaScript, le “!” signifie “négation” et includes “contient”. On peut aussi utiliser une expression régulière qui testera (test) s’il y a un 5 et qui au passage convertira le paramètre (ici le nombre i) en chaine :

function dont_give_me_five(debut, fin) {
    let compteur = 0;
    for (let i = debut; i <= fin; i++)
        if (!/5/.test(i))
            compteur++;
    return compteur;
}

APL

Vous pourrez tester les commandes ci-dessous en allant sur le site https://tryapl.org/

Si vous n’avez jamais entendu parler d’APL, j’ai fait 3 petites vidéos d’introduction à son sujet, la première est ici :

APL permet de générer facilement la liste des nombres de 1 à N ≥ 0. Par exemple :

      ⍳6       ⍝ le symbole ⍳ se lit 'iota'
1 2 3 4 5 6

Pour que la liste démarre à 0 (ce qui est le cas des positions dans les tableaux en Python ou JavaScript), on peut l’imposer :

      ⎕IO ← 0
      ⍳6
0 1 2 3 4 5

Si maintenant on teste 17+4-1 et 17-1+4, on s’attend à obtenir la même chose… Et bien non !

      17+4-1
20
      17-1+4
12

La logique d’APL est de faire les calculs de la droite vers la gauche, donc pour la première écriture on aura -1 puis 4-1=3 puis +3=3 et enfin17+3=20.
Pour la seconde écriture, 4 puis 1+4=5 puis -5 puis 17-5=12.
Il ne faut donc pas confondre -1+4 et ¯1+4 (il y a un symbole spécial pour les nombres négatifs)

Pour avoir la liste des nombres entre 4 et 17 :

      4 + ⍳17+1-4
4 5 6 7 8 9 10 11 12 13 14 15 16 17
      4 {⍺ + ⍳⍵+1-⍺} 17
4 5 6 7 8 9 10 11 12 13 14 15 16 17

Le symbole ⍺ correspond au paramètre qui est à gauche et ⍵ à celui de droite.

Transformons chacun de ces nombres en chaines avec ⍕ et ¨ (pour chaque)

      ⍕¨4 {⍺ + ⍳⍵+1-⍺} 17             ⍝ Nombres transformés en chaines
┌─┬─┬─┬─┬─┬─┬──┬──┬──┬──┬──┬──┬──┬──┐
│4│5│6│7│8│9│10│11│12│13│14│15│16│17│
└─┴─┴─┴─┴─┴─┴──┴──┴──┴──┴──┴──┴──┴──┘
      ⍴∘⍕¨4 {⍺ + ⍳⍵+1-⍺} 17           ⍝ Longueurs des chaines
┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐
│1│1│1│1│1│1│2│2│2│2│2│2│2│2│
└─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘

Cherchons maintenant si le caractère ‘5’ est dans ces chaines, pour cela on va composer ∊ (test d’appartenance) avec ⍕ :

      '5' ∊∘⍕¨ 4 + ⍳14
0 1 0 0 0 0 0 0 0 0 0 1 0 0

et en ajoutant la négation ~ :

     ~ '5' ∊∘⍕¨ 4 + ⍳14
1 0 1 1 1 1 1 1 1 1 1 0 1 1

Il ne reste plus qu’à compter le nombre de 1 en utilisant une réduction :

    +/ ~ '5' ∊∘⍕¨ 4 + ⍳14
12

Ce qui donne comme programme final que vous pouvez lancer directement ici :

      dont_give_me_five ← {+/ ~ '5' ∊∘⍕¨ ⍺ + ⍳⍵+1-⍺}

      
      4 dont_give_me_five 17
12
      ¯17 dont_give_me_five ¯4
12

Autres versions en python/javascript

Notre version APL propose de créer une liste de booléens suivant que ‘5’ est où non dans la chaine puis d’en faire la réduction par la somme. Or en Python :

> True + True        # 1 + 1
2
> True + False       # 1 + 0 
1

D’où cette seconde version :

def dont_give_me_five(debut, fin):
    return sum(['5' not in str(i) for i in range(debut, fin + 1)])

# qui peut même s'écrire sans les crochets :

def dont_give_me_five(debut, fin):
    return sum('5' not in str(i) for i in range(debut, fin + 1))

Pour terminer, voyons comment utiliser reduce en JavaScript afin d’ajouter +1 (ou + true) à chaque fois que le nombre convient. Pour cela il faut partir d’un tableau de taille fin – debut + 1, peut importe son contenu :

>> [...Array(17 - 4 + 1)]
(14) [undefined, undefined, ..., undefined]

reduce utilise un accumulateur ayant une valeur initiale (pour nous 0) et au fur et à mesure cet accumulateur va pouvoir changer. Ci-dessous 3 paramètres ont être ajoutés, l’accumulateur a, la valeur v et le rang r. Ainsi, en parcourant les éléments d’un tableau, on peut récupérer leurs valeurs et leurs rangs. Le 0 après la virgule est pour l’initialisation de l’accumulateur.

[...Array(17 - 4 + 1)].reduce((a,v,r) =>    , 0)

Vous devriez comprendre l’idée de cette version :

dontGiveMeFive = (debut,fin) => [...Array(fin - debut + 1)]
     .reduce(
       (a, _ ,r) => a + !/5/.test(r + debut)
     ,0)

Concours MPO105

C.Ret a organisé un petit MPO (Misez p’tit Optimisez) dont vous trouverez l’énoncé ici.

Il fallait déjà remarquer que :

eq1

La difficulté n’était donc pas tant au niveau de la programmation mais plutôt de trouver une machine ancienne, avec peu de pas de programme, suffisamment rapide et de créer un programme court avec un minimum de variables…

Voici les explications concernant le programme que j’ai proposé pour la calculatrice Radio Shack EC-4001 (Clone américain du Sinclair Cambridge Programmable de 1977) :

Le programme ci-dessous calcule la racine carrée du nombre voulu (4, 64, 169…) moins un.

1 F 3 1 -

Etapes en vidéo pour entrer le programme avec l’émulateur.

Signification :

  • 1 → Touche racine carrée (en mode programmation, les touches correspondent aux fonctions (7 → sin, 8 → cos etc.)
  • F → Moins (on voit le F en bleu sur le clavier)
  • 3 → # pour préciser que l’on va entrer un nombre
  • 1 → Le chiffre 1 (il faut donc 2 pas pour entrer ‘1’ )
  • – → “=” (le “-” en bleu, à ne pas confondre avec la touche “-”  !)

Erreur de 1/1000 pour la valeur 26553409

5152

J’ai également proposé une autre solution en utilisant une calculatrice financière non programmable en remarquant que la formule pour les intérêts composés est :

eq2

Donc, en prenant n = 2 et PV = 1, on obtient :

CodeCogsEqn

qui est exactement la formule que l’on cherche à programmer. Voici ce que cela donne par exemple sur une HP 10bII une fois que l’on a initialisé la machine par C ALL (Effacer les mémoires), 2 n, 1 +/- PV. Remarquez que les résultats sont multipliés par 100 car la machine affiche la valeur finale en %. Ainsi 18 100 correspond par exemple à 181.

Recherche de calculatrices

Bonjour à tous,

Comme vous avez pu le constater je fais régulièrement des vidéos sur des calculatrices anciennes (généralement des programmables). Si vous en avez à me proposer (en don ou à me vendre), n’hésitez pas à me contacter à cette adresse : schraf @ univ-angers . fr

Un petit aperçu de ma collection de Texas Instrument :

Collection

ti2

Mes énigmes Facebook

J’ai posté plusieurs énigmes sur le groupe Facebook Casse-tête, énigmes et paradoxes, suite aux remarques des membres, j’ai modifié quelques énoncés et vous en propose ici une version en PDF imprimable.

Vous trouverez une partie des solutions expliquées en vidéo ici :

Mes 6 énigmes proposées sur un groupe Facebook (Partie 1)
6 nouvelles énigmes proposées sur un groupe Facebook (Partie 2)
Petites énigmes mathématiques à programmer (avec solutions)