-
Notifications
You must be signed in to change notification settings - Fork 312
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Template for modulo operations #40
base: master
Are you sure you want to change the base?
Template for modulo operations #40
Conversation
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 |
There was a problem hiding this 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): |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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): |
There was a problem hiding this comment.
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: |
There was a problem hiding this comment.
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.
8399462
to
ccb5210
Compare
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]) |
There was a problem hiding this comment.
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. 🙂
This is probably not necessary anymore since 64bit has become the standard |
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.