Task: Minimum positive multiple in base 10 using only 0 and 1


C++: #include <iostream>
#include <vector>

__int128 imax(__int128 a, __int128 b) {
    if (a > b) {
        return a;
    }
    return b;
}

__int128 ipow(__int128 b, __int128 n) {
    if (n == 0) {
        return 1;
    }
    if (n == 1) {
        return b;
    }

    __int128 res = b;
    while (n > 1) {
        res *= b;
        n--;
    }
    return res;
}

__int128 imod(__int128 m, __int128 n) {
    __int128 result = m % n;
    if (result < 0) {
        result += n;
    }
    return result;
}

bool valid(__int128 n) {
    if (n < 0) {
        return false;
    }
    while (n > 0) {
        int r = n % 10;
        if (r > 1) {
            return false;
        }
        n /= 10;
    }
    return true;
}

__int128 mpm(const __int128 n) {
    if (n == 1) {
        return 1;
    }

    std::vector<__int128> L(n * n, 0);
    L[0] = 1;
    L[1] = 1;

    __int128 m, k, r, j;
    m = 0;
    while (true) {
        m++;
        if (L[(m - 1) * n + imod(-ipow(10, m), n)] == 1) {
            break;
        }
        L[m * n + 0] = 1;
        for (k = 1; k < n; k++) {
            L[m * n + k] = imax(L[(m - 1) * n + k], L[(m - 1) * n + imod(k - ipow(10, m), n)]);
        }
    }

    r = ipow(10, m);
    k = imod(-r, n);

    for (j = m - 1; j >= 1; j--) {
        if (L[(j - 1) * n + k] == 0) {
            r = r + ipow(10, j);
            k = imod(k - ipow(10, j), n);
        }
    }

    if (k == 1) {
        r++;
    }
    return r / n;
}

std::ostream& operator<<(std::ostream& os, __int128 n) {
    char buffer[64]; 
    int pos = (sizeof(buffer) / sizeof(char)) - 1;
    bool negative = false;

    if (n < 0) {
        negative = true;
        n = -n;
    }

    buffer[pos] = 0;
    while (n > 0) {
        int rem = n % 10;
        buffer[--pos] = rem + '0';
        n /= 10;
    }
    if (negative) {
        buffer[--pos] = '-';
    }
    return os << &buffer[pos];
}

void test(__int128 n) {
    __int128 mult = mpm(n);
    if (mult > 0) {
        std::cout << n << " * " << mult << " = " << (n * mult) << '\n';
    } else {
        std::cout << n << "(no solution)\n";
    }
}

int main() {
    int i;

    
    for (i = 1; i <= 10; i++) {
        test(i);
    }
    
    for (i = 95; i <= 105; i++) {
        test(i);
    }
    test(297);
    test(576);
    test(594); 
    test(891);
    test(909);
    test(999); 

    
    test(1998);
    test(2079);
    test(2251);
    test(2277);

    
    test(2439);
    test(2997);
    test(4878);

    return 0;
}






Python: def getA004290(n):
    if n < 2:
        return 1
    arr = [[0 for _ in range(n)] for _ in range(n)]
    arr[0][0] = 1
    arr[0][1] = 1
    m = 0
    while True:
        m += 1
        if arr[m - 1][-10 ** m % n] == 1:
            break
        arr[m][0] = 1
        for k in range(1, n):
            arr[m][k] = max([arr[m - 1][k], arr[m - 1][k - 10 ** m % n]])
    r = 10 ** m
    k = -r % n
    for j in range((m - 1), 0, -1):
        if arr[j - 1][k] == 0:
            r = r + 10 ** j
            k = (k - 10 ** j) % n   
    if k == 1:
        r += 1
    return r
 
for n in [i for i in range(1, 11)] + \
          [i for i in range(95, 106)] + \
          [297, 576, 594, 891, 909, 999, 1998, 2079, 2251, 2277, 2439, 2997, 4878]:
    result = getA004290(n)
    print(f"A004290({n}) = {result} = {n} * {result // n})")