Enumerating all 3-tuples

Steven D'Aprano steve+comp.lang.python at pearwood.info
Wed Mar 21 01:14:30 EDT 2018


On Tue, 13 Mar 2018 23:56:37 +0100, Denis Kasak wrote:

[...]
> The triples can be viewed as a pair of a pair and a natural number:
> 
> (1,1),1 (1,1),2 (1,1),3 ...
> (2,1),1 (2,1),2 (2,1),3 ...
> (1,2),1 (1,2),2 (1,2),3 ...

[...]
> This leads fairly naturally to the implementation.
> 
>      from itertools import accumulate, count
> 
>      def c(i):
>          """
>          Inverse of the Cantor pairing function, mapping N → N×N. """
>          assert i >= 1
> 
>          # partial sums of the series 1 + 2 + 3 + ... sums =
>          accumulate(count(1))
>          n = 0
> 
>          while True:
>              m = next(sums)
>              if m < i:
>                  n += 1
>              else:
>                  r = m - i
>                  break
> 
>          return r + 1, n - r + 1
> 
> 
>      def c3(i):
>          """
>          Inverse of the Cantor pairing function generalization to
> triples,
>          mapping N → N×N×N.
>          """
>          n, m = c(i)
>          return c(n) + (m,)
> 
> Applying c3 to the natural numbers gives the sequence you wanted:


Thanks!

That looks interesting, I haven't had a chance to play with it in a lot 
of detail yet, but it looks to me like every time you generate a triple, 
it starts counting up from 1.

So iterating over c3(1), c3(2), c3(4), ... c3(something big) is going to 
have O(N**2) performance. It's like the old joke about the Polish painter:

http://global.joelonsoftware.com/English/Articles/BacktoBasics.html

Since that's exactly what I need to do, that might be a problem.

On the other hand, I doubt I'll need to generate more than a few thousand 
of these, so it might be fast enough. I guess I have to run some 
benchmarks to find out.

But however they turn out, I appreciate your time and code. Thanks heaps!



-- 
Steve




More information about the Python-list mailing list