Syllables in a Number

2

Make a program/function which takes in an integer from 0 to 999999999999 (inclusive) as input and returns how many syllables it has when spoken in English. Make your code short.

Specification

  • A billion is a thousand million, a trillion is a million million, etc.
  • A million has three syllables -- it's mill-ee-on, as opposed to mill-yon. Pronounce all -illions like this.
  • Numbers like 1115 are 'one thousand, one hundred and fifteen'. The 'and' counts as a syllable.
  • 0 is zero. That's two syllables.

I know the specification seems mishmash in terms of which standards are used (British or American, mainly) -- it's what I and everyone I know use. I would change it so it's consistent, but someone's already answered...

Test Cases

> 0
2
(zero)

> 100
3
(one hundred)

> 1000001
6
(one million and one)

> 1001000001
10
(one billon, one million and one)

> 7
2
(seven)

> 28
3
(twenty-eight)

> 78
4
(seventy-eight)

> 11
3
(eleven)

> 1111
10
(one thousand, one hundred and eleven)

> 999999999999
36
(nine hundred and ninety-nine billion, nine hundred and ninety-nine million, nine hundred and ninety-nine thousand, nine hundred and ninety-nine)

0WJYxW9FMN

Posted 2017-08-17T16:42:23.070

Reputation: 2 663

Question was closed 2017-08-17T23:46:29.367

Possible duplicate of this one or this one

– James – 2017-08-17T16:59:25.930

1@DJMcMayhem They're similar, but certainly not duplicates. – Trebuchette – 2017-08-17T17:03:43.140

1You were quite short on tags :/ – Mr. Xcoder – 2017-08-17T17:09:02.673

Relevant OEIS, although I'm not sure how it copes with illions... – Dom Hastings – 2017-08-17T17:53:08.543

1IMHO, This specification is awful. "Billion" is used in American English, so if that's the standard you're using (it is, seeing your examples), then you shouldn't include and in the numbers, because that's grammatically incorrect, unless you're using British English, I think. So 1111 would be one thousand, one hundred, eleven). But British English uses "thousand million" instead of "billion". So you're mixing standards. – mbomb007 – 2017-08-17T18:10:14.037

1@mbomb007 I was just using what I use in real life. I'm British. I say 1111 as 'one thousand, one hundred and eleven' (which makes logical sense). What does 'mixing standards' take away from the challenge, though? – 0WJYxW9FMN – 2017-08-17T19:24:57.373

Personally, just as we fix typos and grammar mistakes in questions and answers, it feels bad to see it wrong in a challenge spec. – mbomb007 – 2017-08-17T20:58:46.707

@mbomb007 Seeing as someone's already answered, I'll just add a note in the description. – 0WJYxW9FMN – 2017-08-17T22:05:41.063

1

Possible duplicate of Count up by Syllables

– HyperNeutrino – 2017-08-17T23:46:29.367

1"Please clarify your specific problem or add additional details to highlight exactly what you need." Exactly what is wrong with the wording and level of detail? – 0WJYxW9FMN – 2017-08-18T21:17:02.693

This seems completely clear to me. Could one of the people who marked it as unclear maybe specify what's unclear about it? – benzene – 2017-08-19T02:37:25.850

Answers

1

Python 2, 232 bytes

def f(a):o=map(int,format(a,",").split(","));print(a%100>0)*(a>1000)+sum((k%100>0)*(k/100>0)for k in o[:-1])+sum((k>99)*2+`k`.count('7')+(k/10%10>0)+3-`k+1000`.count('0')for k in o)+sum((0<o[~k])*(5-k)*k/2for k in range(len(o)))or 2

Try it online!

This still has some potential for golfing, maybe in a lambda. The function splits the input into groups of three digits, each of which have a certain number of syllables. Luckily, every digit is 1 syllable except for 7. Every tens-place adds an extra 1 syllable to the number of syllables of the digit except for 1, which adds 0 (-teen or ten).

Ungolfed:

def f(k):
    a=k
    if a==0:return 2
    o=[]
    while a>0:
        o.append(a%1000)
        a/=1000
    o=o[::-1]
    return \
int(o[-1]%100>0 and len(o)>1)        +len('+1 if first group of three have "and"'[0:0])+\
sum(\
  [int(k%100>0 and k/100>0)        +len('+1 if rest have "and"'[0:0])\ 
for k in o[:-1]])+    
sum(\
  [int(k>99)*2                      +len('have "hundred"'[0:0])\
  +str(k).count('7')               +len('+1 for "se-ven"'[0:0])\
  +(k/10%10>0)                    +len('+1 for "-ty" e.g. nine-ty'[0:0])\
  +3-str(k+1000).count('0')        +len('+1 for each number'[0:0])\
for k in o])+\
sum(\
  [int(o[-(k+1)]>0)*([0,2,3,3][k])  +len('add 2 if "thousand", add 3 if "million", add 3 if "billion"'[0:0])\
for k in range(len(o))])

-12 bytes thanks to @Mr.Xcoder

fireflame241

Posted 2017-08-17T16:42:23.070

Reputation: 7 021

237 bytes, starter, much more left to golf I think – Mr. Xcoder – 2017-08-17T19:33:28.193

Would a>1000 => a>1e3 work? – Zacharý – 2017-08-17T20:02:13.583

@Zacharý Indeed, 231

– Mr. Xcoder – 2017-08-18T22:06:55.720