[Perl] nombre en mots

Dominix d.minix at gmail.com
Lun 22 Fév 20:43:02 CET 2016


bon, chacun mettra a son goût, j'ai ajusté les vingt _et_ un et les 's' 
des cents.

pour passer des paramètres via URL, est ce que le plus simple c'est une 
app/dancer ? plack ? mojolicious ?
merci de vos avis (c'est ma question de départ au final) ... bon je vais 
voir si hollande arrive, c'est pas souvent qu'il passe dans ma rue.

Le 22/02/2016 01:22, Sébastien Moretti a écrit :
> Ça dépend des suisses (des cantons) mais c'est plutôt huitante par ici.
>
>> A ma connaissance, les Belges utilisent quatre-vingts. Mais je crois que
>> les Québecois utilisent octante (et peut-être les Suisses).
>>
>>
>>
>> Le 22 février 2016 à 10:30, Dominique <d.minix at gmail.com
>> <mailto:d.minix at gmail.com>> a écrit :
>>
>>     houla, l'octante c'est faite la malle ;-)
>>
>>     Le 21 février 2016 à 20:44, Alain BarBason <alain at barbason.be
>>     <mailto:alain at barbason.be>> a écrit :
>>
>>         Le 22/02/16 06:55, Dominique a écrit :
>>
>>             suite a qq échange, j'ai pondu la version fr de nombre en
>>             mots (ci joint)
>>
>>         Version belge
>>                                   septante  quatre-vingt nonante ) );
>>
>>         :-)
>>
>>         Abb
>

-------------- section suivante --------------
#!/usr/bin/perl 
# This is an 79-character-wide ASCII-encoded Perl-source-code text file. 
# =======|=========|=========|=========|=========|=========|=========|========= 
############################################################################### 
# Writes a number in words.                                                   # 
# Eg, given "398", outputs "trois cent quatre-vingt dix huit"                 # 
# Input: A single command-line argument consisting of a non-negative integer. # 
# Ootput: The number in words.                                                # 
# Author: Robbie Hatley for english original, adapté en fraçais par dominix   # 
# Edit history:                                                               # 
#    Sat Feb 20, 2016 - Wrote it.                                             # 
#    Sat Feb 21, 2016 - version française (dominix)                           # 
# NB la version belge est activable par le changement du commentaire 80 vs 81 #
############################################################################### 

use v5.018; 
use strict; 
use warnings; 

sub nombre_en_mots ($); 

# main body of script: 
{ 
    if ( 1 != @ARGV ) 
    { 
       die "Error: This program takes exactly one argument, which must be\n", 
           "a non-negative integer not exceeding 10^66-1.\n", 
           "$!\n"; 
    } 
    my $number = shift; 
    say nombre_en_mots($number); 
    exit 0; 
} 

sub nombre_en_mots ($) 
{ 
    return "pas d'entrée input"        if @_ < 1; 
    return 'entrée excessive'          if @_ > 1; 

    my $number = shift; # input string 

    return 'entrée indéfinie'          if not defined $number; 
    return "n'est pas un entier non negatif" if $number !~ m/^[\d]+$/; 
    return 'dépassement'               if length($number) > 66; 
    return 'zéro'                      if 0 == $number; 

    # Dissect the number into its digits little-endian-wise, 
    # so that the digit index is equal to log10 of place value. 
    # While this is backwards from the way people read numbers, 
    # it makes the programming MUCH easier. 
    my @digits = (); 
    unshift @digits, $_ for split //, $number; 

    # Right-zero-pad @digits as necessary so that it will have 
    # exactly 66 elements (usually most of them zeros): 
    my $index   = 0; 
    for ( $index = scalar(@digits) ; $index < 66 ; ++$index ) 
    { 
       push @digits, 0; 
    } 

    my @groups = ( '' , qw( mille
                  million       milliard
                  billion       billiard
                  trillion      trilliard
                  quadrillion   quadrilliard
                  quintillion   quintilliard
                  sextillion    sextilliard
                  septillion    septilliard
                  octillion     octilliard
                  nonillion     nonilliard
                  decillion     decilliard) ); 

    my @ones = ( '', qw(  un        deux      trois 
                          quatre    cinq      six 
                          sept      huit      neuf   ) ); 

    my @tens = ( '', qw(  dix       vingt     trente 
                          quarante  cinquante soixante 
                          soixante-dix  quatre-vingt   quatre-vingt-dix ) ); 
#                         septante  octante   nonante ) ); 

    my @hundreds = ( '', 'cent',       'deux cent', 'trois cent', 
                        'quatre cent', 'cinq cent', 'six cent', 
                       'sept cent',    'huit cent', 'neuf cent' ); 

    my $string  = ''; # output string 

    # Iterate through digit groups of @digits in reverse order 
    # (right to left, most-significant to least-significant, 
    # remembering that we're writing all number BACKWARDS on purpose, 
    # so that the digits are ordered ones, tens, hundreds, thousands, etc) 
    # and separate out each group in turn as a slice: 
    for (reverse 0..21) 
    { 
       my @slice = @digits[3*$_+0, 3*$_+1, 3*$_+2]; 

       #If this slice is populated: 
       if ($slice[2] > 0 || $slice[1] > 0 || $slice[0] > 0 ) 
       { 
          # if hundreds: 
          if ($slice[2] > 0) 
          { 
             $string .= $hundreds[$slice[2]]; 
             # if we also have tens or ones, append ' ': 
             if ($slice[1] > 0 || $slice[0] > 0) 
             { 
                $string .= ' '; 
             }
             else
             {
                $string .= 's' if ($slice[2] > 1)
             } 
          } 
          # if tens: 
          if ($slice[1] > 0) 
          { 
             if ( $tens[$slice[1]] =~ /dix$/  ) { 
                 $string .= ($slice[0] == 1) ? "$tens[$slice[1]-1] onze"
                    :  ($slice[0] == 2) ? "$tens[$slice[1]-1] douze"
                    :  ($slice[0] == 3) ? "$tens[$slice[1]-1] treize"
                    :  ($slice[0] == 4) ? "$tens[$slice[1]-1] quatorze"
                    :  ($slice[0] == 5) ? "$tens[$slice[1]-1] quinze"
                    :  ($slice[0] == 6) ? "$tens[$slice[1]-1] seize"
                    :  ($slice[0] == 7) ? $tens[$slice[1]].'-'.$ones[$slice[0]]
                    :  ($slice[0] == 8) ? $tens[$slice[1]].'-'.$ones[$slice[0]]
                    :  ($slice[0] == 9) ? $tens[$slice[1]].'-'.$ones[$slice[0]]
                    :  $tens[$slice[1]]
             } else {
                 $string .= $tens[$slice[1]]; 
                 # if we also have ones, append ' ': 
                 if ($slice[0] > 0) 
                 { 
                    #$string .= ' '.$ones[$slice[0]]; 
                    $string .= ($slice[0] == 1) ? ' et un'
                               : ' '.$ones[$slice[0]]
                 } 
             }
          } 
          if ($slice[1] == 0 and $slice[0] > 0) {
             # tout ça juste pour ne pas avoir "un mille"
             $string .= $ones[$slice[0]] if not (($slice[2]==0)&&($slice[0]==1)&&($_==1))
          }
          # Finally, if this is not the least-significant group, 
          # append group name (thousand, million, billion, whatever): 
          if ($_ > 0) 
          { 
             $string .= ' '; 
             $string .= $groups[$_]; 
          } 
       } # end if (slice is populated) 

       # If this is not the least-significant group, 
       # and if both current and next group are populated, 
       # then append comma and space: 
       if ($_ > 0) 
       { 
          my @nexts = @digits[3*$_-3, 3*$_-2, 3*$_-1]; 
          if 
          ( 
             ($slice[2] > 0 || $slice[1] > 0 || $slice[0] > 0 ) 
             && 
             ($nexts[2] > 0 || $nexts[1] > 0 || $nexts[0] > 0 ) 
          ) 
          { 
             $string .= ', '; 
          } # end appending ', ' if necessary 
       } # end if (not least-significant group) 
    } # end for (each group) 
    $string =~ s/  / /g;$string =~ s/^ //;
    # We're done, so return $string: 
    return $string; 
} 


Plus d'informations sur la liste de diffusion Perl