cg-Cad

Lisp »Tips 'n Tricks »Traduttore »1 »2 »3 »4

N2c

;|

   N2C.LSP (C) 2005 by Claudio Piccini.
   www.cg-cad.com

   Traduce un numero in lettere
   Es. 145 -> centoquarantacinque

   Limiti: 
   valore max. 9999999
   1974   -> unomillenovecentosettantaquattro
   101000 -> centounomille

|;

(defun c:n2c ( / lstUnit lstDec lst10_19
                 numero stringa lstr nc7 i
                 n1 n2 n3 n4 n5 n6 n7
                 cNumero
 )

 (setq lstUnit 
  (list 
   "zero" "uno" "due" "tre" "quattro" "cinque" 
   "sei" "sette" "otto" "nove"
  )
 )

 (setq lstDec 
  (list 
   "zero" "dieci" "venti" "trenta" "quaranta" "cinquanta" 
   "sessanta" "settanta" "ottanta" "novanta"
  )
 )

 (setq lst10_19 
  (list 
   "zero" "dieci" "undici" "dodici" "tredici" "quattordici" "quindici" 
   "sedici" "diciassette" "diciotto" "diciannove"
  )
 )

 (setq numero (getreal "\n numero? "))
 
 (setq stringa (rtos numero 2 0))

 (setq lstr (strlen stringa)) ; strlen restituisce la lunghezza di una stringa

 (setq nc7 (- 7 lstr))

 (setq i 0)
 (while (< i nc7)
  (setq stringa (strcat "0" stringa))
  (setq i (1+ i)) 
 )

 (setq n1 (atoi(substr stringa 7 1))
       n2 (atoi(substr stringa 6 1))
       n3 (atoi(substr stringa 5 1))
       n4 (atoi(substr stringa 4 1))
       n5 (atoi(substr stringa 3 1))
       n6 (atoi(substr stringa 2 1))
       n7 (atoi(substr stringa 1 1))
 )

 (cond
  ((= n7 0)(setq cNumero ""))
  ((= n7 1)(setq cNumero "unmilione"))
  ((> n7 1)(setq cNumero (strcat (nth n7 lstUnit) "milioni")))
 )

 (cond 
  ((= n6 0)(setq cNumero (strcat cNumero ""))) ; spazio
  ((= n6 1)(setq cNumero (strcat cNumero "cento")))
  ((> n6 1)(setq cNumero (strcat cNumero (nth n6 lstUnit) "cento")))
 )

 (if (= n5 0)
  (setq cNumero (strcat cNumero "")) ; spazio
  (if (= n4 0)
   (setq cNumero (strcat cNumero (nth n5 lstDec)))
   (if (= n5 1)
    (setq cNumero (strcat cNumero (nth (1+ n4) lst10_19) "mila"))
    (setq cNumero (strcat cNumero (nth n5 lstDec)))
   )
  )
 ) 

 (if (= n4 0)
  (setq cNumero (strcat cNumero "")) ; spazio
  (if (= n5 1)
   (setq cNumero (strcat cNumero "")) ; spazio
   (setq cNumero (strcat cNumero (nth n4 lstUnit)))
  )
 )
 
 (if (= (+ n4 n5 n6) 0)
  (setq cNumero (strcat cNumero "")) ; spazio
  (if (= n4 1)
   (setq cNumero (strcat cNumero "mille"))
   (setq cNumero (strcat cNumero "mila"))
  )
 )

 (if (= n3 0)
  (setq cNumero (strcat cNumero "")) ; spazio
  (if (= n3 1)
   (setq cNumero (strcat cNumero "cento"))
   (setq cNumero (strcat cNumero (nth n3 lstUnit) "cento"))
  )
 )

 (if (= n2 0)
  (setq cNumero (strcat cNumero "")) ; spazio
  (if (= n1 0)
   (setq cNumero (strcat cNumero (nth n2 lstDec)))
   (if (= n2 1)
    (setq cNumero (strcat cNumero (nth (1+ n1) lst10_19)))
    (setq cNumero (strcat cNumero (nth n2 lstDec)))
   )
  )
 )

 (if (= n1 0)
  (setq cNumero (strcat cNumero "")) ; spazio
  (if (= n2 1)
   (setq cNumero (strcat cNumero "")) ; spazio
   (setq cNumero (strcat cNumero (nth n1 lstUnit)))
  )
 )
)
;;;eof

Test del lisp

Command: n2c
numero? 1234567
"unmilioneduecentotrentaquattromilacinquecentosessantasette"

N2C
numero? 9999999
"novemilioninovecentonovantanovemilanovecentonovantanove"

N2C
numero? 145
"centoquarantacinque"

N2C
numero? 157
"centocinquantasette"

N2C
numero? 890
"ottocentonovanta"

N2C
numero? 567
"cinquecentosessantasette"

N2C
numero? 444
"quattrocentoquarantaquattro"

N2C
numero? 1974
"unomillenovecentosettantaquattro"

N2C
numero? 1000200
"unmilioneduecento"

N2C
numero? 101000
"centounomille"

Analisi del lisp

Questo lisp è la traduzione in AutoLISP di un sorgente di Comet (programma free per il computo metrico).
Con l'istruzione (setq stringa (rtos numero 2 0)) traduco il numero reale in una stringa di caratteri, es. 123 -> "123".
L'istruzione (setq lstr (strlen stringa)) mi restituisce in lstr la lunghezza della stringa; salvo nella variabile nc7 il numero di cifre necessarie per completare un numero di 7 cifre:
(setq nc7 (- 7 lstr))
All'interno di un ciclo (while () ...) occupo gli spazi vuoti con il carattere "0":
(setq i 0)
(while (< i nc7)
(setq stringa (strcat "0" stringa))
(setq i (1+ i))
)

Salvo nelle variabili n1 n2 n3 n4 n5 n6 n7 il relativo numero intero; cioè per mezzo della funzione (substr stringa posizione lunghezza) estraggo il carattere e con la funzione (atoi stringa) lo trasformo in un numero intero.
(setq n1 (atoi(substr stringa 7 1))
n2 (atoi(substr stringa 6 1))
n3 (atoi(substr stringa 5 1))
n4 (atoi(substr stringa 4 1))
n5 (atoi(substr stringa 3 1))
n6 (atoi(substr stringa 2 1))
n7 (atoi(substr stringa 1 1))
)

Quindi lo trasformo in una stringa. Con i limiti evidenziati nel test.

A questo punto, nel sorgente in xbase, è facile intervenire sulla stringa e aggiustare il tiro...

  if len(cRetVal) > 0
     cRetVal := strTran(cRetVal,"oo","o")
     cRetVal := strTran(cRetVal,"tao","to")
     cRetVal := strTran(cRetVal,"tiu","tu")
     cRetVal := strTran(cRetVal,"tio","to")
     cRetVal := strTran(cRetVal,"tau","tu")
     if at("unomille",cRetVal) != 0 .and. at("unomille",cRetVal) = 1
        cRetVal := strTran(cRetVal,"unomille","mille")
     endif   
     if at("mille",cRetVal) != 0 .and. at("mille",cRetVal) > 1
        cRetVal := strTran(cRetVal,"mille","mila")
     endif
     cRetVal := strTran(cRetVal,"unmilioneunomila","unmilionemille")
     cRetVal := strTran(cRetVal,"milioniunomila","milionimille")
     cRetVal := strTran(cRetVal,"milamila","mila")
     cRetVal += "/" + ltrim(str(n0,2,0))
  else
     cRetVal := ltrim(str(n0,2,0))
  endif

...più difficile interagire con una stringa in autolisp :)

Lisp »Tips 'n Tricks

Ultimo Aggiornamento_Last Update: 20 Aprile 2005