IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

[Ludique] Défis code en un tweet


Sujet :

JavaScript

  1. #1
    Rédacteur/Modérateur

    Avatar de SylvainPV
    Profil pro
    Inscrit en
    Novembre 2012
    Messages
    3 375
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2012
    Messages : 3 375
    Points : 9 944
    Points
    9 944
    Par défaut [Ludique] Défis code en un tweet
    Salut les codeurs,

    Pour changer un peu des ordinaires questions/réponses aux débutants, je propose aux ninjavascript un petit challenge ludique: celui d'écrire une fonction avec un code suffisamment court pour rentrer dans un tweet, c'est à dire <= 140 caractères. Ce petit défi est inspiré de ce site : http://www.140byt.es/ ; vous pouvez vous en inspirer pour trouver des pistes pour réduire la taille de votre code. Une fois n'est pas coutume, ce défi n'a pas d'intérêt pratique si ce n'est vous apprendre à manier les notations alambiquées et assemblages subtils du Javascript minifié. Et puis, pour le fun

    Je vous donnerais régulièrement de nouveaux objectifs à réaliser par cette fonction, dès lors que plus personne n'aura trouvé le moyen de réduire le code de la précédente. Je suis aussi ouvert à toute suggestion de fonction à réaliser par message privé, si quelqu'un a une bonne idée.

    En voici les règles :
    • le code sera inséré et testé sous cette forme:
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      (function maFonction(){
      // votre code ici
      })()
      Seule la partie interne est comptée pour la limite des 140 caractères. Votre code devra comprendre une instruction return pour renvoyer le résultat désiré de la fonction
    • aucune librairie externe n'est permise (de toute façon elle ne rentrerait pas en 140 caractères)
    • la fonction doit renvoyer le résultat escompté avec les dernières versions des navigateurs Firefox et Chrome. Je vous fais grâce de IE
    • le code doit être suffisamment performant pour renvoyer le résultat en moins de cinq secondes sur un ordinateur de moyenne gamme
    • il n'y a aucune exigence particulière en matières de bonnes pratiques d'écriture de code : variables globales, conditions ternaires, opérateurs logiques à tout va... vous pouvez vous lâcher !

    Comme premier défi, je vous propose d'écrire une fonction qui renverra le prochain vendredi 13 du mois à arriver. Incontournable pour les superstitieux, vous pourrez l'exposer sur votre site Internet à côté de votre compteur d'apocalypse maya qui vend beaucoup moins de rêve depuis son passage dans les négatifs. Je vous laisse la liberté du format du résultat de la fonction, du moment que l'on dispose des deux informations essentielles : le mois et l'année du prochain jour fatidique.

    N'hésitez pas à poster vos propositions même au delà de 140 caractères, ou à challenger les propositions des autres. Bonne chasse aux caractères

  2. #2
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 120
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 120
    Points : 44 910
    Points
    44 910
    Par défaut
    Bonjour,
    après avoir cherché à augmenter la taille des JS tu veux la réduire

    Je ne saisie pas pourquoi cette forme de déclaration pour la fonction de test.

    Voici ma proposition, le code de la fonction fait 109 caractères, donc dans les clous.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    function getNextVendredi13(){
    d=new Date();d.setDate(13);m=d.getMonth();while(d.getDay()!=5){d.setMonth(++m);}return{m:m,y:d.getFullYear()}
    }
    Je ne sais pas si cela répond au cahier des charge, toujours est-il que la fonction retourne un objet avec m pour le mois, au format Date soit le mois -1, et y pour l'année.

  3. #3
    Membre expert
    Avatar de Sunchaser
    Homme Profil pro
    OPNI (Objet Programmant Non Identifié)
    Inscrit en
    Décembre 2004
    Messages
    2 059
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : OPNI (Objet Programmant Non Identifié)
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 059
    Points : 3 204
    Points
    3 204
    Par défaut
    Bonsoir,
    En reprennant le "format" de NoSmoking, de mon côté j'avais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    function getNextVendredi13(){
    f=new Date();m=f.getMonth();y=f.getFullYear();do{t=new Date(y,m,13);if(t.getDay()==5){f=null;return t}if(m==11){m=0;y+=1}else m+=1}while(f)
    };
    139 chars, si je compte bien.
    Décidemment, je suis trop "bavard".
    J'avais un petit peu plus court et fainéant sur le départ, mais ca supposait de considérer qu'on partait de manière "statique" de Juillet 2013 au lieu de "sysdate".
    J'ai pas osé, bien que cela n'était pas spécifié.

    @+

  4. #4
    Rédacteur/Modérateur

    Avatar de SylvainPV
    Profil pro
    Inscrit en
    Novembre 2012
    Messages
    3 375
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2012
    Messages : 3 375
    Points : 9 944
    Points
    9 944
    Par défaut
    @NoSmoking: c'est la même forme de déclaration que toi, c'est juste qu'elle est auto-exécutée. De cette manière c'est plus pratique pour tester et ça me laisse la possibilité de passer des arguments en entrée si j'en ai besoin sur d'autres problèmes. Bien joué pour ta solution, 109 caractères c'est pas mal du tout. Mais on peut descendre bien plus bas Un indice: naviguer entre valeurs UTC est plus simple que naviguer entre les mois.

    @Sunchaser: Non, on ne part d'aucun argument en entrée, il faut donc récupérer la date d'aujourd'hui via le constructeur Date comme tu l'as fait. Quelques petits conseils pour réduire ton code :
    - l'opérateur ++ est plus court que d'écrire +=1
    - la double do..while peut être écrite de manière plus courte en un simple while
    - les conditions if..else peuvent être écrire de manière plus courte via des conditions ternaires ? : ou des opérateurs logiques || && ou binaires.
    - f=new Date; suffit pour récupérer la date d'aujourd'hui

  5. #5
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 120
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 120
    Points : 44 910
    Points
    44 910
    Par défaut
    celui d'écrire une fonction avec un code suffisamment court pour rentrer dans un tweet, c'est à dire <= 140 caractères
    j'ai même un ; en trop, je ramène donc à 108 caractères
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    function getNextVendredi13(){
    d=new Date();d.setDate(13);m=d.getMonth();while(d.getDay()!=5){d.setMonth(++m)}return{m:m,y:d.getFullYear()}
    }
    ...dès lors que plus personne n'aura trouvé le moyen de réduire le code de la précédente
    je ne veux pas tuer le défi trop vite

  6. #6
    Rédacteur/Modérateur

    Avatar de SylvainPV
    Profil pro
    Inscrit en
    Novembre 2012
    Messages
    3 375
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2012
    Messages : 3 375
    Points : 9 944
    Points
    9 944
    Par défaut
    D'ailleurs j'aurais accepté :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    (function getNextVendredi13(){
    d=new Date();d.setDate(13);m=d.getMonth();while(d.getDay()!=5){d.setMonth(++m)}return d
    })()
    puisqu'on a toutes les infos attendues en sortie.
    Ce qui porte à 87 caractères ! Pas mal, pas mal ! Pour ma part, voici le plus court que j'ai trouvé:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    (function getNextVendredi13(){
    for(d=new Date;(d=new Date(+d+8e7)).getDay()*d.getDate()!=65;);return d
    })()
    8e7 est en notation exponentielle un intervalle en millisecondes juste en dessous des 24 heures. Je teste le produit 13*5=65 car par chance il s'agit d'une décomposition en facteurs premiers, et comme il n'y a pas 13 jours dans la semaine le cas est unique. Cela nous donne 71 caractères. Qui dit mieux ?

  7. #7
    Membre actif
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    128
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 128
    Points : 210
    Points
    210
    Par défaut
    J'adore le code golf !

    79 caractères, en repartant de la version de NoSmoking :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    function getNextVendredi13(){
    for(d=new Date,d.setDate(13);d.getDay()!=5;d.setMonth(d.getMonth()+1));return d
    }
    EDIT : SylvainPV m'a tuer

  8. #8
    Rédacteur/Modérateur

    Avatar de SylvainPV
    Profil pro
    Inscrit en
    Novembre 2012
    Messages
    3 375
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2012
    Messages : 3 375
    Points : 9 944
    Points
    9 944
    Par défaut
    Bien tenté
    Par contre je pense qu'il y a un souci avec la version setMonth. Supposons que nous sommes le samedi 14 septembre 2013, la fonction getNextVendredi13 renverra le vendredi 13 septembre. Or ce n'est pas le prochain

  9. #9
    Membre actif
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    128
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 128
    Points : 210
    Points
    210
    Par défaut
    Bien vu, du coup toutes les solutions proposées (sauf la tienne) sont fausses.
    Il faudrait vérifier que (d.getDay == 5 && d.getTime() > now.getTime()).

    Par contre que se passe t'il si on est vendredi 13 ?
    Ta solution renvois le jour courant et non le prochain vendredi 13.
    La formulation "le prochain vendredi 13 du mois à arriver" est un peu ambigüe sur les cas limites.
    De la même manière si je suis jeudi 12, dois-je renvoyer le lendemain ou le vendredi 13 d'un mois dans le futur (l'énoncé dit "du mois à arriver") ?

    PS : du coup je pense qu'on peut passer à un autre défi, je doute franchement qu'il y ai une solution plus optimale que la tienne.

  10. #10
    Membre émérite
    Avatar de Kaamo
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    1 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 165
    Points : 2 778
    Points
    2 778
    Par défaut
    Wouhouuuu il remet ça
    Ce site est très intéressant pour apprendre des nouvelles techniques. J'avais vu passer un tetris codé dans cette taille, c'est impressionnant ! D'ailleurs, l'un des leaders de 140byt.es est le créateur de JSFuck, ça annonce la couleur

    Sinon on peut partir de ce postulat : Un mois avec un vendredi 13 commence forcément par un dimanche. Pas eu le temps de me pencher sur le code, mais à priori, ça fera plus !

    Par contre que se passe t'il si on est vendredi 13 ?
    Vu le code de Sylvain, la date du jour est exclue, donc si on est vendredi 13, ce n'est pas celui-ci qu'il faut retourner

  11. #11
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 120
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 120
    Points : 44 910
    Points
    44 910
    Par défaut
    Bien vu, du coup toutes les solutions proposées (sauf la tienne) sont fausses.
    me..e cela je l'avais vu mais j'ai oublié le report

    Du coup je remonte à 119 caractères
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    function getNextVendredi13(){
    d=new Date;m=d.getMonth();d.getDate()>13? d.setMonth(m+1):0;d.setDate(13);while(d.getDay()!=5){d.setMonth(++m)}return d
    }
    par contre
    Ta solution renvois le jour courant et non le prochain vendredi 13.
    cela reste vrai pour moi aussi!

  12. #12
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 120
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 120
    Points : 44 910
    Points
    44 910
    Par défaut
    Citation Envoyé par Kaamo
    Un mois avec un vendredi 13 commence forcément par un dimanche.
    j'aime bien cette approche également.

  13. #13
    Membre émérite
    Avatar de Kaamo
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    1 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 165
    Points : 2 778
    Points
    2 778
    Par défaut
    ça revient au même que ta solution à vue de nez, sauf qu'il faut faire un setDate(1) et faire le test d.getDay()!=0.
    Incrémenter jour par jour comme Sylvain l'a fait me parait être la meilleure soluce

    EDIT : on peut gratter un caractère sur le script de Sylvain
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    (function getNextVendredi13(){
    for(d=new Date;d.getDay()*d.getDate()!=65;d=new Date(+d+8e7));return d
    })()

  14. #14
    Rédacteur/Modérateur

    Avatar de SylvainPV
    Profil pro
    Inscrit en
    Novembre 2012
    Messages
    3 375
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2012
    Messages : 3 375
    Points : 9 944
    Points
    9 944
    Par défaut
    Haha bien vu, on arrive à 70 caractères. Chapeau bas, ça rentre dans une moitié de tweet

    La piste du dimanche 1er est intéressante, d'autant que le dimanche est à l'index zéro au getDay, ce qui permet un raccourci de code en l'interprétant comme booléen. le setMonth est trop long à écrire, on peut peut-être incrémenter numériquement comme j'ai fait mais comment gérer les mois de 30 et 31 jours ? Sans parler de Février...

    S'il n'y a pas d'autre idée lumineuse d'ici ce soir, je posterais un nouvel énoncé

    EDIT: j'ai finalement trouvé comment économiser 2 caractères avec la piste de Kamao :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    (function getNextVendredi13(){
    for(d=new Date;d.getDay()+d.getDate()>1;d=new Date(+d+8e7));return d
    })()
    Alors okay, ça ne renvoie pas la date du vendredi 13 mais le premier du mois où on trouve le prochain vendredi 13. Si on s'en tient à l'énoncé, avoir l'info du mois et de l'année peu importe le format de réponse, on est border-line

  15. #15
    Membre émérite
    Avatar de Kaamo
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    1 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 165
    Points : 2 778
    Points
    2 778
    Par défaut


    on peut peut-être incrémenter numériquement comme j'ai fait mais comment gérer les mois de 30 et 31 jours ? Sans parler de Février...
    C'est exactement sur quoi j'ai coincé !
    Pour positionner au 1er du mois de sysdate : setDate(1); et pour positionner au 1er du mois suivant de sysdate : setDate(1+X);X est le nombre de jours du mois.

    Du coup, ça fonctionne en incrémentant le mois (méthode NoSmoking)
    Mais il y a toujours le problème du check du jour sur lequel on se trouve ! Si je suis avant le 13, je check le 1er jour du mois de sysdate. Si j'ai passé le 13, je me positionne sur le 1er jour du mois suivant. Et ça, c'est gourmand

    109 caractères, par rapport à celle de NoSmoking, on peut enlever l'opérateur ternaire et la condition du while se simplifie, un ptit espace + accolade en trop :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    (function getNextVendredi13(){
    d=new Date,m=d.getMonth();d.setMonth(m+d.getDate()>13);d.setDate(1);while(d.getDay())d.setMonth(++m);return d
    })()

  16. #16
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 120
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 120
    Points : 44 910
    Points
    44 910
    Par défaut
    Même si celle de Sylvain est très gourmande en itération elle reste la plus aboutie, chapeau bas donc.

    Je n'aurais qu'une question, que va tu faire des 72 caractères gagnés, les reporter sur le prochain test

    S'il n'y a pas d'autre idée lumineuse d'ici ce soir, je posterais un nouvel énoncé
    Ca sent les vacances pour certains, ou encore la baisse d'activités

  17. #17
    Rédacteur/Modérateur

    Avatar de SylvainPV
    Profil pro
    Inscrit en
    Novembre 2012
    Messages
    3 375
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2012
    Messages : 3 375
    Points : 9 944
    Points
    9 944
    Par défaut
    Haha je ne sais pas, on peut compter les scores si ça vous amuse. Mais bon ce n'est pas un concours, plus une collaboration

    Bon, nouvel énoncé :
    Numéro 2 : une fonction qui convertit une suite de chiffres écrits en toutes lettres en français (de zéro à neuf) en leur équivalent numérique.
    Voilà le code de test:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    (function parseNumbers(s){
    //votre code ici; retour attendu : la String "1234567890"
    })("un deux trois quatre cinq six sept huit neuf zero");

  18. #18
    Membre actif
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    128
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 128
    Points : 210
    Points
    210
    Par défaut
    Juste les chiffres, pas les nombres ?

  19. #19
    Membre actif
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    128
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 128
    Points : 210
    Points
    210
    Par défaut
    99 caractères :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    (function parseNumbers(s){
    return s.replace(/ ?(s?.)\S*/g,function(a,b){return{z:0,u:1,d:2,t:3,q:4,c:5,si:6,se:7,h:8,n:9}[b]})
    })("un deux trois quatre cinq six sept huit neuf zero");

  20. #20
    Rédacteur/Modérateur

    Avatar de SylvainPV
    Profil pro
    Inscrit en
    Novembre 2012
    Messages
    3 375
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2012
    Messages : 3 375
    Points : 9 944
    Points
    9 944
    Par défaut
    Déjà très joli Je crois aussi que les RegExp sont la meilleure option, mais sait-on jamais je creuse quelques pistes du côté des Array

Discussions similaires

  1. Défi : Toutes les semaines un peu de code pour aller plus loin avec Windows 7
    Par Jérôme Lambert dans le forum Développement Windows
    Réponses: 41
    Dernier message: 05/01/2012, 12h00
  2. [Ludique] Mini-jeu : épisode 3 (déchiffrage de code, niveau : facile)
    Par RomainVALERI dans le forum Général JavaScript
    Réponses: 17
    Dernier message: 03/11/2010, 00h45
  3. [Ludique] Mini-jeu - niveau 2 : déchiffrage de code (niveau modéré)
    Par RomainVALERI dans le forum Général JavaScript
    Réponses: 13
    Dernier message: 28/07/2010, 23h15
  4. [Ludique] Mini-jeu : déchiffrage de code (niveau facile)
    Par RomainVALERI dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 13/07/2010, 18h24

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo