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. #241
    Membre averti Avatar de regseb
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2013
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2013
    Messages : 16
    Par défaut
    En me basant sur le script de Suppression d'une lettre dans une page WEB de NoSmoking, j'arrive à 119 caractères (testé seulement sous Firefox).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    (function(n,l){
    c='childNodes';d='data';if(n.nodeType==3)n[d]=n[d].split(l).join('');for(var i=0;n[c][i];)arguments.callee(n[c][i++],l)
    })(document.body, 'e'); // e est la lettre a supprimer.
    Voici comment j'ai diminué la taille de la ligne (le nombre de caractères est entre parenthèses) :
    • supprimer if(n[t]==1), la condition du for est suffisante (11) ;
    • utiliser directement le nodeType (7);
    • utiliser la méthode arguments.callee pour la récursivité (2);
    • déplacer le ++i (1).

  2. #242
    Membre Expert
    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 : 38
    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
    Par défaut
    Tiens, j'étais passé à côté de ce script. Bien vu pour le callee !

    - Pour éviter d'avoir à écrire var pour déclarer le i dans le scope de la fonction, il suffit de l'inclure dans les paramètres de la fonction. Ainsi, pas de Global Leak et du coup le i est local à chaque récursion.
    - Aussi, le d='data' semble être un mauvais raccourci. Vu qu'il n'est appelé que deux fois, c'est plus avantageux de l'écrire carrément plutôt que de passer par un alias.
    - Déclarer c=childNodes là où on se sert de c pour la première fois histoire de gagner 2 car encore
    - écrire if(n.nodeType==3) en forme ternaire. C'est plus court, même avec le else (:) et en plus ça permet de déclarer le i=0 à cet endroit ce qui fait encore économiser

    105 donc après ces modifs :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    (function(n,l,i,c){
    for(n.data=n.nodeType==3?n.data.split(l).join(''):i=0;n[c='childNodes'][i];)arguments.callee(n[c][i++],l)
    })(document.body, 'e'); // e est la lettre a supprimer.

  3. #243
    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
    Par défaut
    Cool un up

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    (function(d,l){
    w=d.createTreeWalker(d.body,4);while(n=w.nextNode())n.data=n.data.split(l).join('')
    })(document, 'e'); // e est la lettre a supprimer.
    83 caractères, si vous me permettez de remplacer document.body par document dans les arguments

  4. #244
    Membre Expert
    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 : 38
    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
    Par défaut
    Aie

  5. #245
    Membre éclairé

    Femme Profil pro
    Experte JS / Conseillère en best practices / Chercheuse en programmation
    Inscrit en
    Octobre 2007
    Messages
    741
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Experte JS / Conseillère en best practices / Chercheuse en programmation
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Octobre 2007
    Messages : 741
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    (function(d,e){
    w=d.createTreeWalker(d.body,4);while(n=w.nextNode())n.data=n.data.replace(e,'')
    })(document, /e/gi); // e est la lettre a supprimer.
    80 insensitive ^^'

    EDIT: en modifiant la RegExp, on peut même en faire un tweet de 0

    /[\w\d\.()=;,'{}/]/gi

  6. #246
    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
    Par défaut
    Ca ne remplace pas toutes les occurences, il manque le flag global J'avais déjà essayé cette piste
    Et je n'ai rien compris à l'histoire du tweet de zéro

  7. #247
    Membre averti Avatar de regseb
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2013
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2013
    Messages : 16
    Par défaut
    @Kaamo
    On peut aller à 91 caractères en remplaçant le for par un for of (expérimental). Je n'ai pas réussi à bien replacer l'opérateur ternaire, j'ai donc meublé le else avec 0.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    (function(n,l){
    n.data=n.nodeType==3?n.data.split(l).join(''):0;for(i of n.childNodes)arguments.callee(i,l)
    })(document.body, 'e'); // e est la lettre a supprimer.
    @SylvainPV
    En remplaçant le document.body par document, la méthode supprime une lettre de toute la page. Alors qu'avant, on pouvait choisir dans quel élément on supprimait la lettre.
    Si tu utilises un for à la place du while, tu gagnes 1 caractère pour arriver à 84.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    (function(n,l){
    for(w=document.createTreeWalker(n,4);d=w.nextNode();)d.data=d.data.split(l).join('')
    })(document.body, 'e'); // e est la lettre a supprimer.
    @Lcf.vs
    Le replace remplace toutes les occurrences, mais c'est grâce à l'expression régulière que tu as déclaré en dehors de la fonction.

  8. #248
    Membre éclairé

    Femme Profil pro
    Experte JS / Conseillère en best practices / Chercheuse en programmation
    Inscrit en
    Octobre 2007
    Messages
    741
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Experte JS / Conseillère en best practices / Chercheuse en programmation
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Octobre 2007
    Messages : 741
    Par défaut
    Citation Envoyé par SylvainPV Voir le message
    Ca ne remplace pas toutes les occurences, il manque le flag global J'avais déjà essayé cette piste
    Si, si, il y a bien le g... ^^'

    Citation Envoyé par SylvainPV Voir le message
    Et je n'ai rien compris à l'histoire du tweet de zéro
    C'était une plaisanterie, car si tu l'appliques sur cette page, mon Tweet code est vide

    Citation Envoyé par regseb Voir le message
    @Lcf.vs
    Le replace remplace toutes les occurrences, mais c'est grâce à l'expression régulière que tu as déclaré en dehors de la fonction.
    Que je sache, ce n'était pas interdit... de plus, passer une RegExp String plutôt qu'une simple String est plus précis... on peut définir des conditions de remplacement plus strictes, sans rien changer au Tweet code.

    Enfin, mélanger de l'expérimental (for... of) et du déprécié (arguments.callee)...

  9. #249
    Membre Expert
    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 : 38
    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
    Par défaut
    Enfin, mélanger de l'expérimental (for... of) et du déprécié (arguments.callee)...
    Héhé c'est ce qui fait la magie ! Mais on est limité par une règle (du 1er post) :
    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
    for ... of n'est pas encore supporté par Chrome, c'est une bonne idée sinon

  10. #250
    Membre éclairé

    Femme Profil pro
    Experte JS / Conseillère en best practices / Chercheuse en programmation
    Inscrit en
    Octobre 2007
    Messages
    741
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Experte JS / Conseillère en best practices / Chercheuse en programmation
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Octobre 2007
    Messages : 741
    Par défaut
    Allez, histoire de donner un peu de vie à ce topic sympa...

    Selon les mêmes règles que précédemment, je vous propose de plancher sur un benchmark le plus précis possible...

    Contraintes :

    • Le premier argument est la fonction à benchmarker
    • Le deuxième argument est la durée minimale du test (en millisecondes)
    • La valeur de retour, un float, doit indiquer la durée moyenne d'exécution de la fonction passée en argument (en millisecondes, précision maximale -> toFixed(18))


    Voici ma version :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    (function (f,d) {
    D=Date,s=+new D,e=+new D,c=0,function b(){f();l=+new D;s+d>l?b(c++):0}();return+((l-s-(e-s)*c)/c).toFixed(18)
    }(function () {}, 1000));

  11. #251
    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
    Par défaut
    Ça va être délicat pour tester l'exactitude de ce genre de fonctions... Soustraire deux dates n'est pas aussi rigoureux que d'autres fonctions conçues pour, comme console.time/timeEnd. Aussi, le toFixed(18) n'apporte pas de précision supplémentaire, il force juste le formattage avec un paquet de zéro derrière.

    Basiquement, avec la méthode de soustraction de dates on pourrait écrire quelque-chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    (function (f,n) {
    _=new Date;for(i=n;--i;f());return(+new Date-_)/n;
    }(function () { return Math.random(); }, 1e6));
    en moyennant sur un grand nombre d'itérations.

    Mais le plus simple et plus précis serait d'utiliser console.time, qui apporte une précision à 0.001 ms (en théorie bien sûr, j'ai des gros doutes sur la réalité de la chose)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    (function (f) {
        console.time("l");
        f();
        console.timeEnd("l");
    })(function () { 
       new Array(1e6).join('#').split('');
    })

  12. #252
    Membre éclairé

    Femme Profil pro
    Experte JS / Conseillère en best practices / Chercheuse en programmation
    Inscrit en
    Octobre 2007
    Messages
    741
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Experte JS / Conseillère en best practices / Chercheuse en programmation
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Octobre 2007
    Messages : 741
    Par défaut
    En fait, le toFixed() sert à avoir une division exacte, sinon, on tombe dans le classique soucis des décimaux en JS...

    Le 18, oui, il est peut-être abusif mais il fallait bien choisir une longueur et, 18, c'est la longueur maximale de décimales pour un nombre, en JS.

    Par contre, si tu essaie mon code, tu verras que tu obtiendras extrêmement rarement plein de 0.

    Utiliser des outils non-natifs, tel que console? zut, j'croyais qu'on faisait du vrai JS, ici. lol

    Après, en effet, j'aurais pu fixer un nombre d'itérations, plutôt qu'une durée minimale... mais ça aurait été moins drôle...

  13. #253
    Membre Expert
    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 : 38
    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
    Par défaut
    @Lcfvs : j'ai un beau InternalError: too much recursion (FF) ou encore un RangeError: Maximum call stack size exceeded (Chrome).

    Je crois que je n'ai pas une stack aussi grosse que la tienne

    Sinon pour revenir au sujet, les bons outils de benchmark utilisent, il me semble, window.performance :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    (function (f,n) {
    _=performance.now();for(i=n;--i;f());return(performance.now()-_)/n;
    }(function () { return Math.random(); }, 1e6));

  14. #254
    Membre éclairé

    Femme Profil pro
    Experte JS / Conseillère en best practices / Chercheuse en programmation
    Inscrit en
    Octobre 2007
    Messages
    741
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Experte JS / Conseillère en best practices / Chercheuse en programmation
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Octobre 2007
    Messages : 741
    Par défaut
    Citation Envoyé par Kaamo Voir le message
    @Lcfvs : j'ai un beau InternalError: too much recursion (FF) ou encore un RangeError: Maximum call stack size exceeded (Chrome).

    Je crois que je n'ai pas une stack aussi grosse que la tienne
    Hum... à mon avis, au vu du message d'erreur, l'explication, c'est que tu as une machine sacrément plus balèze que la mienne...

    Citation Envoyé par Kaamo Voir le message
    Sinon pour revenir au sujet, les bons outils de benchmark utilisent, il me semble, window.performance
    Cool, une API standard que je ne connaissais pas...

  15. #255
    Membre averti Avatar de regseb
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2013
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2013
    Messages : 16
    Par défaut
    Voici ma proposition pour le benchmark :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var sleep = function() {
        var start = Date.now();
        while (Date.now() - start < 10) ;
    }
     
    var time = (function (f,d) {
    n=Date.now;for(s=n(),c=0;(e=n()-s)<d;++c)f();return(e/c).toFixed(18)
    })(sleep, 1000);
     
    console.log(time);
    Je remplace new Date par Date.now() qui me fait gagner de la place pour arriver à 68 caractères.
    Par contre, le code ci-dessus affiche 10.000000000000000000. Donc soit le code nécessaire pour calculer le temps exécution dure moins de 1 ms ; soit un bogue s'est glissé dans le code.

  16. #256
    Membre Expert
    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 : 38
    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
    Par défaut
    Ah oui ? Je le comprends dans le sens où il y a trop de récursions à traiter pour ma bécane ... mais je réfléchis peut-être à l'envers

    C'est le moteur de benchmark de JSPerf, assez intéressant à lire, bien commenté.

    @regseb : J'ai eu 10.009999999999999787 .. mais c'est rare.

  17. #257
    Membre éclairé

    Femme Profil pro
    Experte JS / Conseillère en best practices / Chercheuse en programmation
    Inscrit en
    Octobre 2007
    Messages
    741
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Experte JS / Conseillère en best practices / Chercheuse en programmation
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Octobre 2007
    Messages : 741
    Par défaut
    Citation Envoyé par Kaamo Voir le message
    Ah oui ? Je le comprends dans le sens où il y a trop de récursions à traiter pour ma bécane ... mais je réfléchis peut-être à l'envers
    C'est logique, en fait... en un temps donné, si ta machine est plus puissante, elle fait donc plus d'opérations...

    Ce qui fait que tu atteins la limite de récursion et pas moi.

  18. #258
    Membre Expert
    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 : 38
    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
    Par défaut
    En effet, ça va mieux après le café et cette explication

  19. #259
    Membre éclairé

    Femme Profil pro
    Experte JS / Conseillère en best practices / Chercheuse en programmation
    Inscrit en
    Octobre 2007
    Messages
    741
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Experte JS / Conseillère en best practices / Chercheuse en programmation
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Octobre 2007
    Messages : 741
    Par défaut
    Un tout petit peu plus long (75) que la version de regseb mais légèrement plus précis

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var sleep = function() {
        var start = Date.now();
        while (Date.now() - start < 10) ;
    }
     
    var time = (function (f,d) {
    n=Date.now;for(c=0,s=n()+d;(e=n())<s;++c)f();return+((e-s+d)/c).toFixed(18)
    })(sleep, 1000);
     
    console.log(time);
    Différences :
    • affectation de c avant celle de s
    • une opération (soustraction) de moins dans la condition et donc à chaque exécution
    • retourne un nombre



  20. #260
    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
    Par défaut
    Mouais, je persiste à dire que soustraire deux dates est d'une précision plutôt douteuse. Surtout si à chaque itération on fait d'autres opérations pour mesurer le temps écoulé ou incrémenter un compteur : comment déduisez-vous le temps passé sur ces opérations du temps final, pour n'obtenir que le temps d'exécution de la fonction testée uniquement ? A ce tarif là, une précision à la sous-milliseconde est totalement inutile.

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: 42
    Dernier message: 20/08/2025, 11h13
  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