-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathranker.py
78 lines (63 loc) · 1.67 KB
/
ranker.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from sage.misc.cachefunc import cached_method
class OnFly:
"""
Returns a pair of enumeration functions rank / unrank.
rank assigns on the fly an integer, starting from 0, to any object
passed as argument. The object should be hashable. unrank is the
inverse function; it returns None for indices that have not yet
been assigned.
EXAMPLES::
sage: rank, unrank = on_fly()
sage: rank('a')
0
sage: rank('b')
1
sage: rank('c')
2
sage: rank('a')
0
sage: unrank(2)
'c'
sage: unrank(3)
sage: rank('d')
3
sage: unrank(3)
'd'
Test pickling::
sage: import __main__ # Won't be needed when in a proper module / in Sage
sage: __main__.OnFly = OnFly
sage: rank1, unrank1 = loads(dumps([rank, unrank]))
sage: rank1.cache
{(('a',), ()): 0, (('b',), ()): 1, (('c',), ()): 2, (('d',), ()): 3}
sage: rank1('a')
0
sage: rank1('b')
1
sage: rank1('e')
4
sage: unrank(4)
sage: unrank1(4)
'e'
.. todo:: add tests as in combinat::rankers
"""
def count():
i = 0
while True:
yield i
i+=1
counter = count()
def __init__(self):
self.i = -1
@cached_method(do_pickle=True)
def rank(self, x):
self.i = self.i + 1
self.unrank.set_cache(x, self.i)
return self.i
@cached_method(do_pickle=True)
def unrank(self, i):
return None
def on_fly():
o = OnFly()
return [o.rank, o.unrank]