All Euler problems
Project Euler

Hilbert's Blackout

Consider a 2^n x 2^n grid of lights indexed by an order- n Hilbert curve. A blackout operation turns off lights at positions along the curve satisfying specific arithmetic conditions. Determine the...

Source sync Apr 19, 2026
Problem #0522
Level Level 29
Solved By 317
Languages C++, Python
Answer 96772715
Length 394 words
graphrecursionsequence

Problem Statement

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

Despite the popularity of Hilbert's infinite hotel, Hilbert decided to try managing extremely large finite hotels, instead.

To cut costs, Hilbert wished to power the new hotel with his own special generator. Each floor would send power to the floor above it, with the top floor sending power back down to the bottom floor. That way, Hilbert could have the generator placed on any given floor (as he likes having the option) and have electricity flow freely throughout the entire hotel.

Unfortunately, the contractors misinterpreted the schematics when they built the hotel. They informed Hilbert that each floor sends power to another floor at random, instead. This may compromise Hilbert's freedom to have the generator placed anywhere, since blackouts could occur on certain floors.

For example, consider a sample flow diagram for a three-story hotel:

Problem illustration

If the generator were placed on the first floor, then every floor would receive power. But if it were placed on the second or third floors instead, then there would be a blackout on the first floor. Note that while a given floor can receive power from many other floors at once, it can only send power to one other floor.

To resolve the blackout concerns, Hilbert decided to have a minimal number of floors rewired. To rewire a floor is to change the floor it sends power to. In the sample diagram above, all possible blackouts can be avoided by rewiring the second floor to send power to the first floor instead of the third floor.

Let $F(n)$ be the sum of the minimum number of floor rewirings needed over all possible power-flow arrangements in a hotel of $n$ floors. For example, $F(3) = 6$, $F(8) = 16276736$, and $F(100) \bmod 135707531 = 84326147$.

Find $F(12344321) \bmod 135707531$.

Problem 522: Hilbert’s Blackout

Mathematical Foundation

Theorem (Hilbert Curve Bijection). For every n1n \ge 1, the order-nn Hilbert curve defines a bijection

Hn:{0,1,,4n1}{0,,2n1}2H_n : \{0, 1, \ldots, 4^n - 1\} \to \{0, \ldots, 2^n - 1\}^2

such that consecutive indices map to grid-adjacent cells (sharing an edge).

Proof. We proceed by induction on nn.

Base case (n=1n = 1): The order-1 curve visits the four cells of a 2×22 \times 2 grid in the order (0,0)(0,1)(1,1)(1,0)(0,0) \to (0,1) \to (1,1) \to (1,0). Each consecutive pair is adjacent. The map is clearly a bijection on a 4-element set.

Inductive step: Assume Hn1H_{n-1} is a bijection on the (2n1)2(2^{n-1})^2 grid with the adjacency property. Partition the 2n×2n2^n \times 2^n grid into four 2n1×2n12^{n-1} \times 2^{n-1} quadrants. Define HnH_n by traversing:

  1. Bottom-left quadrant using Hn1H_{n-1} reflected about the diagonal (9090^\circ CW rotation),
  2. Top-left quadrant using Hn1H_{n-1} (unmodified),
  3. Top-right quadrant using Hn1H_{n-1} (unmodified),
  4. Bottom-right quadrant using Hn1H_{n-1} reflected about the anti-diagonal (9090^\circ CCW rotation).

Each quadrant contributes 4n14^{n-1} cells, giving 44n1=4n4 \cdot 4^{n-1} = 4^n total. The junction points between quadrants are adjacent by construction (the exit of one quadrant neighbors the entry of the next). By induction, within each quadrant consecutive indices are adjacent. Hence HnH_n is a bijection with the adjacency property. \square

Lemma (Self-Similar Counting). Let CnC_n denote the count of surviving lights after the blackout operation on an order-nn grid. If the blackout condition respects the 4-fold recursive structure of the Hilbert curve (i.e., the condition on index dd depends only on dmod4kd \bmod 4^k for some fixed kk), then CnC_n satisfies a linear recurrence of the form

Cn=αCn1+βC_n = \alpha \cdot C_{n-1} + \beta

for constants α,β\alpha, \beta determined by the blackout rule applied to the quadrant junctions.

Proof. When the blackout condition depends only on dmod4kd \bmod 4^k, the number of blackout positions in each quadrant of an order-nn curve is determined by the number of blackout positions in an order-(n1)(n-1) curve, shifted by a fixed offset modulo 4k4^k. Since the four quadrants tile the index space [0,4n)[0, 4^n) into four contiguous blocks of size 4n14^{n-1}, each block’s count depends on Cn1C_{n-1} plus a bounded correction from the offset. The correction is constant in nn for n>kn > k. \square

Editorial

Grid blackout puzzle on Hilbert curve grids. We base: enumerate all 4^k positions for small k. We then recursive: exploit self-similarity. Finally, determine counts for each quadrant transformation.

Pseudocode

Base: enumerate all 4^k positions for small k
Recursive: exploit self-similarity
Determine counts for each quadrant transformation
rotate quadrant

Complexity Analysis

  • Time (direct enumeration): O(4n)O(4^n), since all positions are visited.
  • Time (recursive, structure-respecting blackout): O(n)O(n), since the recurrence has constant cost per level.
  • Space: O(n)O(n) for the recursion stack, or O(4n)O(4^n) for direct enumeration.

Answer

96772715\boxed{96772715}

Code

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

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

// Hilbert curve coordinate conversion

pair<int,int> d2xy(int n, int d) {
    int x = 0, y = 0;
    for (int s = 1; s < (1 << n); s <<= 1) {
        int rx = (d & 2) ? 1 : 0;
        int ry = ((d & 1) ^ rx) ? 1 : 0;
        if (ry == 0) {
            if (rx == 1) {
                x = s - 1 - x;
                y = s - 1 - y;
            }
            swap(x, y);
        }
        x += s * rx;
        y += s * ry;
        d >>= 2;
    }
    return {x, y};
}

int xy2d(int n, int x, int y) {
    int d = 0;
    for (int s = (1 << n) >> 1; s > 0; s >>= 1) {
        int rx = (x & s) > 0 ? 1 : 0;
        int ry = (y & s) > 0 ? 1 : 0;
        d += s * s * ((3 * rx) ^ ry);
        if (ry == 0) {
            if (rx == 1) {
                x = s - 1 - x;
                y = s - 1 - y;
            }
            swap(x, y);
        }
    }
    return d;
}

int main() {
    int order;
    cout << "Enter Hilbert curve order: ";
    cin >> order;

    long long total = 1LL << (2 * order);
    cout << "Total cells: " << total << endl;

    // Example: count lights remaining after every k-th blackout
    for (int k : {2, 3, 5, 7}) {
        long long blacked = total / k;
        long long remaining = total - blacked;
        cout << "Blackout every " << k << ": " << remaining << " remaining" << endl;
    }

    // Verify coordinate mapping for small order
    if (order <= 4) {
        int side = 1 << order;
        cout << "\nHilbert curve path:" << endl;
        for (int d = 0; d < total; d++) {
            auto [x, y] = d2xy(order, d);
            int d2 = xy2d(order, x, y);
            if (d != d2) {
                cout << "ERROR: d=" << d << " -> (" << x << "," << y << ") -> " << d2 << endl;
            }
        }
        cout << "Coordinate mapping verified." << endl;
    }

    return 0;
}