Rounded Square Roots
Define the "rounded square root" algorithm for a positive integer n: 1. Let d be the number of digits of n. 2. If d is odd, set x_0 = 2 x 10^((d-1)/2). If d is even, set x_0 = 7 x 10^((d-2)/2). 3....
Problem Statement
This archive keeps the full statement, math, and original media on the page.
We define the rounded-square-root of a positive integer $n$ as the square root of $n$ rounded to the nearest integer.
The following procedure (essentially Heron's method adapted to integer arithmetic) finds the rounded-square-root of $n$:
Let $d$ be the number of digits of the number $n$.
If $d$ is odd, set $x_0 = 2 \times 10^{(d-1)/2}$.
If $d$ is even, set $x_0 = 7 \times 10^{(d-2)/2}$.
Repeat: $$x_{k+1} = \Biggl\lfloor{\dfrac{x_k + \lceil{n / x_k}\rceil}{2}}\Biggr\rfloor$$ until $x_{k+1} = x_k$.
As an example, let us find the rounded-square-root of $n = 4321$.
$n$ has $4$ digits, so $x_0 = 7 \times 10^{(4-2)/2} = 70$.
$x_0 = 7 \times 10^{(4-2)/2} = 70$.
$$x_1 = \Biggl\lfloor{\dfrac{70 + \lceil{4321 / 70}\rceil}{2}}\Biggr\rfloor = 66$$ $$x_2 = \Biggl\lfloor{\dfrac{66 + \lceil{4321 / 66}\rceil}{2}}\Biggr\rfloor = 66$$ Since $x_2 = x_1$, we stop here.
So, after just two iterations, we have found that the rounded-square-root of $4321$ is $66$ (the actual square root is $65.7343137\cdots$).
The number of iterations required when using this method is surprisingly low.
For example, we can find the rounded-square-root of a $5$-digit integer ($10\,000 \le n \le 99\,999$) with an average of $3.2102888889$ iterations (the average value was rounded to $10$ decimal places).
Using the procedure described above, what is the average number of iterations required to find the rounded-square-root of a $14$-digit number ($10^{13} \le n < 10^{14}$)?
Give your answer rounded to $10$ decimal places.
Note: The symbols $\lfloor x \rfloor$ and $\lceil x \rceil$ represent the floor function and ceiling function respectively.
Problem 255: Rounded Square Roots
Mathematical Foundation
Lemma 1 (Fixed Range). All integers in have exactly digits (even), so the initial guess is .
Proof. An integer has digits if and only if . For , we have . Since is even, .
Theorem 1 (Convergence). The iteration is an integer variant of Newton’s method for . For any and any initial , the sequence converges to a fixed point satisfying , i.e., is the nearest integer to (rounded up on half-integers).
Proof. Newton’s method for gives the iteration . The integer variant uses ceiling division and floor of the average. One can verify:
- If , then , and (the sequence is non-increasing once above the fixed point).
- If , then , and .
- The sequence is eventually monotone and bounded, hence convergent.
The fixed-point condition characterizes as the rounded square root.
Theorem 2 (Grouping by Quotient). For fixed , the values of producing a given ceiling quotient form the interval . The next iterate is then , which is constant over this interval.
Proof. By definition of ceiling division, iff , i.e., . Since depends on only through , all in this interval share the same .
Editorial
Average number of iterations of the rounded square root algorithm for n from 10^13 to 10^14 - 1. All numbers have 14 digits (even), so x0 = 7 * 10^6 = 7000000. Iteration: x_{k+1} = floor((x_k + ceil(n/x_k)) / 2) Stop when x_{k+1} == x_k. Interval-based approach: track (x_current, n_lo, n_hi) and split by ceil(n/x) values at each step. We use a map: x_value -> count_of_n_values. We then initially, all n in [N_lo, N_hi] start with x = x0. Finally, converged: these n values took iteration iterations.
Pseudocode
Use a map: x_value -> count_of_n_values
Initially, all n in [N_lo, N_hi] start with x = x0
For each distinct q = ceil(n/x), compute x_next
Converged: these n values took `iteration` iterations
else
Continue iterating: group by x_next
Complexity Analysis
- Time: At each iteration, the number of groups is (since the number of distinct ceiling quotients for a given over is by the divisor-bound argument). With iterations, the total is . For : approximately .
- Space: for storing the groups at each iteration level.
Answer
Code
Each problem page includes the exact C++ and Python source files from the local archive.
#include <bits/stdc++.h>
using namespace std;
/*
* Problem 255: Rounded Square Roots
*
* For n from 10^13 to 10^14-1 (14 digits, d=14, even): x0 = 7*10^6
* Iteration: x_{k+1} = floor((x_k + ceil(n/x_k)) / 2)
* Stop when x_{k+1} == x_k.
*
* Interval-based approach: track (x, n_lo, n_hi) groups and split by
* ceil(n/x) values at each step. For fixed x, x_next = floor((x+q)/2)
* where q = ceil(n/x). Each x_next value corresponds to 2 consecutive q values.
*
* Answer: 4.4474011180
*/
typedef long long ll;
ll ceildiv(ll a, ll b) {
return (a + b - 1) / b;
}
int main(){
const ll N_LO = 10000000000000LL;
const ll N_HI = 99999999999999LL;
const ll TOTAL = N_HI - N_LO + 1;
const int x0 = 7000000;
struct Interval {
int x;
ll nlo, nhi;
};
vector<Interval> current;
current.push_back({x0, N_LO, N_HI});
long double total_iterations = 0;
while (!current.empty()) {
// Process one iteration
map<int, vector<pair<ll,ll>>> next_map;
ll converged_count = 0;
// We need iteration number for weighting. Track separately.
// Actually we increment a counter.
static int iter = 0;
iter++;
for (auto& [x, nlo, nhi] : current) {
ll q_lo = ceildiv(nlo, (ll)x);
ll q_hi = ceildiv(nhi, (ll)x);
ll xn_lo = ((ll)x + q_lo) / 2;
ll xn_hi = ((ll)x + q_hi) / 2;
for (ll xn = xn_lo; xn <= xn_hi; xn++) {
ll q1 = max(2LL * xn - x, q_lo);
ll q2 = min(2LL * xn + 1 - x, q_hi);
if (q1 > q2) continue;
ll n1 = max((q1 - 1) * x + 1, nlo);
ll n2 = min(q2 * x, nhi);
if (n1 > n2) continue;
if (xn == x) {
converged_count += n2 - n1 + 1;
} else {
next_map[(int)xn].push_back({n1, n2});
}
}
}
total_iterations += (long double)converged_count * iter;
current.clear();
for (auto& [xn, intervals] : next_map) {
sort(intervals.begin(), intervals.end());
ll lo = intervals[0].first, hi = intervals[0].second;
for (size_t i = 1; i < intervals.size(); i++) {
if (intervals[i].first <= hi + 1) {
hi = max(hi, intervals[i].second);
} else {
current.push_back({xn, lo, hi});
lo = intervals[i].first;
hi = intervals[i].second;
}
}
current.push_back({xn, lo, hi});
}
}
long double avg = total_iterations / (long double)TOTAL;
printf("%.10Lf\n", avg);
return 0;
}
"""
Problem 255: Rounded Square Roots
Average number of iterations of the rounded square root algorithm
for n from 10^13 to 10^14 - 1.
All numbers have 14 digits (even), so x0 = 7 * 10^6 = 7000000.
Iteration: x_{k+1} = floor((x_k + ceil(n/x_k)) / 2)
Stop when x_{k+1} == x_k.
Interval-based approach: track (x_current, n_lo, n_hi) and split by
ceil(n/x) values at each step.
Answer: 4.4474011180
"""
from collections import defaultdict
def ceildiv(a, b):
return (a + b - 1) // b
def solve():
N_LO = 10**13
N_HI = 10**14 - 1
TOTAL = N_HI - N_LO + 1
x0 = 7000000
# State: list of (x, n_lo, n_hi)
current = [(x0, N_LO, N_HI)]
total_iterations = 0.0
iteration = 0
while current:
iteration += 1
next_map = defaultdict(list) # x_next -> [(nlo, nhi)]
converged_count = 0
for x, nlo, nhi in current:
q_lo = ceildiv(nlo, x)
q_hi = ceildiv(nhi, x)
xn_lo = (x + q_lo) // 2
xn_hi = (x + q_hi) // 2
for xn in range(xn_lo, xn_hi + 1):
q1 = max(2 * xn - x, q_lo)
q2 = min(2 * xn + 1 - x, q_hi)
if q1 > q2:
continue
n1 = max((q1 - 1) * x + 1, nlo)
n2 = min(q2 * x, nhi)
if n1 > n2:
continue
if xn == x:
converged_count += n2 - n1 + 1
else:
next_map[xn].append((n1, n2))
total_iterations += converged_count * iteration
# Merge intervals
current = []
for xn, intervals in sorted(next_map.items()):
intervals.sort()
lo, hi = intervals[0]
for i in range(1, len(intervals)):
if intervals[i][0] <= hi + 1:
hi = max(hi, intervals[i][1])
else:
current.append((xn, lo, hi))
lo, hi = intervals[i]
current.append((xn, lo, hi))
avg = total_iterations / TOTAL
print(f"{avg:.10f}")
if __name__ == "__main__":
solve()