Skip to content

Problem 252: add OEIS A307036 and A359060 (k = 3, 4); retain possible flag - #360

Merged
teorth merged 1 commit into
teorth:mainfrom
papanokechi:p252-oeis
Jul 31, 2026
Merged

Problem 252: add OEIS A307036 and A359060 (k = 3, 4); retain possible flag#360
teorth merged 1 commit into
teorth:mainfrom
papanokechi:p252-oeis

Conversation

@papanokechi

Copy link
Copy Markdown
Contributor

Problem #252 concerns the irrationality of $S_k = \sum_{n \ge 1} \sigma_k(n)/n!$. The entry already links $k = 1$ and $k = 2$. This adds the $k = 3$ and $k = 4$ constants. The "possible" flag is retained, since $k \ge 5$ is not covered (see below).

k OEIS name field, quoted verbatim
1 A227988 Decimal expansion of Sum_{n >= 1} sigma_1(n)/n!.
2 A227989 Decimal expansion of Sum_{n >= 1} sigma_2(n)/n!.
3 A307036 Decimal expansion of Sum_{k >= 1} sigma_3(k)/k!, where sigma_3(k) is the sum of cubes of the divisors of k (A001158).
4 A359060 Decimal expansion of Sum_{n >= 1} sigma_4(n)/n!.

The name fields are quoted verbatim so that functional equivalence with the problem statement can be judged without recomputation.

Verification

Each constant was computed two independent ways, both as exact rationals over 120 terms:

  • (A) direct $\sum \sigma_k(n)/n!$, with $\sigma_k$ obtained by trial division;
  • (B) the rearrangement $\sum_d d^k \sum_j 1/(jd)!$, which swaps the order of summation and so shares no code path with (A).

The two agree exactly on 40 truncated significant digits for every $k \in {1,\dots,6}$.

Each was then compared against the live OEIS data field, comparing truncated rather than rounded digits (see the companion issue #357):

k A-number agreement
1 A227988 exact over 87 digits
2 A227989 exact over 87 digits
3 A307036 exact over 87 digits
4 A359060 exact over 81 digits

An 80-digit agreement rules out coincidence, so identity is settled; the name quotes above are supplied so that the separate question of functional equivalence of description can be checked directly.

Code: stdlib-only apart from an optional urllib OEIS fetch, and it runs in well under a minute. It is reproduced in a comment below so it can be inspected and re-executed rather than taken on trust.

Why "possible" stays

$S_5$ and $S_6$ are not in the OEIS. By CONTRIBUTING.md's rule ("If you believe that there are still further sequences related to this problem that could be added in the future, keep the possible string"), the flag should therefore remain: the family is demonstrably incomplete.

I am deliberately not proposing an OEIS submission for them, since per the project's AI policy any OEIS submission must be human-originated. Recording the truncated values here only so the gap is visible to anyone who wants to pursue it:

S_5 = 143.8119639327382460893906480919610538206...
S_6 = 556.4071645455845889451656064554874344282...

AI disclosure

This PR was prepared with AI assistance (GitHub Copilot CLI). No sequence values were taken from a model: all figures come from code that was written, inspected and executed locally, and every constant was reproduced by two independent methods before being compared to OEIS. Nothing here is proposed for submission to the OEIS.

Both constants verified against the live OEIS data field to 87 and 81
digits respectively, using truncated rather than rounded comparison.
The 'possible' flag is retained because S_5 and S_6 are not in OEIS.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: cc8c383e-e43d-4ccd-be8c-1c339d66f08c
@papanokechi

Copy link
Copy Markdown
Contributor Author

Verification code, reproduced in full so it can be inspected and re-executed. Python 3, standard library only (the OEIS fetch uses urllib). Method A and method B share no code path.

"""
Erdos problem 252: S_k = sum_{n>=1} sigma_k(n) / n!

Recomputes the constants EXACTLY, reports them TRUNCATED (not rounded), and
re-verifies the four OEIS links through oeis_constant_match, which refuses to
round.

Two independent evaluations are retained as the anti-hallucination cross-check:
  (A) direct exact Fraction sum with sigma_k by trial division
  (B) rearranged  sum_d d^k sum_j 1/(jd)!  also as an exact Fraction sum
Both are exact rationals, so agreement is checked as exact equality of the
truncated digit strings rather than to a floating tolerance.
"""

from __future__ import annotations

import json
import time
import urllib.parse
import urllib.request
from fractions import Fraction
from math import factorial

from oeis_constant_match import compare_to_oeis, truncated_digits

N_TERMS = 120          # 120! dwarfs any precision we print
DIGITS_REPORT = 40
LINKS = {1: "A227988", 2: "A227989", 3: "A307036", 4: "A359060"}
UA = {"User-Agent": "erdos-oeis-check/1.0 (manual verification)"}


def sigma_k(n: int, k: int) -> int:
    """Sum of k-th powers of the divisors of n, by trial division."""
    total = 0
    d = 1
    while d * d <= n:
        if n % d == 0:
            total += d ** k
            other = n // d
            if other != d:
                total += other ** k
        d += 1
    return total


def method_a(k: int, n_terms: int = N_TERMS) -> Fraction:
    """Direct: sum sigma_k(n) / n!."""
    return sum((Fraction(sigma_k(n, k), factorial(n)) for n in range(1, n_terms + 1)),
               Fraction(0))


def method_b(k: int, n_terms: int = N_TERMS) -> Fraction:
    """Rearranged: sum_d d^k sum_j 1/(jd)!  -- swaps the order of summation."""
    total = Fraction(0)
    for d in range(1, n_terms + 1):
        inner = Fraction(0)
        j = 1
        while j * d <= n_terms:
            inner += Fraction(1, factorial(j * d))
            j += 1
        total += Fraction(d ** k) * inner
    return total


def _oeis_entry(anum: str) -> dict:
    url = f"https://oeis.org/search?fmt=json&q={urllib.parse.quote('id:' + anum)}"
    req = urllib.request.Request(url, headers=UA)
    with urllib.request.urlopen(req, timeout=60) as fh:
        payload = json.load(fh)
    # The API has returned both a bare list and a {"results": [...]} envelope.
    results = payload if isinstance(payload, list) else (payload.get("results") or [])
    if not results:
        raise RuntimeError(f"no OEIS result for {anum}")
    return results[0]


def oeis_data(anum: str) -> str:
    return _oeis_entry(anum)["data"]


def oeis_name(anum: str) -> str:
    return _oeis_entry(anum)["name"]


def main() -> None:
    print("=" * 78)
    print("Erdos 252: cross-check of the two independent evaluations")
    print("=" * 78)
    exact: dict[int, Fraction] = {}
    for k in range(1, 7):
        a = method_a(k)
        b = method_b(k)
        da = truncated_digits(a, DIGITS_REPORT)
        db = truncated_digits(b, DIGITS_REPORT)
        agree = da == db
        exact[k] = a
        print(f"k={k}: methods agree on {DIGITS_REPORT} truncated digits: {agree}")
        if not agree:
            raise SystemExit(f"METHODS DISAGREE at k={k}: {da} vs {db}")

    print()
    print("=" * 78)
    print(f"Constants, TRUNCATED to {DIGITS_REPORT} significant digits")
    print("=" * 78)
    for k in range(1, 7):
        digits = truncated_digits(exact[k], DIGITS_REPORT)
        intpart = len(str(int(exact[k])))
        shown = digits[:intpart] + "." + digits[intpart:]
        print(f"  k={k}: {shown}")

    print()
    print("=" * 78)
    print("OEIS verification (truncation-aware)")
    print("=" * 78)
    all_ok = True
    for k, anum in LINKS.items():
        data = oeis_data(anum)
        ok, n, detail = compare_to_oeis(exact[k], data)
        all_ok &= ok
        print(f"  k={k} -> {anum}: {'MATCH' if ok else 'FAIL'} ({n} digits)")
        print(f"      {detail}")
        print(f"      name: {oeis_name(anum)}")
        time.sleep(2)

    print()
    print(f"ALL FOUR LINKS VERIFIED: {all_ok}")


if __name__ == "__main__":
    main()

@teorth
teorth merged commit d41452e into teorth:main Jul 31, 2026
1 check passed
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.

2 participants