All Euler problems
Project Euler

Mountain Range

The elevation at point (x, y) is given by h(x,y) = (5000 - 0.005(x^2 + y^2 + xy) + 12.5(x+y)) * e^(-|0.000001(x^2+y^2) - 0.0015(x+y) + 0.7|). A mosquito wants to fly from A = (200, 200) to B = (140...

Source sync Apr 19, 2026
Problem #0262
Level Level 16
Solved By 863
Languages C++, Python
Answer 2531.205
Length 651 words
geometrymodular_arithmeticoptimization

Problem Statement

This archive keeps the full statement, math, and original media on the page.

The following equation represents the continuous topography of a mountainous region, giving the elevation \(h\) at any point \((x, y)\): \[h = \left (5000 - \frac {x^2 + y^2 + xy}{200} + \frac {25(x + y)}2\right ) \cdot e^{-\left |\frac {x^2 + y^2}{1000000} - \frac {3(x + y)}{2000} + \frac 7 {10}\right |}.\] A mosquito intends to fly from \(A(200,200)\) to \(B(1400,1400)\), without leaving the area given by \(0 \le x, y \le 1600\).

Because of the intervening mountains, it first rises straight up to a point \(A^\prime \), having elevation \(f\). Then, while remaining at the same elevation \(f\), it flies around any obstacles until it arrives at a point \(B^\prime \) directly above \(B\).

First, determine \(f_{\mathrm {min}}\) which is the minimum constant elevation allowing such a trip from \(A\) to \(B\), while remaining in the specified area.

Then, find the length of the shortest path between \(A^\prime \) and \(B^\prime \), while flying at that constant elevation \(f_{\mathrm {min}}\).

Give that length as your answer, rounded to three decimal places.

Note: For convenience, the elevation function shown above is repeated below, in a form suitable for most programming languages:

\(h=( 5000-0.005*(x*x+y*y+x*y)+12.5*(x+y) ) * \exp ( -\operatorname {abs}(0.000001*(x*x+y*y)-0.0015*(x+y)+0.7) )\)

Problem 262: Mountain Range

Mathematical Development

Theorem 1 (Symmetry). The elevation function satisfies h(x,y)=h(y,x)h(x, y) = h(y, x) for all (x,y)R2(x, y) \in \mathbb{R}^2. Consequently, the landscape is symmetric about the line y=xy = x.

Proof. Both the polynomial factor P(x,y)=50000.005(x2+y2+xy)+12.5(x+y)P(x,y) = 5000 - 0.005(x^2 + y^2 + xy) + 12.5(x + y) and the exponent g(x,y)=0.000001(x2+y2)0.0015(x+y)+0.7g(x,y) = 0.000001(x^2 + y^2) - 0.0015(x + y) + 0.7 involve only the symmetric expressions x2+y2x^2 + y^2, xyxy, and x+yx + y. Since P(x,y)=P(y,x)P(x,y) = P(y,x) and g(x,y)=g(y,x)g(x,y) = g(y,x), we have h(x,y)=h(y,x)h(x,y) = h(y,x). \square

Theorem 2 (Mountain ridge structure). Define g(x,y)=0.000001(x2+y2)0.0015(x+y)+0.7g(x,y) = 0.000001(x^2 + y^2) - 0.0015(x + y) + 0.7. The zero set C={(x,y):g(x,y)=0}\mathcal{C} = \{(x,y) : g(x,y) = 0\} is the circle

C:(x750)2+(y750)2=425000,\mathcal{C}: (x - 750)^2 + (y - 750)^2 = 425000,

of center (750,750)(750, 750) and radius 425000651.9\sqrt{425000} \approx 651.9. On C\mathcal{C}, the exponential factor attains its maximum value e0=1e^0 = 1. Away from C\mathcal{C}, g>0|g| > 0 and the exponential decays, so the elevation is concentrated near C\mathcal{C}, forming an annular mountain range.

Proof. Setting g=0g = 0: 0.000001(x2+y2)=0.0015(x+y)0.70.000001(x^2 + y^2) = 0.0015(x + y) - 0.7, so x2+y2=1500(x+y)700000x^2 + y^2 = 1500(x + y) - 700000. Completing the square: (x750)2+(y750)2=7502+7502700000=1125000700000=425000(x - 750)^2 + (y - 750)^2 = 750^2 + 750^2 - 700000 = 1125000 - 700000 = 425000. The exponential factor ege^{-|g|} is maximized precisely when g=0|g| = 0, i.e., on C\mathcal{C}. \square

Theorem 3 (Minimax characterization of fminf_{\min}). The value fminf_{\min} equals the minimax elevation:

fmin=infγΓ(A,B)max(x,y)γh(x,y),f_{\min} = \inf_{\gamma \in \Gamma(A,B)} \max_{(x,y) \in \gamma} h(x,y),

where Γ(A,B)\Gamma(A,B) is the set of continuous paths from AA to BB in [0,1600]2[0,1600]^2. The infimum is attained at a saddle point (pinch point) of hh on the mountain ridge.

Proof. Since A=(200,200)A = (200,200) lies inside the circle C\mathcal{C} and B=(1400,1400)B = (1400,1400) lies outside, any continuous path from AA to BB must cross the high-elevation ridge near C\mathcal{C}. The minimax elevation is the lowest value ff such that the sub-level set {hf}\{h \le f\} contains a connected path from AA to BB. This occurs when the barrier {h>f}\{h > f\} ceases to separate AA from BB, which happens at a saddle point where the barrier pinches to zero width. By the symmetry of hh and the geometry of the domain, the relevant saddle lies on the xx-axis (where y=0y = 0). Numerical optimization of h(x,0)h(x, 0) locates the saddle at x895.483x^* \approx 895.483 with fmin=h(x,0)10396.462f_{\min} = h(x^*, 0) \approx 10396.462. By symmetry, a second saddle exists at (0,y)(0, y^*) with y895.483y^* \approx 895.483. \square

Theorem 4 (Shortest path structure). At elevation fminf_{\min}, the shortest horizontal path from the vertical through AA to the vertical through BB consists of at most two straight-line segments (tangent to the contour {h=fmin}\{h = f_{\min}\}) and arcs along the contour, threading through the pinch point.

Proof. The passable region {hfmin}\{h \le f_{\min}\} at the critical elevation has the pinch point as a bottleneck. In a planar region bounded by a smooth curve, the shortest path between two points consists of straight-line segments in the interior and geodesic arcs along the boundary. At transition points PP and QQ, the tangency condition requires hAP\nabla h \perp \overrightarrow{AP} at PP and hQB\nabla h \perp \overrightarrow{QB} at QQ (the gradient of the constraint function is normal to the boundary, and the straight segment must be tangent to the boundary at the junction). The path is therefore:

AParcpincharcQB.A \to P \xrightarrow{\text{arc}} \text{pinch} \xrightarrow{\text{arc}} Q \to B.

\square

Editorial

h(x,y) = (5000 - 0.005*(x^2+y^2+xy) + 12.5(x+y)) A mosquito flies from A(200,200) to B(1400,1400) within 0<=x,y<=1600. It ascends to elevation f, flies horizontally at f, then descends. Find f_min (minimum elevation allowing such trip), then the shortest horizontal path at f_min, rounded to 3 decimal places. Solution approach: 1. f_min = minimax elevation = 10396.462193 (peak on y=0 boundary at x=895.483). 2. The barrier {h > f_min} is an annular (ring-shaped) region. It has a “pinch point” at (895.483, 0) where the barrier width is zero. By symmetry h(x,y)=h(y,x), another pinch exists at (0, 895.483). 3. The shortest path from A to B goes: A -> PA -> arc(PA, pinch) -> arc(pinch, Q) -> Q -> B where PA is tangent from A to the outer contour (left branch), and Q is tangent from B to the outer contour (right branch). The arc goes through the pinch point at (895.483, 0). 4. PA = (624.650, 48.254), Q = (1536.043, 873.038). 5. Path = 450.948 + 276.452 + 1259.565 + 544.239 = 2531.205. We numerically maximize h(x, 0) over x in [800, 1000] via bounded optimization. We then find tangent point P on outer-left contour branch. Finally, find tangent point Q on outer-right contour branch.

Pseudocode

Numerically maximize h(x, 0) over x in [800, 1000] via bounded optimization
Find tangent point P on outer-left contour branch:
Find tangent point Q on outer-right contour branch:
Compute total path length:
Round to 3 decimal places

Complexity Analysis

  • Time: O(N)O(N) for contour tracing with NN steps; O(log(1/ϵ))O(\log(1/\epsilon)) bisection iterations for tangent-point finding; O(N)O(N) for arc-length integration. Total: O(N)O(N) where NN is the contour resolution (inversely proportional to step size).
  • Space: O(1)O(1) auxiliary storage (contour traced incrementally without storing all points).

Answer

2531.205\boxed{2531.205}

Code

Each problem page includes the exact C++ and Python source files from the local archive.

C++ project_euler/problem_262/solution.cpp
#include <bits/stdc++.h>
using namespace std;

/*
 * Problem 262: Mountain Range
 *
 * h(x,y) = (5000 - 0.005*(x^2+y^2+x*y) + 12.5*(x+y))
 *         * exp(-|0.000001*(x^2+y^2) - 0.0015*(x+y) + 0.7|)
 *
 * Find f_min (minimax elevation A(200,200) to B(1400,1400)),
 * then shortest path at f_min through the pinch point.
 *
 * The barrier {h > f_min} is ring-shaped with a pinch at (895.483, 0).
 * f_min = max h(x,0) = h(895.483, 0) ≈ 10396.462.
 *
 * Path: A -> PA(tangent) -> arc to pinch -> arc to Q(tangent) -> B
 * PA ≈ (624.650, 48.254), Q ≈ (1536.043, 873.038)
 *
 * Approach: numerical contour tracing and tangent finding.
 *
 * Answer: 2531.205
 */

double h_func(double x, double y) {
    double t1 = x*x + y*y + x*y;
    double t2 = x*x + y*y;
    double base = 5000.0 - 0.005*t1 + 12.5*(x+y);
    double ex = fabs(0.000001*t2 - 0.0015*(x+y) + 0.7);
    return base * exp(-ex);
}

double dh_dx(double x, double y) {
    const double eps = 1e-7;
    return (h_func(x+eps, y) - h_func(x-eps, y)) / (2*eps);
}

double dh_dy(double x, double y) {
    const double eps = 1e-7;
    return (h_func(x, y+eps) - h_func(x, y-eps)) / (2*eps);
}

// Find x on contour h=f at given y, scanning from left or right
double find_contour_x(double y, double f, bool from_left) {
    double prev = h_func(from_left ? 0 : 1600, y) - f;
    int start = from_left ? 1 : 1599;
    int end = from_left ? 1601 : -1;
    int step = from_left ? 1 : -1;
    for (int xi = start; xi != end; xi += step) {
        double cur = h_func(xi, y) - f;
        if (prev * cur < 0) {
            // Bisect
            double lo = from_left ? xi-1.0 : (double)xi;
            double hi = from_left ? (double)xi : xi+1.0;
            for (int i = 0; i < 60; i++) {
                double mid = (lo+hi)/2;
                if ((h_func(mid, y) - f) * (h_func(lo, y) - f) <= 0)
                    hi = mid;
                else
                    lo = mid;
            }
            return (lo+hi)/2;
        }
        prev = cur;
    }
    return -1;
}

double trace_arc(double x0, double y0, double x1, double y1, double f, double step_size=0.05) {
    double x = x0, y = y0;
    double total = 0;
    for (int i = 0; i < 500000; i++) {
        double gx = dh_dx(x, y);
        double gy = dh_dy(x, y);
        double t1x = -gy, t1y = gx;
        double t2x = gy, t2y = -gx;
        double dx = x1-x, dy = y1-y;
        double tx, ty;
        if (t1x*dx + t1y*dy > t2x*dx + t2y*dy)
            tx = t1x, ty = t1y;
        else
            tx = t2x, ty = t2y;
        double tn = sqrt(tx*tx + ty*ty);
        if (tn < 1e-12) break;
        tx /= tn; ty /= tn;
        double nx = x + step_size*tx;
        double ny = y + step_size*ty;
        // Project to contour
        for (int j = 0; j < 5; j++) {
            double hv = h_func(nx, ny);
            double gx2 = dh_dx(nx, ny);
            double gy2 = dh_dy(nx, ny);
            double g2 = gx2*gx2 + gy2*gy2;
            if (g2 < 1e-20) break;
            double corr = (hv - f) / g2;
            nx -= corr * gx2;
            ny -= corr * gy2;
        }
        total += sqrt((nx-x)*(nx-x) + (ny-y)*(ny-y));
        x = nx; y = ny;
        double d = sqrt((x-x1)*(x-x1) + (y-y1)*(y-y1));
        if (d < step_size * 2) {
            total += d;
            break;
        }
    }
    return total;
}

int main() {
    // Find f_min: max of h(x,0)
    double best_x = 895, best_h = h_func(895, 0);
    for (double x = 890; x <= 900; x += 0.001) {
        double hv = h_func(x, 0);
        if (hv > best_h) { best_h = hv; best_x = x; }
    }
    double f_min = best_h;
    double pinch_x = best_x;
    fprintf(stderr, "f_min = %.6f at x = %.6f\n", f_min, pinch_x);

    // Find tangent PA from A(200,200) on left branch
    // Binary search on y where tangent residual changes sign
    auto tangent_res_A = [&](double y) {
        double xl = find_contour_x(y, f_min, true);
        if (xl < 0) return 1e10;
        double gx = dh_dx(xl, y);
        double gy = dh_dy(xl, y);
        return gx*(xl-200) + gy*(y-200);
    };

    double lo = 40, hi = 50;
    for (int i = 0; i < 60; i++) {
        double mid = (lo+hi)/2;
        if (tangent_res_A(mid) < 0) lo = mid; else hi = mid;
    }
    double y_PA = (lo+hi)/2;
    double x_PA = find_contour_x(y_PA, f_min, true);
    fprintf(stderr, "PA = (%.6f, %.6f)\n", x_PA, y_PA);

    // Find tangent Q from B(1400,1400) on right branch
    auto tangent_res_B = [&](double y) {
        double xr = find_contour_x(y, f_min, false);
        if (xr < 0) return 1e10;
        double gx = dh_dx(xr, y);
        double gy = dh_dy(xr, y);
        return gx*(xr-1400) + gy*(y-1400);
    };

    lo = 870; hi = 875;
    for (int i = 0; i < 60; i++) {
        double mid = (lo+hi)/2;
        if (tangent_res_B(mid) < 0) lo = mid; else hi = mid;
    }
    double y_Q = (lo+hi)/2;
    double x_Q = find_contour_x(y_Q, f_min, false);
    fprintf(stderr, "Q = (%.6f, %.6f)\n", x_Q, y_Q);

    // Compute path
    double d_APA = sqrt((200-x_PA)*(200-x_PA) + (200-y_PA)*(200-y_PA));
    double arc1 = trace_arc(x_PA, y_PA, pinch_x, 0, f_min);
    double arc2 = trace_arc(pinch_x, 0, x_Q, y_Q, f_min);
    double d_QB = sqrt((x_Q-1400)*(x_Q-1400) + (y_Q-1400)*(y_Q-1400));

    double total = d_APA + arc1 + arc2 + d_QB;
    fprintf(stderr, "d(A,PA)=%.3f + arc1=%.3f + arc2=%.3f + d(Q,B)=%.3f = %.3f\n",
            d_APA, arc1, arc2, d_QB, total);
    printf("%.3f\n", total);
    return 0;
}