Counting letters in a number between 1 and 1000

  • #1
ergospherical
Gold Member
346
462
Excluding spaces and hyphens, how many letters are there in a given number between 1 and 1000 (inclusive)? How can I make my algorithm more efficient?

Python:
dig_lens = [4,3,3,5,4,4,3,5,5,4]
tens_lens = [0,3,6,6,6,5,5,7,6,6]
teens_lens = [0,6,6,8,8,7,7,9,8,8]

def num_letters(n):
    nlist = []
    while(n>=1):
        nlist.append(n%10)
        n//=10
    length = len(nlist)

    if(n==1000):
        return 11

    count = 0
    if(length == 1):
        count = count + dig_lens[n]

    if(length == 2):
        if(nlist[1]==1 and nlist[0]>0):
            count = count + teens_lens[nlist[0]]
        else:
            count = count + tens_lens[nlist[1]] + dig_lens[nlist[0]]

    if(length == 3):
        count = count + dig_lens[nlist[2]] + 7
        if(nlist[1]==0 and nlist[0]>0):
            count = count + 3 + dig_lens[nlist[0]]
        elif(nlist[1]==1 and nlist[0]>0):
            count = 3 + count + teens_lens[nlist[0]]
        else:
            count = 3 + count + tens_lens[nlist[1]] + dig_lens[nlist[0]]

    return count

##e.g.##
print(num_letters(816))
 

Answers and Replies

  • #2
DaveC426913
Gold Member
20,010
3,282
Does it ever pronounce "hundred"?
 
  • #3
ergospherical
Gold Member
346
462
it does pronounce hundred - that's accounted for in the first line of the length=3 case!
 
Last edited:
  • #4
DaveC426913
Gold Member
20,010
3,282
OK, I see what you're doing. Hundred is "+7".
Eleven is "6".
 
  • Like
Likes ergospherical
  • #5
pbuk
Science Advisor
Gold Member
2,506
1,245
If length == 1 then you do not need to test if length == 2 (use elif) Edit: or if you are done then return the answer.

You could use count += instead of count = count + ... but if count is 0 then you don't need to include it in any sums anyway. Edit: you hardly need an intermediate count, if you know the answer just return it.

Edit: use more spaces and use them consistently

Python:
dig_lens = [4, 3, 3, 5, 4, 4, 3, 5, 5, 4]
tens_lens = [0, 3, 6, 6, 6, 5, 5, 7, 6, 6]
teens_lens = [0, 6, 6, 8, 8, 7, 7, 9, 8, 8]


def num_letters(n):
    nlist = []
    while n >= 1:
        nlist.append(n % 10)
        n //= 10
    length = len(nlist)

    if n == 1000:
        return 11

    if length == 1:
        return dig_lens[n]

    if length == 2:
        if nlist[1] == 1 and nlist[0] > 0:
            return teens_lens[nlist[0]]
        else:
            return tens_lens[nlist[1]] + dig_lens[nlist[0]]

    if length == 3:
        count = dig_lens[nlist[2]] + 7
        if nlist[1] == 0 and nlist[0] > 0:
            return count + 3 + dig_lens[nlist[0]]
        if nlist[1] == 1 and nlist[0] > 0:
            return count + 3 + teens_lens[nlist[0]]
        else:
            return count + 3 + tens_lens[nlist[1]] + dig_lens[nlist[0]]

    raise RuntimeError("Can't handle more than 1,000")


##e.g.##
print(num_letters(10000))
 
Last edited:
  • Like
Likes ergospherical
  • #6
DaveC426913
Gold Member
20,010
3,282
Notice that the size of the number is an input, which means a user might not cooperate with the constraints. How robust is your program if the input parameter were 1,001? Or 10,000?

See how flexible and universal and bulletproof you can make it.
 
  • Like
Likes ergospherical
  • #7
ergospherical
Gold Member
346
462
Edit: you hardly need an intermediate count, if you know the answer just return it.
Yeah, I started thinking I was going to try and do some clever recursive algorithm, but realised it'd just be easier to split it into cases - but didn't get rid of the intermediate count.
 
  • #8
pbuk
Science Advisor
Gold Member
2,506
1,245
Sorry, I have edited and re-edited my code, bad habit. It is prettier now. Should have just passed it through the Black parser straight off, my typing is a bit haphazard after a Friday night in the pub for the first time in 18 months.
 
Last edited:
  • Haha
Likes Filip Larsen and sysprog
  • #9
DaveC426913
Gold Member
20,010
3,282
Comments are good, for those who are trying to review your code.
I had a bunch of false starts before I got a handle on what it was doing.
 
  • #10
Filip Larsen
Gold Member
1,440
348
if n == 1000:
return 11
Looks like that test should use the original value of n to trigger properly?
 
  • #11
ergospherical
Gold Member
346
462
Looks like that test should use the original value of n to trigger properly?
whoopsie, yeah that and the length=1 case ought to be before the loop
 

Related Threads on Counting letters in a number between 1 and 1000

Replies
3
Views
2K
  • Last Post
Replies
5
Views
772
Replies
1
Views
2K
  • Last Post
Replies
18
Views
10K
Replies
5
Views
11K
  • Last Post
Replies
12
Views
1K
Top