Journal Esod mumixam !

Post√©¬†par¬† (site Web personnel) . Licence CC¬†By‚ÄĎSA.
√Čtiquettes¬†:
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) . √Č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/12/14 √† 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¬† (site Web personnel) . √Č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¬† (site Web personnel) . √Č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¬† (site Web personnel) . √Č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¬† (site Web personnel) . √Č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 ?

    • [^] # 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¬† (site Web personnel) . √Čvalu√©¬†√†¬†7. Derni√®re modification le 05/12/14 √† 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.

      Love ‚Äď b√©po

      • [^] # 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/12/14 √† 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¬† (site Web personnel) . √Č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 à ceux qui les ont postés. Nous n’en sommes pas responsables.