# Re: function that counts...

Discussion in 'Python' started by Raymond Hettinger, May 24, 2010.

1. ### Raymond HettingerGuest

On May 19, 12:58 pm, superpollo <> wrote:
> ... how many positive integers less than n have digits that sum up to m:
>
> In [197]: def prttn(m, n):
>      tot = 0
>      for i in range(n):
>          s = str(i)
>          sum = 0
>          for j in range(len(s)):
>              sum += int(s[j])
>          if sum == m:
>              tot += 1
>     .....:
>
> In [207]: prttn(25, 10000)
> Out[207]: 348
>
> any suggestion for pythonizin' it?

Not sure it is an improvement to reroll it into a one-liner:

def prttn(m, n):
return sum(m == sum(map(int, str(x))) for x in range(n))
>>> prttn(25, 10000)

348

Some people find the functional style easier to verify because of
fewer auxilliary variables and each step is testable independently.
The m==sum() part is not very transparent because it relies on
True==1, so it's only readable if it becomes a common idiom (which it
could when you're answering questions of the form "how many numbers
have property x").

If speed is important, the global lookups can be localized:

def prttn(m, n, map=itertools.imap, int=int, str=str, range=range):
return sum(m == sum(map(int, str(x))) for x in range(n))

Raymond

Raymond Hettinger, May 24, 2010

2. ### Matteo LandiGuest

What about avoiding the string conversion and use mod/div operations
in order to create a list of digits for a number?

Now that you have the sequences it's easy to count which sums up to m.

On Mon, May 24, 2010 at 4:14 PM, Raymond Hettinger <> wrote:
> On May 19, 12:58 pm, superpollo <> wrote:
>> ... how many positive integers less than n have digits that sum up to m:
>>
>> In [197]: def prttn(m, n):
>> tot = 0
>> for i in range(n):
>> s = str(i)
>> sum = 0
>> for j in range(len(s)):
>> sum += int(s[j])
>> if sum == m:
>> tot += 1
>> .....:
>>
>> In [207]: prttn(25, 10000)
>> Out[207]: 348
>>
>> any suggestion for pythonizin' it?

>
> Not sure it is an improvement to reroll it into a one-liner:
>
> def prttn(m, n):
> return sum(m == sum(map(int, str(x))) for x in range(n))
>>>> prttn(25, 10000)

> 348
>
> Some people find the functional style easier to verify because of
> fewer auxilliary variables and each step is testable independently.
> The m==sum() part is not very transparent because it relies on
> True==1, so it's only readable if it becomes a common idiom (which it
> could when you're answering questions of the form "how many numbers
> have property x").
>
> If speed is important, the global lookups can be localized:
>
> def prttn(m, n, map=itertools.imap, int=int, str=str, range=range):
> return sum(m == sum(map(int, str(x))) for x in range(n))
>
> Raymond
>
>
>
> --
> http://mail.python.org/mailman/listinfo/python-list
>

--
Matteo Landi
http://www.matteolandi.net/

Matteo Landi, May 24, 2010

3. ### BryanGuest

Raymond Hettinger wrote:
> If speed is important, the global lookups can be localized:
>
> def prttn(m, n, map=itertools.imap, int=int, str=str, range=range):
>     return sum(m == sum(map(int, str(x))) for x in range(n))

That's just silly. "If speed is important," we abandon the naive
algorithm.

--
--Bryan

Bryan, May 26, 2010