Skip to content

Conversation

@bjorn-martinsson
Copy link
Collaborator

One of the most common codes that I've looked up over time is a mod template that I wrote many years ago for a private repository. It is useful enough to be used around once every second competition.

I cleaned up my old code, and added some extra features to it. I think this could be a super useful template to have on PyRival!

Note that I have yet to add tests to it, I will do that tomorrow.

@cheran-senthil What do you think about this template? I think it is both very simple and super useful to have.

@bjorn-martinsson
Copy link
Collaborator Author

As a small note on the fast mod mul. Locally on my windows computer using PyPy the code runs around a factor of 10 faster with modmul compared to doing a * b % MOD.

Copy link
Owner

@cheran-senthil cheran-senthil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can move this to the misc folder, and probably decide on naming later. Overall, I'm quite happy with the code, and we can merge whenever you think this is ready.

or calculate matrix multiplication mod MOD.
"""

def fast_modder(MOD):
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps call this make_modmul?


def fast_modder(MOD):
""" Returns function modmul(a,b) that quickly calculates a * b % MOD, assuming 0 <= a,b < MOD """
import sys, platform
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm tempted to move this up, to the top of the file, even though this is specific.

def redu(x):
return x if x < MOD else x - MOD

def matrix_modmul(A, B):
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have something for this elsewhere, so let's remove that too.

import sys, platform
impl = platform.python_implementation()
maxs = sys.maxsize
if 'PyPy' in impl and MOD <= maxs and MOD ** 2 > maxs:
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can actually check impl == 'PyPy'. Seems to work on PyPy3 as well.

@cheran-senthil
Copy link
Owner

With the new version of PyPy on Windows, what are your thoughts on this moving forward?

@bjorn-martinsson
Copy link
Collaborator Author

With the new version of PyPy on Windows, what are your thoughts on this moving forward?

Once CF updates (assuming it ever updates) then we can remove all the fast modmul stuff from the template. But I still think this template has its uses even after that.

""" Calculate n choose k in O(1) time """
if k < 0 or k > n:
return 0
return modmul(modmul(fac[n], fac_inv[k]), fac_inv[n - k])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fac_inv should be inv_fac here. 🙂

@cheran-senthil
Copy link
Owner

This is probably not necessary anymore since 64bit has become the standard

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants