Square Root Digital Expansion
For the first one hundred natural numbers, find the total of the digital sums of the first one hundred decimal digits for all irrational square roots.
Problem Statement
This archive keeps the full statement, math, and original media on the page.
It is well known that if the square root of a natural number is not an integer, then it is irrational. The decimal expansion of such square roots is infinite without any repeating pattern at all.
The square root of two is \(1.41421356237309504880\cdots \), and the digital sum of the first one hundred decimal digits is \(475\).
For the first one hundred natural numbers, find the total of the digital sums of the first one hundred decimal digits for all the irrational square roots.
Problem 80: Square Root Digital Expansion
Mathematical Foundation
Theorem 1 (Irrationality Criterion). For a positive integer , is irrational if and only if is not a perfect square.
Proof. () Suppose is not a perfect square and with , , . Then . Let be a prime dividing to an odd power (such a prime exists since is not a perfect square). Then is odd, while is even. This contradicts .
() If , then .
Lemma 1 (Perfect Squares in Range). The perfect squares in are , totaling 10 values. Thus we compute for irrational square roots.
Proof. , so there are exactly 10 perfect squares: .
Theorem 2 (High-Precision Extraction). To obtain the first 100 decimal digits of (for non-square ), it suffices to compute and take the first 100 digits of in decimal.
Proof. We have since (the floor of an integer times a positive number distributes when the base is a perfect square, i.e., ).
For , , so , meaning has at most 101 digits. The first 100 digits of (from the left) represent the first 100 significant decimal digits of (including digits before and after the decimal point).
More precisely: if has digits before the decimal point (where for and for , but is excluded), then has digits, and the first 100 digits of give integer-part digits plus fractional digits, totaling 100 significant digits.
Theorem 3 (Newton’s Method for Integer Square Roots). Given a positive integer , the sequence defined by and
converges to . The convergence is quadratic, and termination occurs when , at which point .
Proof. Let . We show:
(i) For : (strictly decreasing). Since , we have , so:
(ii) For : (stays above the answer). By AM-GM:
Taking the floor: .
(iii) Termination: The sequence is strictly decreasing and bounded below by , so it must reach in finitely many steps. At that point, . Since , we have , so , giving (since and ). Thus , and we terminate.
(iv) Quadratic convergence: Let . Then , which follows from the standard Newton’s method analysis. The number of iterations is .
Editorial
The filtering step is immediate: only non-squares matter, because perfect squares have rational square roots and are excluded by the statement. For every remaining , we scale by so that
contains the first 100 significant digits of as an integer. That turns a decimal-digit problem into an integer square-root problem.
After computing that integer root, we read off its first 100 decimal digits, sum them, and add the result to the global total. So the candidates are simply the non-squares from to , and the only filtering is the perfect-square check before the high-precision extraction.
Pseudocode
Precompute the perfect squares up to 100.
Set the running total to 0.
For each n from 1 to 100:
If n is a perfect square, skip it
Compute r = floor(sqrt(n x 10^198))
Read the first 100 decimal digits of r
Add their digit sum to the running total
Return the running total.
Complexity Analysis
Time: For each of the 90 non-square values of , we compute using Newton’s method. The number has digits. Each Newton iteration performs one division and one addition of -digit numbers, costing where is the multiplication/division cost for -digit integers (e.g., with schoolbook, with FFT). Newton’s method converges in iterations (quadratic convergence from an initial guess).
- Time: where
With schoolbook arithmetic (): .
Space: Each integer has digits.
- Space: per computation, total
Answer
Code
Each problem page includes the exact C++ and Python source files from the local archive.
#include <bits/stdc++.h>
using namespace std;
// Simple big integer class for this problem
// We use Python-style arbitrary precision via strings and manual arithmetic
// Actually, for C++ we'll use __int128 won't suffice (need ~200 digits).
// We'll implement a simple big integer with vector<int> digits.
struct BigInt {
vector<int> d; // digits in base 10^9, least significant first
static const int BASE = 1000000000;
BigInt() {}
BigInt(long long v) {
if (v == 0) d.push_back(0);
while (v > 0) {
d.push_back(v % BASE);
v /= BASE;
}
}
bool isZero() const {
return d.empty() || (d.size() == 1 && d[0] == 0);
}
// Compare: -1, 0, 1
int cmp(const BigInt& o) const {
if (d.size() != o.d.size()) return d.size() < o.d.size() ? -1 : 1;
for (int i = (int)d.size() - 1; i >= 0; i--) {
if (d[i] != o.d[i]) return d[i] < o.d[i] ? -1 : 1;
}
return 0;
}
bool operator>=(const BigInt& o) const { return cmp(o) >= 0; }
bool operator>(const BigInt& o) const { return cmp(o) > 0; }
bool operator<(const BigInt& o) const { return cmp(o) < 0; }
bool operator==(const BigInt& o) const { return cmp(o) == 0; }
BigInt operator+(const BigInt& o) const {
BigInt res;
int carry = 0;
int n = max(d.size(), o.d.size());
res.d.resize(n);
for (int i = 0; i < n; i++) {
long long s = carry;
if (i < (int)d.size()) s += d[i];
if (i < (int)o.d.size()) s += o.d[i];
res.d[i] = s % BASE;
carry = s / BASE;
}
if (carry) res.d.push_back(carry);
return res;
}
BigInt operator*(const BigInt& o) const {
BigInt res;
res.d.assign(d.size() + o.d.size(), 0);
for (int i = 0; i < (int)d.size(); i++) {
long long carry = 0;
for (int j = 0; j < (int)o.d.size(); j++) {
long long cur = (long long)d[i] * o.d[j] + res.d[i + j] + carry;
res.d[i + j] = cur % BASE;
carry = cur / BASE;
}
if (carry) res.d[i + o.d.size()] += carry;
}
while (res.d.size() > 1 && res.d.back() == 0) res.d.pop_back();
return res;
}
// Division by 2
BigInt div2() const {
BigInt res;
res.d.resize(d.size());
long long carry = 0;
for (int i = (int)d.size() - 1; i >= 0; i--) {
long long cur = carry * BASE + d[i];
res.d[i] = cur / 2;
carry = cur % 2;
}
while (res.d.size() > 1 && res.d.back() == 0) res.d.pop_back();
return res;
}
// Division: this / o (integer division)
BigInt divBy(const BigInt& o) const {
// Simple long division
BigInt res;
BigInt rem;
res.d.resize(d.size(), 0);
for (int i = (int)d.size() - 1; i >= 0; i--) {
// rem = rem * BASE + d[i]
rem.d.insert(rem.d.begin(), d[i]);
while (rem.d.size() > 1 && rem.d.back() == 0) rem.d.pop_back();
// Binary search for quotient digit
int lo = 0, hi = BASE - 1, best = 0;
while (lo <= hi) {
int mid = lo + (hi - lo) / 2;
BigInt prod = o * BigInt(mid);
if (prod.cmp(rem) <= 0) {
best = mid;
lo = mid + 1;
} else {
hi = mid - 1;
}
}
res.d[i] = best;
BigInt sub = o * BigInt(best);
// rem = rem - sub
long long borrow = 0;
for (int j = 0; j < (int)rem.d.size(); j++) {
long long val = (long long)rem.d[j] - borrow;
if (j < (int)sub.d.size()) val -= sub.d[j];
if (val < 0) {
val += BASE;
borrow = 1;
} else {
borrow = 0;
}
rem.d[j] = val;
}
while (rem.d.size() > 1 && rem.d.back() == 0) rem.d.pop_back();
}
while (res.d.size() > 1 && res.d.back() == 0) res.d.pop_back();
return res;
}
string toString() const {
if (d.empty()) return "0";
string s = to_string(d.back());
for (int i = (int)d.size() - 2; i >= 0; i--) {
string t = to_string(d[i]);
s += string(9 - t.size(), '0') + t;
}
return s;
}
int digitSum(int numDigits) const {
string s = toString();
int sum = 0;
for (int i = 0; i < min(numDigits, (int)s.size()); i++) {
sum += s[i] - '0';
}
return sum;
}
};
// Integer square root using Newton's method
BigInt isqrt(const BigInt& n) {
if (n.isZero()) return BigInt(0);
// Initial guess: start high
BigInt x = n;
BigInt y = (x + n.divBy(x)).div2();
while (y < x) {
x = y;
y = (x + n.divBy(x)).div2();
}
return x;
}
int main() {
// Compute 10^198
BigInt power(1);
for (int i = 0; i < 198; i++) {
power = power * BigInt(10);
}
set<int> perfect_squares = {1, 4, 9, 16, 25, 36, 49, 64, 81, 100};
int total = 0;
for (int n = 1; n <= 100; n++) {
if (perfect_squares.count(n)) continue;
BigInt N = BigInt(n) * power;
BigInt root = isqrt(N);
total += root.digitSum(100);
}
cout << total << endl;
return 0;
}
"""
Problem 80: Square Root Digital Expansion
For the first 100 natural numbers, find the total of the digital sums
of the first 100 decimal digits for all irrational square roots.
Answer: 40886
"""
from math import isqrt
def main():
scale = 10**198
perfect_squares = {i * i for i in range(1, 11)}
total = 0
for n in range(1, 101):
if n in perfect_squares:
continue
root = isqrt(n * scale)
digits = str(root)[:100]
total += sum(int(c) for c in digits)
print(total)
if __name__ == "__main__":
main()