mercoledì 4 gennaio 2017

Perl: come si scrivono i numeri?

Dovendo insegnare a mio figlio la matematica di base, ovvero i numeri, ho passato qualche minuto nello scrivere un semplice programmino Perl che mostra come si scrivono i nomi dei numeri in italiano.
Il giro è abbastanza semplice: si definiscono degli array per i nomi delle unità e delle decine, dopodiché si divide il numero per le decine in modo da ottenere il numero aritmeticamente scomposto.
Come esempio, da 57 si ottiene 50 + 7. Con questi due valori si estraggono i nomi simbolici di decine e unità, poi si tagliano le eventuali vocali doppie nell'unione dei nomi.
Ovviamente una complicazione è data dal range 10-20, quello dei teen.


#!/usr/bin/env perl

use v5.10;

my $units = {
         1 => 'uno'
       , 2 => 'due'
       , 3 => 'tre'
       , 4 => 'quattro'
       , 5 => 'cinque'
       , 6 => 'sei'
       , 7 => 'sette'
       , 8 => 'otto'
       , 9 => 'nove'
       , 0 => ''
};


my $tenths = {
   10 => 'dieci'
       , 11 => 'undici'
       , 12 => 'dodici'
       , 13 => 'tredici'
       , 14 => 'quattordici'
       , 15 => 'quindici'
       , 16 => 'sedici'
       , 17 => 'diciassette'
       , 18 => 'diciannove'
       , 20 => 'venti'
       , 30 => 'trenta'
       , 40 => 'quaranta'
       , 50 => 'cinquanta'
       , 60 => 'sessanta'
       , 70 => 'settanta'
       , 80 => 'ottanta'
       , 90 => 'novanta'
       , 100 => 'cento'
};


for my $value ( 1..99 ){


   my ( $unita, $decine ) = 0;

   if ( $value < 10 ){
       $unita  = $value;
       $decine = 0;
   } elsif ( $value >= 10 && $value < 20 ){
       $unita  = 0;
       $decine = $value;
   }
   else{
       $unita  = $value % 10;
       $decine = $value - $unita;
   }
   

   my $risultato = sprintf "%s %s %s = %s %s %s",
   ( $tenths->{ $decine }  ? $tenths->{ $decine } : "" ),
   ( $tenths->{ $decine }  && $units->{ $unita }  ? "+" : "" ),
   ( $units->{ $unita }  ? $units->{ $unita } : "" ),
   ( $tenths->{ $decine }  ? $tenths->{ $decine } : "" ),
   ( $tenths->{ $decine }  && $units->{ $unita }  ? "+" : "" ),
   ( $units->{ $unita }  ? $units->{ $unita } : "" );

   my $slang = $tenths->{ $decine };
   if ( $tenths->{ $decine } =~ /[aeiou]$/
        && $units->{ $unita } =~ /^[aeiou]/ ){
       $slang =~ s/[aeiou]$//;
   }
   $slang .= $units->{ $unita };
   say "$value si compone di $risultato\n\te si legge \t" . uc( $slang );
}



Il risultato finale è qualcosa di simile:



90 si compone di  90 + 0 = novanta
       e si legge      NOVANTA
91 si compone di  90 + 1 = novanta + uno
       e si legge      NOVANTUNO
92 si compone di  90 + 2 = novanta + due
       e si legge      NOVANTADUE
93 si compone di  90 + 3 = novanta + tre


Nessun commento: