Développement applicatif

Retour d’expérience : concours salaire-in-game

Publié le 04/01/2022 Par Didier ANDERSEN

Didier Andersen, consultant chez Meritis dévoile les coulisses du concours salaire in Game. Découvrez ses méthodes de calcul et explications.

J’ai eu l’occasion de participer au concours de développement salaire-in-game (proposé par Expectra de Randstad). J’aime résoudre des problèmes et me mesurer aux autres. Pour moi, cette expérience est vraiment enrichissante et gratifiante. Ce concours est une compétition de vitesse : celui ou celle qui donne le résultat le plus tôt gagne la compétition.  Je vous propose dans cet article de revivre cet évènement à travers mon ressenti plutôt que via une résolution optimisée des exercices. N’hésitez pas à commenter, à partager vos remarques, à discuter ou à proposer des solutions (tous langages confondus).

Chez Meritis, au sein de la communauté Captcha (mené par Gaëtan Eleouet), nous participons régulièrement à ce type d’évènement. Nous nous retrouvons toutes les deux semaines pour suivre l’actualité des concours, poser des problèmes et les résoudre ensemble. Pour ma part, je résous les exercices en java mais les concours sont « multilangages ».

Comme il est toujours plus convivial et motivant de faire les concours à plusieurs, nous nous sommes synchronisés avec Gaëtan pour faire celui-ci en même temps.

Problème 1 : dénombrement de points

Problème 1 : dénombrement de points du concour salair in game 2020

Après analyse du sujet, l’exercice consiste à compter le nombre de points dans un grillage carré à l’intérieur d’un cercle. Il ne faut pas oublier de compter le point central du cercle et les points sur le cercle.

Sachant que le rayon du cercle est de 5 000 m et que le quadrillage est de 10 m, nous pouvons diviser toutes les distances par 10.

La méthode de calcul

méthode de calcul du problème 1 du concour salaire in game 2020

Pour rappel : la distance d’un point (x1,y1) au centre du cercle (0,0) est la racine carrée de (x12+y12), c’est à dire un calcul d’hypoténuse.

Pour résoudre le problème, je découpe le problème en 4 et je traite le problème sur un quart de cercle.

La solution sera la somme :

4*[nombre de points dans un quart de cercle] + 4*[nombre de points sur un rayon] + le point central.

Ce qui revient à :

4*[nombre de points dans un quart de cercle] + 4*500+1

Mon algorithme se décompose en plusieurs étapes :

  • Simulation des points sur un carré de 600 m (plus de points que nécessaire).
  • Parcours des points dans le carré sans compter les points des bords (x=0 et y=0) pour ne pas les compter plusieurs fois lors du calcul final (comme on a découpé l’exercice en 4).
  • Calculer la distance entre les points (ce qui fait apparaître une racine carrée et donc des nombres décimaux), puis on compte uniquement les points recherchés.
méthode de calcul 1

La console affiche alors la valeur 195 837.

Par conséquent, le calcul final est donc 4*195837 + 4*500 + 1= 785 349. Et hop exercice réussi.

Le débrief

Pendant le débrief post-challenge (lors de la réunion de la communauté Captcha), nous avons conclu que l’exercice pouvait être fait plus simplement :

  • Au lieu de simuler puis de parcourir les points, nous nous sommes rendu compte qu’il était possible de faire les deux en même temps.
  • Le nombre de points est limité (< 1 000 000), nous pouvons donc simuler tout le problème au lieu de le couper en 4, et nous affranchir du calcul final.
  • Enfin, nous aurions également pu nous affranchir des nombres décimaux, en comparant les distances au carré.
formule 1 - vérsion améliorée

Problème 2 : décodage via un hachage inversé

égigme 2 sur 5 du salair in game 2020

L’exercice nous demande de déchiffrer un message. Le message a été encodé via un algorithme de hachage 256. Lors d’une précédente réunion, nous avions vu un exercice de collision de hachage java, c’est à dire que deux messages différents donnent le même message encodé via le hachage java.

Je demande donc à Gaëtan s’il s’agit du même algorithme de hachage. Il m’informe que non, ce n’est pas le même hachage, et qu’il vient de finir l’exercice avec un temps de calcul de 20 minutes.

Je ne me décourage pas et je cherche sur internet comment est implémenté le hash SHA256. Et je suis tombé sur ce site : Baeldung.com.

équation 2

La méthode de calcul

Maintenant que je suis capable d’encoder un message, je vais essayer toutes les possibilités, communément appelées « brute force ».

Je commence par mettre en place un « builder » qui va permettre de lister toutes les possibilités, avec toutes les conditions. Je gère les exceptions avec des try-catch. Puis je rajoute dans la boucle une méthode resolve qui va calculer le hash et le comparer avec le résultat souhaité :

formule 2

Le calcul est assez rapide (quelques secondes). L’exercice est résolu avec comme réponse « 17/3@1630,-4890 ».

Le débrief

Conclusion du débrief post-challenge : cet exercice n’a pas d’astuce en particulier. Il faut bien lire l’énoncé et vérifier toutes les conditions afin de réduire au maximum le scope de la « brute force » car oublier une condition coûte très cher en temps de calcul.

Problème 3 : nombre d’occurrences d’un caractère

énigme 3 sur 5 - salaire in game 2020

L’exercice nous demande de prendre le caractère qui revient le plus souvent à une position donnée. À première vue, pas de difficulté particulière. J’ai eu un bon fou rire en comprenant que les données d’entrées du problème étaient disponibles sur le lien Wikipédia. Pour la petite anecdote, je pensais que le résultat devait être dans le tableau… J’ai donc perdu quelques précieuses minutes sur la fin de l’exercice.

La méthode de calcul

Je commence par récupérer les données : copier-coller, Excel, Notepad++ en mode édition multiligne, et voilà une belle liste en java dans une méthode dédiée.

Je pars sur une solution itérative consistant à enlever les caractères déjà traités et à les compter dans une map clé-valeur, la clé étant le caractère et la valeur son nombre d’occurrences.

Mon algorithme se décompose de la manière suivante :

  • Pour chaque élément de la liste, j’extrais le premier caractère et j’ajoute 1 au compteur de ce caractère (sous forme d’une map).
  • Je stocke la chaîne de caractères sans son premier caractère dans une autre liste.
  • Une fois la liste parcourue, je regarde la plus grande valeur dans la map, et j’en détermine le caractère qui apparaît le plus grand nombre de fois.
  • Je recommence le processus avec l’autre liste, celle sans les premiers caractères, comme input.
  • Certains éléments ayant moins de 11 lettres, je mets un try-catch afin de continuer le traitement sans eux.
formule énigme 3 sur 5 - salaire in game 2020

Voici la réponse obtenue : « Ieleiiaranen ». En route vers l’exercice 4.

Le débrief

Voici quelques idées émises pendant le débrief avec la communauté Captcha :

  • Avec Notepad, il est possible de tronquer tous les noms à la même taille.
  • Au lieu de recréer une liste à chaque itération, je pouvais faire appel à la méthode String.charAt() pour récupérer l’élément à la position souhaitée.
  • Il est possible de stocker 11 map (dans une liste pour itérer) et de ne réaliser qu’un seul parcours du tableau de médicament.

Voici un algorithme qui prend en compte toutes ces remarques :

détail formule énigme 3 sur 5 - salaire in game 2020

Problème 4 : automate de Wolfram

énigme 4 sur 5 - salaire in game 2020

Ici, l’exercice consiste à trouver un état particulier (au moins 15 zéros d’affilée) à partir d’un état initial et en appliquant un automate de Wolfram de règle 110.

Je ne connais pas les automates de Wolfram, et je ne les comprends pas en lisant le lien wiki de l’énoncé. Du coup, je ressens une grosse perte de confiance en moi. Je transmets ma panique à mon teammate. Il m’affirme alors qu’il y a un schéma animé très explicatif sur le wiki via le lien suivant : https://en.wikipedia.org/wiki/File:One-d-cellular-automaton-rule-110.gif

D’après ce schéma, on détermine la valeur à la position j du nouvel état en convertissant la chaîne composée des 3 éléments successifs (j-1, j et j+1) de l’état précédent. Les 8 conversions sont données. Un point d’attention est levé pour la détermination du premier et du dernier élément. En effet, pour déterminer le premier élément, on utilise le dernier et vice versa.

La méthode de calcul

Pour la résolution, j’utilise une récursion : je calcule l’état suivant et je vérifie si l’exercice est résolu. Si oui, j’écris le résultat et je sors, sinon je recommence.

formule énigme 4 sur 5 - salaire in game 2020

La solution obtenue : 01110001100101111101111100000000000000001001100000.

Exercice résolu ! Pendant ce temps, mon teammate a fini le dernier exercice. Je partage mon écran et j’ai le droit à une session de live-coaching.

Le débrief

En y repensant a posteriori, une approche itérative est meilleure qu’une approche récursive sur cet exercice. En effet, avec du récursif, j’aurais pu risquer une exception de type stackOverFlow.

Problème 5 : dénombrement des victoires d’un duel

énigme  5 - salaire in game 2020

Dans cette énigme, il faut compter tous les combats gagnés modulo 109. Le combat ne se déroule pas en tour par tour (possibilité d’attaquer plusieurs fois de suite). La solution est donc plus simple à implémenter (pas besoin de se souvenir de qui a joué le tour d’avant), mais le nombre de combats possible est bien plus important.

Le modulo 10^9 suggère qu’il faut éviter une brute force et essayer de réutiliser des calculs précédents. La fatigue se fait sentir, j’ai du mal à voir comment résoudre l’exercice. Gaëtan me rappelle que ce type d’exercice a été vu lors d’une précédente réunion de la communauté Captcha.

Récapitulons : nombre de possibilités avec un modulo… Mais oui, la programmation dynamique (pour vulgariser, de la récursion avec une mémoire) ! Nous avions traité l’exercice de l’escalier, à savoir combien de possibilités pour monter un escalier.

La méthode de calcul

Je mets donc un algorithme bottom-up, c’est-à-dire une récursion (avec mémoire), en partant de l’état initial (en opposition à l’algorithme top down, où l’on part de l’état final).

La récursion va prendre en entrée l’état de santé des deux participants.

Je commence par les conditions d’arrêt de la récursion : les points de vie des participants :

formule énigme  5 - salaire in game 2020

Ensuite, je détermine tous les états possibles et j’applique la récursion sur chacun d’eux :

suite formule énigme  5 - salaire in game 2020

qu’un entier java (32bit), il repart à la valeur minimale à chaque fois qu’il dépasse la valeur maximale. Il vaut mieux le déclarer en Long (64bit). Pas de chance, le résultat est toujours incohérent, le chiffre est trop grand.

C’est à ce moment que je me souviens que l’énoncé demande un modulo. Sachant que le modulo d’une somme est la somme des modulos (distributivité des congruences), j’ajoute donc le modulo à chaque étape.

suite formule énigme  5 - salaire in game 2020 suite 2

La réponse obtenue est 992505663.

Le débrief

Il est possible de passer en BigInteger afin d’avoir le nombre exact de possibilités (102033940458046779283026415918520992505663).

Il est aussi possible de parcourir les possibilités en top down (partir d’une victoire pour remonter au 100 PV), mais cette solution est plus complexe dans ce cas-ci.

La compétition est finie en un peu plus de 2h. 😀 Je suis fatigué mais très content d’avoir réussi tous les exercices. Les réunions / discussions au sein de notre communauté m’ont permis de beaucoup progresser. Je manque encore de pratique pour trouver le bon algorithme et de rapidité. À force de participer, je compte bien réussir de mieux en mieux. Je vous donne rendez-vous pour les prochaines compétitions et corrections.


Vous avez aimé cet article ? Partagez-le et laissez vos commentaires 😉

bannière Meritis

Pas encore de commentaires

Publier un commentaire

Didier Andersen

Auteur

Didier ANDERSEN

Diplômé de L'ENSEM de Nancy, Didier intervient sur le développement, la maintenance et l'évolution d'applications en langage Java destinées aux départements métier des banques de Financement et d'investissement.
Il est passionné par les énigmes et les Casse-Tête et n'hésite pas à participer aux concours de développement aux côtés de Meritis et de la communauté Captcha.

Découvrir ses autres articles

Pas d'autres articles publiés par cet auteur pour le moment