Spelling Numbers in Words: A solution

R←SpellNumber number;⎕IO;units;tens;thousands;numgroups;vals;group;h;t;u

⎕IO←0
number←⌊⍬⍴number

⍝ Names of numbers 0 - 19: NB 0 is blank
units←'' 'one' 'two' 'three' 'four' 'five' 'six' 'seven' 'eight' 'nine'
units←units, 'ten' 'eleven' 'twelve' 'thirteen' 'fourteen' 'fifteen'
units←units, 'sixteen' 'seventeen' 'eighteen' 'nineteen'

⍝ Names of tens: NB 0 and 10 are blank
tens←'' '' 'twenty' 'thirty' 'forty' 'fifty' 'sixty' 'seventy' 'eighty' 'ninety'

⍝ Names of thousands groups
thousands←'trillion' 'billion' 'million' 'thousand' 'zero'    

:If number = 0
  R←'zero'
:Else
  ⍝ Decode |number and loop to handle in groups of a thousand
  R←''
  numgroups←↑⍴thousands
  vals←(numgroups⍴1000) ⊤ |number
  :For group :In ⍳numgroups
    :If 0≠vals[group]
      ⍝ Get hundreds, tens and units
      (h t u)←10 10 10 ⊤ vals[group]
    
      ⍝ Adjust for teens, e.g. 1 3 -> 0 13
      (t u)←t u + ¯1 10 × t = 1
    
      ⍝ Put comma before any hundreds if not first
      R←R,((0≠⍴R)^0≠h)/', '
    
      ⍝ Handle any hundreds
      R←R,(0≠h)/(⊃units[h]), ' hundred'

      ⍝ Want 'and' if anything left in group and not at start of whole thing
      R←R,((0≠⍴R)^0≠t+u)/' and '
    
      ⍝ Handle tens and units, possibly with hyphen as in 'twenty-six'
      R←R,⊃tens[t]
      R←R,(^/0≠t u)/'-'
      R←R,⊃units[u]
    
      ⍝ Put 'thousand', etc
      :If group < numgroups - 1
        R←R,' ',⊃thousands [group]
      :EndIf
    :EndIf
  :EndFor
:EndIf

⍝ Add any 'minus ' at the front
R←((number<0)/'minus '),R

⍝ First character to uppercase
R[0]←⎕A [⎕a⍳R[0]]

<< The task

   

Author: SimonMarsden

SpellNumbers/Solution (last edited 2010-03-26 15:29:45 by SimonMarsden)