Skip to content

Commit 7b5ca10

Browse files
committed
-
1 parent 5765c2c commit 7b5ca10

File tree

3 files changed

+61
-19
lines changed

3 files changed

+61
-19
lines changed

source_py3/python_toolbox/math_tools/sequences.py

Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import numbers
55
import collections
6-
6+
import itertools
77

88
infinity = float('inf')
99

@@ -60,29 +60,60 @@ def abs_stirling(n, k):
6060

6161
_shitfuck_cache = {}
6262

63-
def get_sub_counters(counter):
63+
def get_sub_counters_counter(counter):
64+
from python_toolbox import nifty_collections
6465
assert isinstance(counter, nifty_collections.FrozenCounter)
65-
return {
66+
return nifty_collections.FrozenCounter({
6667
nifty_collections.FrozenCounter(
67-
{key: (value - (key == key_to_reduce)) for key, value in self.items()}
68-
) for key_to_reduce in self
69-
}
68+
{key: (value - (key == key_to_reduce)) for
69+
key, value in counter.items()}
70+
): value_of_key_to_reduce
71+
for key_to_reduce, value_of_key_to_reduce in counter
72+
})
7073

7174

7275
def shitfuck(k, recurrence_counter):
7376
from python_toolbox import nifty_collections
74-
assert isinstance(recurrence_counter, nifty_collections.FrozenCounter)
77+
from python_toolbox import cute_iter_tools
78+
if not isinstance(recurrence_counter, nifty_collections.FrozenCounter):
79+
recurrence_counter = \
80+
nifty_collections.FrozenCounter(recurrence_counter)
81+
if k == 1:
82+
assert recurrence_counter # Works because `FrozenCounter` implements
83+
# `__bool__`.
84+
return 1
85+
try:
86+
return _shitfuck_cache[(k, recurrence_counter)]
87+
except KeyError:
88+
pass
89+
7590
levels = []
7691
current_reccurence_counters = {recurrence_counter}
77-
while len(levels) < k and any(((k - len(levels) + 1), recurrence_counter)
78-
not in _shitfuck_cache for x in levels[-1]):
79-
new_level = {}
80-
for recurrence_counter_ in current_reccurence_counters:
81-
new_level[recurrence_counter_] =
82-
for smaller_recurrence_counter in recurrence_counter_.counters_with_one_removed:
83-
new_level[(k - len(levels), smaller_recurrence_counter)] += factor
84-
levels.append(new_level)
92+
while len(levels) < k and current_reccurence_counters:
93+
levels.append(
94+
{recurrence_counter_: get_sub_counters_counter(recurrence_counter_)
95+
for recurrence_counter_ in current_reccurence_counters
96+
if recurrence_counter_ not in _shitfuck_cache
97+
})
98+
current_reccurence_counters = set(itertools.chain(levels[-1].values()))
99+
85100
# The last level is calculated. Time to make our way up.
86-
if len(levels) == k:
101+
for k_, level in enumerate(reversed(levels), (k - len(levels) + 1)):
102+
if k_ == 1:
103+
continue
104+
elif k_ == 2:
105+
for recurrence_counter_, sub_counters_counter in \
106+
levels.pop().items():
107+
_shitfuck_cache[(k_, recurrence_counter_)] = \
108+
sub_counters_counter.n_elements
109+
else:
110+
for recurrence_counter_, sub_counters_counter in level.items():
111+
_shitfuck_cache[(k_, recurrence_counter_)] = sum(
112+
(_shitfuck_cache[(k_ - 1, sub_counter)] * factor for
113+
sub_counter, factor in sub_counters_counter)
114+
)
115+
116+
return _shitfuck_cache[(k, recurrence_counter)]
87117

118+
88119

source_py3/python_toolbox/nifty_collections/frozen_counter.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
import itertools
77
import collections
88

9-
from python_toolbox import caching
10-
119
from .lazy_tuple import LazyTuple
1210
from .frozen_dict import FrozenDict
1311

@@ -205,3 +203,9 @@ def __and__(self, other):
205203
result[element] = new_count
206204
return FrozenCounter(result)
207205

206+
207+
__bool__ = lambda self: any(True for element in self.elements())
208+
209+
n_elements = property( # blocktodo: want to make this cached but import loop
210+
lambda self: sum(value for value in values if value >= 1)
211+
)

source_py3/test_python_toolbox/test_math_tools/test_sequences.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
from python_toolbox.math_tools import abs_stirling
1+
2+
3+
from python_toolbox.math_tools import abs_stirling, shitfuck
24

35

46
def test_abs_stirling():
@@ -13,3 +15,8 @@ def test_abs_stirling():
1315
35, 10, 1, 0)
1416

1517
assert abs_stirling(200, 50) == 525010571470323062300307763288024029929662200077890908912803398279686186838073914722860457474159887042512346530620756231465891831828236378945598188429630326359716300315479010640625526167635598138598969330736141913019490812196987045505021083120744610946447254207252791218757775609887718753072629854788563118348792912143712216969484697600
18+
19+
20+
def test_shitfuck():
21+
assert shitfuck(3, (3, 1, 1)) == 13
22+

0 commit comments

Comments
 (0)