Journal Esod mumixam !

PostĂ© par (site web personnel) . Licence CC By‐SA.
41
4
déc.
2014

À toutes fins utiles, j'ai rĂ©digĂ© un petit traducteur pour la zorglangue. Un traducteur de et vers la zorglangue, puisque, comme le ROT13, le codage et le dĂ©codage se font avec la mĂȘme seule opĂ©ration.

Subtilités de ce traducteur :

  • il est Ă©crit en Python 3 (et n'utilise que des modules standard) ;
  • il laisse la ponctuation en place ;
  • il met les majuscules oĂč il faut, mĂȘme pour des caractĂšres hors ASCII.

Exemples :

$ echo 'Dose maximum !' | zorglang
Esod mumixam !
echo 'Dose maximum !' | zorglang | zorglang
Dose maximum !

VoilĂ , c'est tout, ça devrait mĂȘme marcher pour des langues qui s'Ă©crivent de droite Ă  gauche puisque cette subtilitĂ© est indĂ©pendante du flux de caractĂšres. Eviv Bulgroz !

Ah non, j'oubliais. Le code :

#! /usr/bin/python3
import io
import re
import sys
word_re = re.compile(r'\b\w+\b')
def zorglang(text):
 with io.StringIO() as buf:
 last_index = 0
 for match in word_re.finditer(text):
 buf.write(text[last_index:match.start()])
 word = match.group()
 for i in range(len(word)):
 if word[i].isupper():
 buf.write(word[-1 - i].upper())
 elif word[i].islower():
 buf.write(word[-1 - i].lower())
 else:
 buf.write(word[-1 - i])
 last_index = match.end()
 buf.write(text[last_index:])
 return buf.getvalue()
if __name__ == '__main__':
 for line in sys.stdin:
 print(zorglang(line), end='')
  • # M'enfin

    PostĂ© par . ÉvaluĂ© Ă  3.

    M'enfin, Gaston va enfin pouvoir lire Spirou...

    ⚓ À g'Auch TOUTE! http://afdgauch.online.fr

    • [^] # Re: M'enfin

      PostĂ© par (site web personnel, Mastodon) . ÉvaluĂ© Ă  10.

      Mais si Gaston lit Spirou, est-ce qu’il Ă©crit lui aussi au courrier des lecteurs ?

      ce commentaire est sous licence cc by 4 et précédentes

      • [^] # Re: M'enfin

        PostĂ© par (site web personnel) . ÉvaluĂ© Ă  10.

        En tout cas il est bien placé pour savoir ce qu'il adviendra de la réponse.

        Courrier en retard 1
        Courrier en retard 2
        Courrier en retard 3

        Paix et prospérité à l'ùme de Franquin.

        kentoc'h mervel eget bezan saotred

  • # En php?

    PostĂ© par (site web personnel) . ÉvaluĂ© Ă  -6.

    Je me demande si le php n'est pas plus simple:
    Découper la phrase avec explode() puis inverser les lettres de chaque mot avec strrev.
    Je ne code pas beaucoup mais amha cela doit pouvoir se régler en 5 lignes.

    • [^] # Re: En php?

      PostĂ© par (site web personnel) . ÉvaluĂ© Ă  10.

      La mĂȘme approche serait tout aussi simple en Python, mais le problĂšme, c'est que :

      • la ponctuation ne serait pas au bon endroit ;
      • les majuscules ne seraient pas au bon endroit.

      Ça donnerait ça :

      $ echo 'Dose maximum !' | zorglang-simpliste
      esoD mumixam !
      $ echo 'Zorglub, au secours !' | zorglang-simpliste
      ,bulgroZ ua sruoces !
      • [^] # Re: En php?

        PostĂ© par (site web personnel) . ÉvaluĂ© Ă  10.

        M'apprendra Ă  balancer un truc en deux minutes du boulot....

        • [^] # Re: En php?

          PostĂ© par . ÉvaluĂ© Ă  10.

          Il faut prendre plus le temps quand tu est au boulot.

  • # EmronĂ© \!

    PostĂ© par . ÉvaluĂ© Ă  3.

    À dnauq iulec ruop eriudart al eugnal Fpmuorths ?

  • # Sans expression rationnelle

    PostĂ© par . ÉvaluĂ© Ă  1.

    Une variante utilisant seulement les outils de manipulations de chaĂźnes

    #! /usr/bin/python3
    import sys
    def reverse_word(word):
     reversed_word = list(word)[::-1]
     if word[0].isupper():
     reversed_word[0] = reversed_word[0].upper()
     reversed_word[-1] = reversed_word[-1].lower()
     return ''.join(reversed_word)
    def zorglang(text):
     return ' '.join(
     [reverse_word(word) for word in text.split()]
     )
    for line in sys.stdin:
     print(zorglang(line), end='')
    • [^] # Re: Sans expression rationnelle

      PostĂ© par (site web personnel) . ÉvaluĂ© Ă  4. DerniĂšre modification le 04 dĂ©cembre 2014 Ă  17:46.

      Ce n'est pas équivalent, la ponctuation se retrouve mal placée :

      $ echo 'Zorglub, au secours !' | zorglang-simpliste
      ,bulgroz ua sruoces !$

      Et le retour Ă  la ligne final est mangĂ©, au passage (d'oĂč l'invite de commande $ que j'ai mis sur la ligne de rĂ©sultat, dans mon example).

      • [^] # Re: Sans expression rationnelle

        PostĂ© par . ÉvaluĂ© Ă  -1.

        Yep, mais cette piste est quand meme plus lisible. Dans le mĂȘme esprit, on peut en tout cas simplifier pas mal la fonction de dĂ©part par:

        def zorglang(text):
         last_index = 0 
         res = "" 
         for match in word_re.finditer(text):
         res += text[last_index:match.start()]
         word = match.group()
         wasup = word[0].isupper()
         word = ''.join(reversed(word))
         if wasup:
         word = word.capitalize()
         res += word
         last_index = match.end()
         res += text[last_index:]
         return res
        • [^] # Re: Sans expression rationnelle

          PostĂ© par (site web personnel) . ÉvaluĂ© Ă  10.

          Effectivement, remplacer le StringIO par une simple chaßne permet de tuer les performances en forçant une copie à chaque opération, et n'effectuer le test de capitalisation que pour la premiÚre lettre permet de ne plus transcrire correctement les mots à capitalisation interne tels que LinuxFr.org.

          C'est un peu plus simple, oui. Et moins bien.

          • [^] # Re: Sans expression rationnelle

            PostĂ© par . ÉvaluĂ© Ă  3.

            et ça donne quoi LinuxFr.org en zorgland? (je ne suis pas sûr de la place du point et de la majuscule "interne")

            • [^] # Re: Sans expression rationnelle

              PostĂ© par (site web personnel) . ÉvaluĂ© Ă  5.

              RfxunIl.gro

              (le point sĂ©pare deux mots ; les lettres sont capitalisĂ©es Ă  la mĂȘme place que dans les mots d'origine, en tout cas c'est mon interprĂ©tation, Franquin n'ayant pas explorĂ© ce genre de subtilitĂ©)

              • [^] # Re: Sans expression rationnelle

                PostĂ© par (site web personnel) . ÉvaluĂ© Ă  7.

                Je connais trÚs peu l'univers Spirou, mais au vu des rÚgles que tu as exposées dans ce journal et les commentaires, j'ai le sentiment que l'esprit serait plutÎt que ça donne "XunilRf.gro".

                Pour tenter d'expliquer, l'idĂ©e gĂ©nĂ©rale que je vois est de garder la « structure » , par exemple s'il y a une majuscule en dĂ©but de phrase, elle doit l'ĂȘtre au dĂ©but du rĂ©sultat et pas Ă  la fin, de mĂȘme pour la ponctuation, et les mots sont dans le mĂȘme ordre, et de n'inverser les lettres qu'au sein d'un seul mot dĂ©limitĂ© par cette structure Ă  la fois.

                Et pour moi cette construction (accoler deux mots en capitalisant leur premiĂšre lettre) relĂšve de la structuration. D'oĂč mon sentiment.

                • [^] # Re: Sans expression rationnelle

                  PostĂ© par (site web personnel) . ÉvaluĂ© Ă  3.

                  Peut-ĂȘtre, l'ennui Ă©tant que ce cas de se prĂ©sentant pas Ă  ma connaissance dans les albums de Spirou et Fantasio de Franquin, on ne pourra jamais le savoir. Et, par ailleurs, la dĂ©tection de mot dans les expressions rationnelles considĂšre LinuxFr comme un seul mot, donc je m'y suis tenu. En outre, il est plus facile de lire RfxunIl.gro que XunilRf.gr, mĂȘme si la capitalisation interne n'y est plus que cosmĂ©tique.

                  • [^] # Re: Sans expression rationnelle

                    PostĂ© par (site web personnel) . ÉvaluĂ© Ă  3.

                    En outre, il est plus facile de lire RfxunIl.gro que XunilRf.gr, mĂȘme si la capitalisation interne n'y est plus que cosmĂ©tique.

                    Si j'ai bien compris le peu que j'ai lu sur Zorglub-truc-machin-chose, c'est plutÎt un argument contre ta solution, ça, non ? ;-)

  • # as allways

    PostĂ© par . ÉvaluĂ© Ă  -7.

    ça se termine en concours de celui qui à la plus grosse. da linux french page devient déprimant.

    • [^] # Re: as allways

      PostĂ© par (site web personnel) . ÉvaluĂ© Ă  1.

      euh, c'est le rot13 qui te fait dire cela ? rot24 comme Rocco_Siffredi c'est l'inverse de 42 on va dire... l'alphabet français est de 26 lettres

    • [^] # Re: as allways

      PostĂ© par . ÉvaluĂ© Ă  10.

      Cela s'écrit "as hallways" ou en bon français "comme dans les couloirs"

      Désolé ...

    • [^] # Re: as allways

      PostĂ© par (site web personnel) . ÉvaluĂ© Ă  4.

      Personnellement, c'est, je trouve, la partie la plus intéressante du journal.
      Mais t'as le droit de préférer un journal avec que des commentaires "wow, super ! Rien à redire, c'est l'algo parfait !".

  • # et en perl

    PostĂ© par . ÉvaluĂ© Ă  7.

    plop

    je rajoute du vide pour éviter le décalage de l'avatar

    #!/bin/perl
    use strict;
    while( <STDIN>){
     while ( m/(\w+)(\W*)/g) {
     my ($mot, $sep ) = (1ăƒ‰ăƒ«, 2ăƒ‰ăƒ«);
     for( my $i = 0 ; $i <= (length $mot) ; $i++){
     if( substr( $mot,$i,1) =~ /[A-Z]/ ) { 
     print uc( substr( $mot, -1-$i, 1 )); 
     }
     else { 
     print lc( substr( $mot, -1-$i, 1 )) ;
     }
     }
     print "${sep}";
     }
    }

    Il ne faut pas décorner les boeufs avant d'avoir semé le vent

    • [^] # Re: et en perl

      PostĂ© par . ÉvaluĂ© Ă  4.

      sur un systĂšme utf-8 il peut ĂȘtre utile de faire l'une des action suivante

      • export PERL_UNICODE="" $ echo HĂ© Y a un caractĂšre accentuĂ© | zorg.pl
      • utiliser le switch -CIO $ echo HĂ© Y a un caractĂšre accentuĂ© | perl -C zorg.pl
      • ajouter use open qw(:std :utf8); au niveau des use ;) $ echo HĂ© Y a un caractĂšre accentuĂ© | zorg.pl

      Voila, j'ajouterai qu'en cas de caractÚres spéciaux avant le premier mot, ils sont bouffés; je poste donc une version améliorée qui marche avec de la ponctuation avant :

      !/usr/bin/perl
      use strict;
      use open qw(:std :utf8);
      while( <STDIN>){
       while ( m/(\w*)(\W*)/g) {
       my ($mot, $sep ) = (1ăƒ‰ăƒ«, 2ăƒ‰ăƒ«);
       for( my $i = 0 ; $i <= (length $mot) ; $i++){
       if( substr( $mot,$i,1) =~ /[A-Z]/ ) {
       print uc( substr( $mot, -1-$i, 1 ));
       }
       else {
       print lc( substr( $mot, -1-$i, 1 )) ;
       }
       }
       print "${sep}";
       }
      }

      $> echo '!!! ya mĂȘMe des accents en plein milieu !!!'| ./zorg.pl
      !!! ay emÊm sed stnecca ne nielp ueilim !!!
      $>

      Il ne faut pas décorner les boeufs avant d'avoir semé le vent

      • [^] # Re: et en perl

        PostĂ© par . ÉvaluĂ© Ă  4.

        et encore une correction :)

        remplacer [A-Z] par \p{upper}

        Il ne faut pas décorner les boeufs avant d'avoir semé le vent

      • [^] # Re: et en perl

        PostĂ© par . ÉvaluĂ© Ă  3.

        Pareil (si je dis pas de bĂȘtises), mais sans boucle :)

        #!/usr/bin/perl
        use strict;
        use warnings;
        use open qw(:std :utf8);
        while (<>) {
         s|(\p{Alphabetic})(\p{Alphabetic}*)|
         my ($first, $rest) = (1ăƒ‰ăƒ«,2ăƒ‰ăƒ«);
         ($first =~ /\p{upper}/)
         ? (ucfirst reverse $rest) . (lc $first)
         : (reverse $rest) . $first
         |xeg;
         print;
        }
        • [^] # Re: et en perl

          PostĂ© par . ÉvaluĂ© Ă  3.

          presque mais
          $>echo '!Eviv BuLgrozé!!' | zorg2.pl
          !Vive ÉzorgLub!!
          $>

          On a un changement des majuscules interne au mot, ce n'est donc pas équivalent au code initial; ensuite je me demande si on peut pas de faire a coup de regex récursive ;)
          (t)ru(C) => C(r)(u)t => Curt, à rechercher du coté de la recherche des palindromes (du point de vu de la logique)

          Il ne faut pas décorner les boeufs avant d'avoir semé le vent

          • [^] # Re: et en perl

            PostĂ© par . ÉvaluĂ© Ă  2.

            On a un changement des majuscules interne au mot, ce n'est donc pas équivalent au code initial

            Pas faux, j'avais pas pensé que les majuscules à l'intérieur des mots étaient à prendre en compte de cette façon.

          • [^] # Re: et en perl

            PostĂ© par . ÉvaluĂ© Ă  2.

            ensuite je me demande si on peut pas de faire a coup de regex récursive ;)
            (t)ru(C) => C(r)(u)t => Curt, à rechercher du coté de la recherche des palindromes (du point de vu de la logique)

            Je vois pas trop comment on pourrait s'en sortir avec des regexps rĂ©cursives, car elles servent uniquement Ă  matcher. Peut-ĂȘtre en utilisant des blocs ?{...} pour insĂ©rer du code dans la regexp. Par contre, on peut s'en sortir en faisant une fonction rĂ©cursive :

            #!/usr/bin/perl
            use strict;
            use warnings;
            use open qw(:std :utf8);
            sub zorglangize {
             my $text = shift;
             if ($text =~ /(\p{Alphabetic})(\p{Alphabetic}*)(\p{Alphabetic})/) {
             my ($first, $middle, $last) = (1ăƒ‰ăƒ«, 2ăƒ‰ăƒ«, 3ăƒ‰ăƒ«); 
             return (($first =~ /\p{upper}/) ? (uc $last) : (lc $last))
             . zorglangize($middle)
             . (($last =~ /\p{upper}/) ? (uc $first) : (lc $first));
             } else {
             return $text;
             }
            }
            while (<>) {
             s/(\p{Alphabetic}+)/zorglangize(1ăƒ‰ăƒ«)/xeg;
             print;
            }

            mais c'est un peu tordu... et probablement moins efficace que d'utiliser substr et des indices. Mais c'est marrant quand mĂȘme :)

            • [^] # Re: et en perl

              PostĂ© par . ÉvaluĂ© Ă  4.

              et probablement moins efficace que d'utiliser substr et des indices

              Bon, test sur un roman de plus de trois cent pages, j'obtiens :

              0m0.55s real 0m0.53s user 0m0.01s system (version récursive)
              0m0.55s real 0m0.54s user 0m0.02s system (version python du journal)
              0m0.47s real 0m0.45s user 0m0.02s system (ta version)
              

              Comme quoi, ça change pas grand chose, et dans tous les cas, c'est clair que les langages de script sont pas fait pour travailler sur du texte caractÚre à caractÚre.

  • # Plus simple

    PostĂ© par (site web personnel) . ÉvaluĂ© Ă  7.

    >,[<++++[->--------<]>[>,--------------------------------]<[>[-]++++[-<++++++++>]<.<]>[-]<++++[->++++++++<]>.[-],]
    
    • [^] # Re: Plus simple

      PostĂ© par . ÉvaluĂ© Ă  2.

      J'allais la demander !

      Du coup, je change mon fusil d'épaule : quelqu'un pour du befunge, ou j'ai le temps d'y réfléchir demain ?

      Matricule 23415

    • [^] # Re: Plus simple

      PostĂ© par . ÉvaluĂ© Ă  3.

      Zorglub, Au secours!
      ,bulgroZ uA

      Il y a un souci quelque part !

  • # elituni

    PostĂ© par (site web personnel) . ÉvaluĂ© Ă  6.

    cnod eriassecén

    kentoc'h mervel eget bezan saotred

  • # Merci, ĂŽ grand merci ...

    PostĂ© par . ÉvaluĂ© Ă  1.

    ... d'avoir enfin utilisé Python dans un contexte qui lui va particuliÚrement bien. C'est d'ailleurs le genre de truc pour lequel on devrait utiliser Python, et ne garder les autres trucs sérieux que pour des langages dignes de ce nom (Ruby étant l'un des meilleurs).

    • [^] # Re: Merci, ĂŽ grand merci ...

      PostĂ© par . ÉvaluĂ© Ă  7. DerniĂšre modification le 05 dĂ©cembre 2014 Ă  11:22.

      Tu te trompes. C’est justement parce qu’il est aussi possible d’utiliser Python Ă  des fin burelesques qu’il surpasse Ruby : lui (Python) au moins n’a pas une pierre coincĂ©e dans l’oignon.

      • [^] # Re: Merci, ĂŽ grand merci ...

        PostĂ© par . ÉvaluĂ© Ă  3.

        Tu te trompes. C’est justement parce qu’il est aussi possible d’utiliser Python Ă  des fin burelesques qu’il surpasse Ruby : lui (Python) au moins n’a pas une pierre coincĂ©e dans l’oignon.

        AprĂšs le monkey patching de Ruby, je crois que le burlesque n'a plus de limites que ce soit pour Ruby ou pour Python...

        "Quand certains rĂąlent contre systemd, d'autres s'attaquent aux vrais problĂšmes." (merci Sinma !)

    • [^] # Re: Merci, ĂŽ grand merci ...

      PostĂ© par . ÉvaluĂ© Ă  3.

      je regrette son programme ne respecte pas la norme python, il manque une citation :P

      Il ne faut pas décorner les boeufs avant d'avoir semé le vent

    • [^] # Re: Merci, ĂŽ grand merci ...

      PostĂ© par . ÉvaluĂ© Ă  4.

      Trop gros, passera pas...

  • # Parce que j'essaye de progresser en bash

    PostĂ© par . ÉvaluĂ© Ă  5.

    sentence=$*
    for word in $sentence
    do
    if [[ "$word" =~ ^.*([!?.,:;])+.*$ ]];then
     punct=${BASH_REMATCH[1]};
     new_word="${word/$punct/}"
     the_word=`echo $new_word | rev`
     result="$result $the_word$punct"
    else
     the_word=`echo $word | rev`
     result="$result $the_word"
    fi
    done
    echo $result

    ./zorg "la phrase Ă  reverser, une bonne phrase qui tue."
    al esarhp Ă  resrever, enu ennob esarhp iuq eut.

    • [^] # Re: Parce que j'essaye de progresser en bash

      PostĂ© par . ÉvaluĂ© Ă  5.

      Il y a un problĂšme au niveau des majuscule et des la gestion de la ponctuation ;)

      $>./zorg.sh '!!!Plop!?!'
      !?!polP!!!

      Il ne faut pas décorner les boeufs avant d'avoir semé le vent

      • [^] # Re: Parce que j'essaye de progresser en bash

        PostĂ© par . ÉvaluĂ© Ă  3.

        ahoui....

        petit scarabée devra progresser encore.

      • [^] # Re: Parce que j'essaye de progresser en bash

        PostĂ© par . ÉvaluĂ© Ă  2.

        Amélioration des majuscules, mais bon la ponctuation est toujours dans les choux, enfin... dans une certaine mesure.

        sentence=$*
        for word in $sentence
        do
        punct=""
        if [[ "$word" =~ ^.*([!?.,:;])+.*$ ]];then
         punct=${BASH_REMATCH[1]};
        fi
        new_word="${word/$punct/}"
        pl=${new_word:0:1};
        if [[ ${pl} == [a-z] ]] & [[ `printf '%o' "'${pl}"` < 133 ]];then
         new_word=${new_word,}
         the_word=`echo $new_word | rev`
         the_word=${the_word^}
        else
         the_word=`echo $new_word | rev`
        fi
         result="$result $the_word$punct"
        done
        echo $result

        herve@DreamMachine:~$ ./zorg "La phrase Ă  reverser, Une bonne phrase Qui tue."
        Al esarhp Ă  resrever, Enu ennob esarhp Iuq eut.

  • # Haskell

    PostĂ© par . ÉvaluĂ© Ă  10.

    import Data.Char
    import Data.List
    import System.Environment
    zorglangue :: String -> String
    zorglangue = concatMap capReverse . splitWords
    w :: Char -> Bool
    w x = isAlphaNum x || x == '_' 
    splitWords :: String -> [String]
    splitWords = groupBy (\a -> \b -> w a == w b)
    capReverse :: String -> String
    capReverse xs | not (all w xs) = xs 
    capReverse xs = map cap $ zip (map (\x -> if isUpper x then toUpper else toLower) xs) (reverse xs)
     where cap (f, c) = f c
    main :: IO()
    main = getContents >>= putStrLn . unlines . map zorglangue . lines
    $ echo "Zorglub, Au secours!" | ./zorglangue
    Bulgroz, Ua sruoces!

    J'ai passé un bon vendredi...

    • [^] # Re: Haskell

      PostĂ© par . ÉvaluĂ© Ă  2.

      Pourquoi faire du faux "currying"?

      (\a -> \b -> w a == w b) est la mĂȘme chose que (\a b -> w a == w b).

      Ruby est le rĂ©sultat d'un gamin qui apprend le Java, puis jette un Ɠil Ă  Perl et se dit « je peux le rĂ©parer! »

      • [^] # Re: Haskell

        PostĂ© par . ÉvaluĂ© Ă  3. DerniĂšre modification le 07 dĂ©cembre 2014 Ă  12:40.

        Qui est la mĂȘme chose que :

        (==) `on` w

        qui est la mĂȘme chose que :

        (==) `on` ((||) <$> isAlphaNum <*> (=='_'))

        Huhuhu, le Haskell, qu'est-ce qu'on se marre.

        EDIT: Oh, j'avais pas remarqué, trÚs joli emploi du zip !

        • [^] # Re: Haskell

          PostĂ© par . ÉvaluĂ© Ă  1.

          ah oui merci pour le on. justement je me souvenais avoir vu ça, mais impossible de retrouver comment faire...

          • [^] # Re: Haskell

            PostĂ© par . ÉvaluĂ© Ă  3.

            Dans le mĂȘme genre, tu peux remplacer ça getContents >>= putStrLn . unlines . map zorglangue . lines par ça interact $ unlines . map zorglangue . lines.

            Et ça map cap $ zip l1 l2 where cap (f, c) = f c par ça zipWith ($) l1 l2.

            Et enfin (mais là je suis pas sûr sûr, en tout cas les types matchent), ça concatMap capReverse . splitWords par ça capReverse <=< splitWords.

            • [^] # Re: Haskell

              PostĂ© par . ÉvaluĂ© Ă  2.

              '<=<' je connaissais pas.
              j'ai lu "programming in haskell", j'ai presque fini "learn yourself a haskell", et j'ai toujours l'impression de ne pas trop maitriser le haskell...

              alors qu'à l'époque, pour python il m'a suffit d'un tutorial...

              • [^] # Re: Haskell

                PostĂ© par . ÉvaluĂ© Ă  7.

                Ce que je trouve, c'est qu'avec haskell, il y a beaucoup de choses simples dans d'autres langages qui sont enrobées de choses compliquées, et pas forcément faciles à retenir au début. Et puis certaines choses qu'on estime de base, pour lesquelles on a des syntaxes spéciales dans d'autres langages (tableaux, chaßnes de caractÚres et tables de hachages) ne sont pas plus pratiques à utiliser que des choses moins courantes. En fait, la seule structure de base vraiment pratique à utiliser en Haskell, c'est les listes chaßnées.

                Mais le plus gĂȘnant, c'est quand tu crois que tu commences Ă  connaĂźtre le langage et que tu tombes sur du code qui utilise des Lens, Arrows ou autre et tu t'aperçois qu'en fait, non :)

  • # blague

    PostĂ© par . ÉvaluĂ© Ă  1.

    référence inside

    et grotesque se dit euqsetorg je suppose?

    fin de ma blague, celui qui trouve la référence gagne un bon point

    • [^] # Re: blague

      PostĂ© par . ÉvaluĂ© Ă  4.

      si personne ne trouve avant vendredi prochain tu nous donneras la réponse ?

      • [^] # Re: blague

        PostĂ© par . ÉvaluĂ© Ă  2.

        rhalala, bon c'est dans "l'horloger de la comÚte" de Tome et Janry. Je ne peux donner la page pour l'instant la BD est toujours chez mes parents qui ne sont pas à cÎté.

  • # Let's get Groovy, Baby!

    PostĂ© par (site web personnel) . ÉvaluĂ© Ă  6.

    Moi aussi je saute des lignes pour éviter l'avatar.

    Ou alors je pourrais vous mettre la version Java.

    Nan j'déconne.

    #!/usr/bin/env groovy
    def original = args ? args[0] : System.in.available() ? System.in.text : ""
    print original.split( "\\b" ).collect {
     if ( it =~ /\w+/ ) {
     def result = ""
     def chars = it.toCharArray()
     chars.eachWithIndex { c, i ->
     result += c.isLowerCase() ? chars[-i - 1].toLowerCase() : chars[-i - 1].toUpperCase()
     }
     result
     } else {
     it
     }
    }.join()
  • # Avec du poil aux pattes

    PostĂ© par . ÉvaluĂ© Ă  9.

    Une version en x86_64, pour Linux. À assembler avec FASM.

    Pour l'ASCII étendu, suit l'ISO 8859-15 (aka Latin-9), et donc pas l'UTF-8. Limites en dur pour la longueur de la ligne et des mots.

    format ELF64 executable 3
    entry _start
    TAILLE_BUF=256
    TAILLE_MOT=64
    segment readable executable
    _start:
     XOR RAX, RAX ; 0 (sys_read)
     XOR RDI, RDI ; 0 (stdin)
     MOV RSI, bufin ; adresse du tampon d'entrée
     MOV RDX, TAILLE_BUF ; taille du tampon
     SYSCALL ; lecture
     MOV [longueur], RAX ; nombre d'octets lus
     XOR RDI, RDI
    teste_nouveau_caractere:
    ; on teste le nouveau caractĂšre
     CALL nature_caractere
     CMP AL, 0
     JNE nouveau_mot
    ; ponctuation et divers : on l'écrit tel quel
     MOV [bufout+RDI], DL
     JMP suivant
    nouveau_mot:
    ; lettre : début d'un nouveau mot
     XOR RBX, RBX ; compteur des caractĂšres du mot
     MOV RSI, RDI ; mémorise la position (offset) du début du mot
    ; on recherche la fin de ce nouveau mot en enregistrant pour chaque lettre son type
    continue_mot:
     MOV [mot+RBX], DL
     MOV [type_car+RBX], AL
     MOV [casse_car+RBX], AH
     INC RDI
     CALL nature_caractere
     CMP AL, 0
     JE fin_mot
     INC RBX
     JMP continue_mot
    fin_mot:
     push RDX
     XOR RCX, RCX
    inverse_mot:
    ; quelle casse faut-il ?
     MOV AL, [casse_car+RCX] ; casse du caractĂšre d'origine
     CMP AL, 0
     JNE minuscule
    ; majuscule
     MOV AL, [casse_car+RBX] ; casse du nouveau caractĂšre
     CMP AL, 0
     JNE monter_casse
    ; déjà en majuscule, il faut juste copier
     MOV AL, [bufin+RSI+RBX]
     MOV [bufout+RSI+RCX], AL
     JMP fin_corps_boucle_mot
    monter_casse:
     MOV AL, [type_car+RBX]
     CMP AL, 1
     JNE pas_min_std
     MOV AL, [mot+RBX]
     ADD AL, "A"
     MOV [bufout+RSI+RCX], AL
     JMP fin_corps_boucle_mot
    pas_min_std:
     CMP AL, 2
     JNE pas_min_acc
     MOV AL, [mot+RBX]
     ADD AL, 0xC0 ; "À"
     MOV [bufout+RSI+RCX], AL
     JMP fin_corps_boucle_mot
    pas_min_acc: ; e dans l'o
     mov [bufout+RSI+RCX], 0xBC ; "ƒ"
     JMP fin_corps_boucle_mot
    minuscule:
     MOV AL, [casse_car+RBX] ; casse du nouveau caractĂšre
     CMP AL, 1
     JNE baisser_casse
    ; déjà en minuscule, il faut juste copier
     MOV AL, [bufin+RSI+RBX]
     MOV [bufout+RSI+RCX], AL
     JMP fin_corps_boucle_mot
    baisser_casse:
     MOV AL, [type_car+RBX]
     CMP AL, 1
     JNE pas_maj_std
     MOV AL, [mot+RBX]
     ADD AL, "a"
     MOV [bufout+RSI+RCX], AL
     JMP fin_corps_boucle_mot
    pas_maj_std:
     CMP AL, 2
     JNE pas_maj_acc
     MOV AL, [mot+RBX]
     ADD AL, 0xE0 ; "Ă "
     MOV [bufout+RSI+RCX], AL
     JMP fin_corps_boucle_mot
    pas_maj_acc: ; E dans l'O
     mov [bufout+RSI+RCX], 0xBD ; "Ɠ"
    fin_corps_boucle_mot:
     INC RCX
     DEC RBX
     JNS inverse_mot
    ; on copie le dernier caractĂšre que l'on vient de trouver
     pop RDX
     MOV [bufout+RDI], DL
    suivant:
     INC RDI
     CMP RDI, [longueur]
     JL teste_nouveau_caractere
     MOV RDI, 1 ; 1 (stdout)
     MOV RSI, bufout ; adresse du message Ă  afficher
     MOV RDX, [longueur] ; nombre d'octets à écrire
     MOV RAX, 1 ; 1 (sys_write)
     SYSCALL ; écriture
    ; Exit
     MOV RDI, 0 ; status de sortie = SUCCESS
     MOV RAX, 60 ; 60 (sys_exit)
     SYSCALL ; exécution de la sortie
    ;; === ROUTINE nature_caractere ===
    ;; entrée :
    ;; rdi : index caractĂšre dans le tampon bufin
    ;; sorties :
    ;; al : type du caractĂšre :
    ;; 0 : ponctuation, divers
    ;; 1 : lettre standard
    ;; 2 : lettre accentuée
    ;; 3 : e dans l'o
    ;; ah : 0 : majuscule
    ;; 1 : minuscule
    ;; dl : rang du caractĂšre dans le type
    ;; ===
    nature_caractere:
     MOV DL, [bufin+RDI]
    test_majuscule:
     CMP DL, "A"
     JB autres
     CMP DL, "Z"
     JA test_minuscule
    ; majuscule standard
     MOV AL, 1
     MOV AH, 0
     SUB DL, "A"
     RET
    test_minuscule: 
     CMP DL, "a"
     JB autres
     CMP DL, "z"
     JA test_edanlo
    ; minuscule standard
     MOV AL, 1
     MOV AH, 1
     SUB DL, "a"
     RET
    test_edanlo:
     CMP DL, 0xBC ; "ƒ"
     JB autres
     JNE test_edanlo_min
    ; e dans l'o majuscule
     MOV AL, 3
     MOV AH, 0
     SUB DL, 0xBC ; "ƒ"
     RET
    test_edanlo_min:
     CMP DL, 0xBD ; "Ɠ"
     JA test_majuscule_accentuee
    ; e dans l'o minuscule
     MOV AL, 3
     MOV AH, 1
     SUB DL, 0xBC ; "ƒ"
     RET
    test_majuscule_accentuee:
     CMP DL, 0xC0 ; "À"
     JB autres
     CMP DL, 0xDD ; "Y'"
     JA test_minuscule_accentuee
    ; majuscule accentuee
     MOV AL, 2
     MOV AH, 0
     SUB DL, 0xC0
     RET
    test_minuscule_accentuee:
     CMP DL, 0xE0 ; "Ă "
     JB autres
     CMP DL, 0xFD ; "y'"
     JA autres
    ; minuscule accentuee
     MOV AL, 2
     MOV AH, 1
     SUB DL, 0xE0
     RET
    autres: 
     MOV AX, 0
     RET
    ;; === FIN nature_caractere ===
    segment readable writeable
     bufin RB TAILLE_BUF
     bufout RB TAILLE_BUF
     mot RB TAILLE_MOT
     type_car RB TAILLE_MOT
     casse_car RB TAILLE_MOT
     longueur DQ 0

    Pas spĂ©cialement propre (je dois Ă©crire en moyenne 50 lignes d'assembleur par an...), ni documentĂ©, ni optimisĂ© (mais vus les langages d'urbains Ă©pilĂ©s prĂ©sentĂ©s dans la plupart des autres propositions, ce programme (binaire de 1364 octets) devrait avoir fini son exĂ©cution avant que les autres n'aient fini leur chargement en mĂ©moire). Ne gĂšre pas pas correctement les signes « multiplication » et « division » (pas envie de m'embĂȘter pour ce cas particulier « intelligemment » placĂ© au beau milieu des majuscules accentuĂ©es).

    • [^] # Re: Avec du poil aux pattes

      PostĂ© par (site web personnel) . ÉvaluĂ© Ă  3.

      vus les langages d'urbains épilés présentés dans la plupart des autres propositions, ce programme (binaire de 1364 octets) devrait avoir fini son exécution avant que les autres n'aient fini leur chargement en mémoire

      Ah bah peut-ĂȘtre (encore que tu sais pas ce qu'un compilo / une VM malins peuvent faire !), mais nous au moins :

      • on est pas limitĂ© Ă  un seul processeur
      • on gĂšre l'UTF-8 parce qu'on est plus en 1992 et les chinois aussi ont internet
      • on met pas de limite de taille arbitraire parce que (扊陀) 140 characters (ć‰Šé™€ă“ă“ăŸă§) 640kB should be enough for everyone
      • on a pas (ou alors pas fait exprĂšs et on corrige :-p) un truc qui fait-le-job-mais-en-fait-pas-pour-X-et-Y-t'as-qu'Ă -t'en-passer

      Alors au choix hein... :-P

      • [^] # Re: Avec du poil aux pattes

        PostĂ© par . ÉvaluĂ© Ă  5.

        on est pas limité à un seul processeur

        Vu que le script original est en Python...

        « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

        • [^] # Re: Avec du poil aux pattes

          PostĂ© par (site web personnel) . ÉvaluĂ© Ă  4.

          J'ai mis du temps Ă  comprendre ta remarque. Alors elle est juste (et pas que pour la version python, les autres ne me semblent pas non plus utiliser de multithreading), mais on ne parle pas de la mĂȘme chose :) Je parlais du fait que son assembleur x86_64 ne doit pas trop bien marcher sur d'autres types de processeurs alors que le python, le perl, le groovy... pas de souci. Mais c'est vrai que j'aurais du dire "un seul type de processeur".

      • [^] # Re: Avec du poil aux pattes

        PostĂ© par . ÉvaluĂ© Ă  5.

        tu sais pas ce qu'un compilo / une VM malins peuvent faire !

        Mouais, c'est quelque chose que l'on entend rĂ©pĂ©tĂ© ad nauseam depuis des annĂ©es, mais en pratique il est rare qu'ils produisent un code plus performant qu'un premier jet bĂȘtement codĂ© Ă  la main. Et de toutes maniĂšres, vu qu'en gĂ©nĂ©ral on passe son temps Ă  appeler des fonctions assez gĂ©nĂ©riques qui ne sont donc pas optimisĂ©es pour le cas que l'on utilise, il n'y a pas grand chose d'optimisable par le compilateur...

        on gĂšre l'UTF-8 parce qu'on est plus en 1992 et les chinois aussi ont internet

        OK, mais on le gÚre comment ? Faudrait se mettre d'accord sur ce qu'on veut avant de commencer à le gérer, sinon, on gÚre l'UTF-8 en entrée mais en produisant une sortie au petit bonheur la chance. Par exemple, dans le programme Python d'origine, le "\w" de la regexp ne va pas forcément donner les résultats que l'on attend. Avec les chiffres, par exemple, pour "Vol_714", on pourrait raisonnablement attendre "Lov_714" (comportement de mon programme) ou "Lov_417" comme résultat. Eh bien non, parce que le "\w" compte les chiffres et les "_" comme des caractÚres de mot, ça va donner "417_lov". Ah non, tiens, en plus ça donne "417_loV", une « erreur » supplémentaire :-) puisque les chiffres n'ont pas de casse et que dans ce cas le programme recopie les caractÚres tels qu'ils sont entrés).

        Quant au Chinois, tu as choisi un bon exemple des emmerdements dans lesquels on est plongé par la complexité et la richesse d'Unicode si on veut le gérer dans son intégralité : dans un texte chinois, il n'y a pas de mots discernables et il n'y a pas de majuscules. Bim, les 2 principales spécification de notre zorglub sautent. Que fait-on ? On inverse tout le bloc d'idéogrammes entre 2 ponctuations, comme le programme d'origine le fait ? Ou pas ? Et surtout quel sens cela a-t-il de rentrer du chinois dans ce programme ?

        on met pas de limite de taille arbitraire parce que 140 characters 640kB should be enough for everyone

        Ben dans la langue de Franquin, le mot le plus long ayant 25 caractÚres, avec 64 on should be tranquille. Sinon, on rachÚtera un caractÚre supplémentaire pour écrire « 128 » à la place :-)

        on a pas (ou alors pas fait exprĂšs et on corrige :-p)

        Oui, je constate que c'est le mode de développement actuel. « Allez, cette fonction a un bon nom, je vais l'utiliser ; on verra bien ce que ça donne : avec un peu de bol, ça marche. » ... « hop c'est bon, j'ai testé avec un exemple, ça roule. Ouais, non lire la spécification de la fonction, ce n'est pas la peine puisque ça marche pour l'instant. On verra bien si quelqu'un se plaint » ...
        NB : j'ai bien conscience que dans les programmes prĂ©sentĂ©s ici, il ne s'agit pas d'un logiciel critique ou d'un soft facturĂ© 200 000 € Ă  un malheureux pige^ Wclient, mais d'un petit jeu, donc ces reproches(?) ne leur sont pas destinĂ©s mais puisque je vois qu'on est d'humeur taquine... :-)

        un truc qui fait-le-job-mais-en-fait-pas-pour-X-et-Y-t'as-qu'Ă -t'en-passer

        Ben... au moins dans le truc que j'ai proposé, les caractéristiques et les limites sont assez clairement mises en avant.
        Si on respecte ces rĂšgles, le comportement devrait ĂȘtre fiable1 .

        Si on prend le programme d'origine, pour les mĂȘme donnĂ©es d'entrĂ©es, si on l'exĂ©cute dans un environnement diffĂ©rent (changement des locales) => BOUM. Alors il vaut peut-ĂȘtre mieux savoir ce qui est supportĂ© et ce qui ne l'est pas par le programme et s'y tenir plutĂŽt que d'avoir un comportement non prĂ©vu ou un crash.


        1. lĂ , logiquement, comme quand on fait une remarque sur l'orthographe, je ne doute pas que quelqu'un va me faire remarquer que j'ai oublier de traiter/spĂ©cifier un cas particulier :-) Ce que je veux dire, c'est que j'ai essayĂ© d'une part d'ĂȘtre conscient des limites de ma version et de les mentionner et d'autre part de ne traiter qu'un type d'entrĂ©e restreint Ă  ce qui fait sens, plutĂŽt que de faire un truc qui est censĂ© tout traiter sans limites, mais qui le fait mal ou de maniĂšre inattendue. Et le coup de la non-gestion assumĂ©e des signes « multiplier » et « diviser », c'est un geste politique de protestation contre la faute de goĂ»t d'avoir collĂ© ces deux signes en plein milieu des majuscules accentuĂ©es :-). Sinon, c'est juste 2 fois 2 instructions Ă  rajouter pour les gĂ©rer correctement. ↩

        • [^] # Re: Avec du poil aux pattes

          PostĂ© par . ÉvaluĂ© Ă  4.

          tu sais pas ce qu'un compilo / une VM malins peuvent faire !

          Mouais, c'est quelque chose que l'on entend rĂ©pĂ©tĂ© ad nauseam depuis des annĂ©es, mais en pratique il est rare qu'ils produisent un code plus performant qu'un premier jet bĂȘtement codĂ© Ă  la main.

          Chic, chic, un troll ! Donc euh, mon boulot a été, pendant un moment, d'optimiser des codes scientifiques (qui souvent sont bien plus faciles à optimiser pour un compilateur que des codes plus traditionnels). Je n'ai presque jamais eu à recourir à l'écriture en ASM, mais par contre savoir le lire était important :

          1. Il fallait pouvoir reconnaßtre un code peu optimisé par le compilateur (alors qu'on pouvait faire mieux)
          2. Il fallait quand mĂȘme pouvoir Ă©crire 2-3 trucs Ă  la main dans certains cas prĂ©cis
          3. La plupart des cas oĂč j'avais besoin de faire du fine tuning, je passais par les intrinsics de gcc/llvm/icc (par exemple, si on veut utiliser les instructions MMX/SSE/AVX sur x86/x64), ce qui Ă©tait quand mĂȘme 'achement plus simple pour obtenir des diagnostics d'erreur quand je me plantais.
          4. La plupart du temps, le compilateur est bien plus malin que le programmeur.

          Concernant mon dernier point : au final, plutĂŽt qu'Ă©crire en ASM, je finissais par savoir comment exprimer mes programmes sous une forme que le compilateur savait optimiser. Souvent, ça passe par la « dĂ©bilisation » du code : si on essaie d'ĂȘtre trop intelligent, le compilateur voit un tas de code compliquĂ©, et laisse tomber. Si au contraire on Ă©crit le code de la façon la plus simple possible, souvent le compilo comprend l'idiome, et trouve des choses intelligentes Ă  faire. Il y a bien entendu des exceptions :

          • Si on essaie d'optimiser pour les caches, il faut souvent recourir Ă  des techniques de « blocking » ou « tiling », mais lĂ  encore on peut s'arranger pour ne pas se mettre en travers du compilateur (par exemple, on met la partie Ă  optimiser du code dans une fonction Ă  part, et ainsi on l'isole du nid de boucle qui l'entoure).
          • Il y a des fois oĂč le compilateur se plante rĂ©ellement dans la gĂ©nĂ©ration du code, mais lĂ  encore, faire de « l'assembleur en C » permet le plus souvent de le remettre dans le droit chemin.

          Sur certaines architectures c'est relativement faux : par exemple sur Itanium, tout un tas de mĂ©canismes super cool concernant la prĂ©dication des branches, la spĂ©culation de contrĂŽle ou de donnĂ©es, etc., n'Ă©taient tout simplement pas accessible Ă  moins de faire de l'assembleur (gcc est dans les choux niveau optim sur ia64, et icc interdit l'utilisation d'assembleur inline — mais il y a des intrinsics pour certains trucs).

          Bref. J'en profite pour lier vers ce blog qui propose un quiz à propos de différentes optimisations que le compilateur peut effectuer.

          Et de toutes maniÚres, vu qu'en général on passe son temps à appeler des fonctions assez génériques qui ne sont donc pas optimisées pour le cas que l'on utilise, il n'y a pas grand chose d'optimisable par le compilateur...

          Ça par contre je suis relativement d'accord. Je n'ai pas Ă©tĂ© regarder, mais j'aimerais bien savoir s'il existe des fonctions de la libc qui ont des variantes, du genre (code non testĂ©, y'a sans doute des bugs) :

          #ifdef __HAS_AVX__ 
          #define memcpyAVX memcpy
          #elif __HAS_SSE2__
          #define memcpySSE2 memcpy
          #elif //...
          //...
          #endif
          void *memcpySSE2(void *restrict s1, const void *restrict s2, size_t n) {
           if (n < sizeof(_m128d)) { // size to copy is less than 8 chars
           char *dst = (char*) s1, *src = (char*) s2;
           while ( n-- )
           *dst++ = *src++;
           } else if ( is_aligned16(s1) && is_aligned16(s2) ) { // aligned on 16B
           _m128d src; // or _m128i with _mm_load_si128/_mm_store_si128, doesn't really matter here...
           size_t i;
           for (i = 0; i < n-8; i += 8) {
           src = _mm_load_ps ( s2 + i );
           _mm_store_ps ( s1 + i, src ); // copy, 8 chars at a time
           }
           for (; i < n; ++i) // epilogue
           *((char*)s1+i) = *((char*)s2+i);
           } else { // unaligned accesses
           _m128d src; // or _m128i with _mm_loadu_si128/_mm_storeu_si128, doesn't really matter here...
           size_t i;
           for (i = 0; i < n-8; i += 8) {
           src = _mm_loadu_ps ( s2 + i );
           _mm_storeu_ps ( s1 + i, src ); // copy, 8 chars at a time
           }
           for (; i < n; ++i) // epilogue
           *((char*)s1+i) = *((char*)s2+i);
           }
          }

          NB: avec icc (et en supposant que mon code ne soit pas complĂštement rempli de bugs, ce qui est trĂšs possible), les boucles vont ĂȘtre dĂ©roulĂ©es, entre 2 et 6 fois, pour tirer avantage des 16 registres SSE. Pour tirer avantage des cas intermĂ©diaires, icc va gĂ©nĂ©rer des variantes qui vont complĂštement dĂ©rouler les cas du genre N=8, N=16, N=32, etc. Je ne crois pas que gcc fasse cela aussi systĂ©matiquement, mais il commence aussi Ă  ĂȘtre bon pour ce qui est de la vectorisation.

Suivre le flux des commentaires

Note : les commentaires appartiennent Ă  celles et ceux qui les ont postĂ©s. Nous n’en sommes pas responsables.