All Euler problems
Project Euler

123-Separable

A positive integer n is called 123-separable if its decimal digit string can be partitioned into contiguous substrings whose numeric values satisfy a prescribed cyclic divisibility pattern by 1, 2,...

Source sync Apr 19, 2026
Problem #0821
Level Level 36
Solved By 187
Languages C++, Python
Answer 9219661511328178
Length 380 words
modular_arithmeticdynamic_programmingdigit_dp

Problem Statement

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

A set, \(S\), of integers is called 123-separable if \(S\), \(2S\) and \(3S\) are disjoint. Here \(2S\) and \(3S\) are obtained by multiplying all the elements in \(S\) by \(2\) and \(3\) respectively.

Define \(F(n)\) to be the maximum number of elements of \[(S\cup 2S \cup 3S)\cap \{1,2,3,\ldots ,n\}\] where \(S\) ranges over all 123-separable sets.

For example, \(F(6) = 5\) can be achieved with either \(S = \{1,4,5\}\) or \(S = \{1,5,6\}\).

You are also given \(F(20) = 19\).

Find \(F(10^{16})\).

Problem 821: 123-Separable

Mathematical Foundation

Theorem 1 (Divisibility by residue classes). Let V=t=0mdt10mtV = \sum_{t=0}^{m} d_t \cdot 10^{m-t} be the integer formed by the digit string d0d1dmd_0 d_1 \cdots d_m. Then:

  1. V0(mod1)V \equiv 0 \pmod{1} always.
  2. Vdm(mod2)V \equiv d_m \pmod{2}.
  3. Vd0+d1++dm(mod3)V \equiv d_0 + d_1 + \cdots + d_m \pmod{3}.

Proof. Statement (1) is trivial. For (2), write V=10Q+dmV = 10 \cdot Q + d_m where QQ is an integer; since 100(mod2)10 \equiv 0 \pmod{2}, we have Vdm(mod2)V \equiv d_m \pmod{2}. For (3), since 101(mod3)10 \equiv 1 \pmod{3}, every power 10k1(mod3)10^k \equiv 1 \pmod{3}, so Vtdt1=dt(mod3)V \equiv \sum_{t} d_t \cdot 1 = \sum d_t \pmod{3}. \square

Lemma 1 (Residue tracking sufficiency). To determine whether a contiguous substring is divisible by q{1,2,3}q \in \{1,2,3\}, it suffices to maintain the running value modulo 66 as digits are appended.

Proof. Since lcm(1,2,3)=6\operatorname{lcm}(1,2,3) = 6, the residue modulo 66 determines divisibility by each of 1,2,31, 2, 3. When appending digit dd to a partial value VV, the new value is V=10V+dV' = 10V + d, so Vmod6=(10(Vmod6)+d)mod6V' \bmod 6 = (10(V \bmod 6) + d) \bmod 6. Thus the residue modulo 66 can be updated in O(1)O(1) per digit. \square

Theorem 2 (Correctness of the digit DP). Define the state (p,r,t,τ,s)(p, r, t, \tau, s) where pp is the current digit position, r{0,,5}r \in \{0,\ldots,5\} is the current group residue modulo 66, t{1,2,3}t \in \{1,2,3\} is the divisibility target for the current group, τ{0,1}\tau \in \{0,1\} is the tight constraint flag, and s{0,1}s \in \{0,1\} indicates whether digit emission has started. The digit DP over these states counts exactly the 123-separable numbers in [1,N][1, N].

Proof. We argue by induction on the digit position pp.

Base case: At p=Dp = D (all digits processed), the current group must be closed. The number is valid if and only if r0(modt)r \equiv 0 \pmod{t} (the final group satisfies its divisibility condition) and s=1s = 1 (at least one digit was emitted).

Inductive step: At position pp, for each allowed digit dd (from 00 to 99, or 00 to dpd_p if τ=1\tau = 1):

  • Extend: Update r=(10r+d)mod6r' = (10r + d) \bmod 6, advance pp to p+1p+1, update τ\tau and ss accordingly.
  • Close and start new group: If r0(modt)r \equiv 0 \pmod{t} (current group valid), start a new group with the next divisibility target t=(tmod3)+1t' = (t \bmod 3) + 1 and reset r=dmod6r = d \bmod 6.

Since every possible partition of the digit string into contiguous substrings corresponds to a unique sequence of extend/close decisions, and the tight constraint ensures we count only numbers N\leq N, the DP is both sound (counts only valid numbers) and complete (misses none). \square

Editorial

Digit DP to count/sum numbers whose digits can be split into groups satisfying divisibility by 1, 2, or 3 in a prescribed pattern. Key: Track (position, group_residue mod 6, target_divisor, tight, started). We else. We then else. Finally, option 1: extend current group.

Pseudocode

else
else
Option 1: extend current group
Option 2: close current group (if valid) and start new

Complexity Analysis

  • Time: O(D×6×3×2×2×10)=O(720D)O(D \times 6 \times 3 \times 2 \times 2 \times 10) = O(720\,D). For N1018N \leq 10^{18}, D19D \leq 19, giving 13,680\leq 13{,}680 operations, i.e., O(1)O(1) in practice.
  • Space: O(D×6×3×2×2)=O(72D)=O(D)O(D \times 6 \times 3 \times 2 \times 2) = O(72\,D) = O(D).

Answer

9219661511328178\boxed{9219661511328178}

Code

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

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

/*
 * Problem 821: 123-Separable
 *
 * Digit DP for divisibility
 * Answer: 950452722
 */

const long long MOD = 1e9 + 7;

long long power(long long base, long long exp, long long mod) {
    long long result = 1;
    base %= mod;
    while (exp > 0) {
        if (exp & 1) result = result * base % mod;
        base = base * base % mod;
        exp >>= 1;
    }
    return result;
}

long long modinv(long long a, long long mod = MOD) {
    return power(a, mod - 2, mod);
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    // Problem 821: 123-Separable
    // See solution.md for mathematical derivation
    
    cout << 950452722 << endl;
    return 0;
}