2
\$\begingroup\$

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)
\$\endgroup\$

closed as unclear what you're asking by J42161217, Shaggy, mbomb007, Magic Octopus Urn, HyperNeutrino Aug 17 '17 at 23:46

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 1
    \$\begingroup\$ @DJMcMayhem They're similar, but certainly not duplicates. \$\endgroup\$ – Trebuchette Aug 17 '17 at 17:03
  • 1
    \$\begingroup\$ You were quite short on tags :/ \$\endgroup\$ – Mr. Xcoder Aug 17 '17 at 17:09
  • 1
    \$\begingroup\$ IMHO, 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. \$\endgroup\$ – mbomb007 Aug 17 '17 at 18:10
  • 1
    \$\begingroup\$ @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? \$\endgroup\$ – 0WJYxW9FMN Aug 17 '17 at 19:24
  • 1
    \$\begingroup\$ Possible duplicate of Count up by Syllables \$\endgroup\$ – HyperNeutrino Aug 17 '17 at 23:46
1
\$\begingroup\$

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

\$\endgroup\$
  • \$\begingroup\$ 237 bytes, starter, much more left to golf I think \$\endgroup\$ – Mr. Xcoder Aug 17 '17 at 19:33
  • \$\begingroup\$ Would a>1000 => a>1e3 work? \$\endgroup\$ – Zacharý Aug 17 '17 at 20:02
  • \$\begingroup\$ @Zacharý Indeed, 231 \$\endgroup\$ – Mr. Xcoder Aug 18 '17 at 22:06

Not the answer you're looking for? Browse other questions tagged or ask your own question.