Repository navigation
Conversation
sum_of_divisors only multiplied in the prime factors it found while trial-dividing, so any prime factor above the trial-division bound was dropped: 94 of the first 119 inputs returned the wrong answer (sum_of_divisors(3) -> 1 instead of 4, sum_of_divisors(12) -> 7 instead of 28). number_of_divisors in the same file already handles this case with `if n > 1: div *= 2`. Also compute with // instead of /: the function accumulated a float and truncated with int(s), so sum_of_divisors(2**62) returned 9223372036854775808 instead of 9223372036854775807 and large inputs were off by orders of magnitude (3**40 was wrong by ~10^4). math.isqrt replaces int(math.sqrt(n)) for the same reason. Verified against an independent factorization of sigma(n) for n = 1..50000: 0 mismatches.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Describe your change
master.Checklist
Description
maths/basic_maths.py::sum_of_divisorsreturned the wrong value for most inputs.Two defects in the same function:
The leftover prime factor was dropped. The function trial-divides by 2, then by odd
iup tosqrt(n), multiplying in the geometric-series term for each prime power it finds. Whatever prime factor remains above that bound at the end was never multiplied in. Its siblingnumber_of_divisorsin the same file does handle this (if n > 1: div *= 2), sosum_of_divisorswas missing the analogous step. Consequence:sum_of_divisors(3)returned1instead of4, and 94 of the first 119 integers were wrong.The arithmetic was done in floats.
int(n / 2),int(n / i), the/in the geometric series, and the finalint(s)truncated away the low bits, so large inputs were wrong by orders of magnitude:Changes
if n > 1: s *= n + 1step, mirroringnumber_of_divisorsin the same file.n //= 2,n //= i,//in the geometric series,math.isqrt(n)for the trial-division bound (replacingint(math.sqrt(n))), and drop the now-redundantint(s).sum_of_divisors(100) == 217doctest is unchanged and still passes.How I tested
Regression proof — before the change, against an independent factorization of
σ(n) = ∏ (p^(e+1) − 1)/(p − 1):
After the change,
sum_of_divisors(n) == sigma_exact(n)for every n in1..50000 (0 mismatches). All the new doctest cases fail on current
master:Submitted with gh CLI by @bougieL