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;
}




Java: import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;



public class MinimumNumberOnlyZeroAndOne {

    public static void main(String[] args) {
        for ( int n : getTestCases() ) {
            BigInteger result = getA004290(n);
            System.out.printf("A004290(%d) = %s = %s * %s%n", n, result, n, result.divide(BigInteger.valueOf(n)));
        }
    }
    
    private static List<Integer> getTestCases() {
        List<Integer> testCases = new ArrayList<>();
        for ( int i = 1 ; i <= 10 ; i++ ) {
            testCases.add(i);
        }
        for ( int i = 95 ; i <= 105 ; i++ ) {
            testCases.add(i);
        }
        for (int i : new int[] {297, 576, 594, 891, 909, 999, 1998, 2079, 2251, 2277, 2439, 2997, 4878} ) {
            testCases.add(i);
        }
        return testCases;
    }
    
    private static BigInteger getA004290(int n) {
        if ( n == 1 ) {
            return BigInteger.valueOf(1);
        }
        int[][] L = new int[n][n];
        for ( int i = 2 ; i < n ; i++ ) {
            L[0][i] = 0;
        }
        L[0][0] = 1;
        L[0][1] = 1;
        int m = 0;
        BigInteger ten = BigInteger.valueOf(10);
        BigInteger nBi = BigInteger.valueOf(n);
        while ( true ) {
            m++;
            
            if ( L[m-1][mod(ten.pow(m).negate(), nBi).intValue()] == 1 ) {
                break;
            }
            L[m][0] = 1;
            for ( int k = 1 ; k < n ; k++ ) {
                
                L[m][k] = Math.max(L[m-1][k], L[m-1][mod(BigInteger.valueOf(k).subtract(ten.pow(m)), nBi).intValue()]);
            }
            
        }
        
        
        BigInteger r = ten.pow(m);
        BigInteger k = mod(r.negate(), nBi);
        for ( int j = m-1 ; j >= 1 ; j-- ) {
            if ( L[j-1][k.intValue()] == 0 ) {
                
                
                r = r.add(ten.pow(j));
                k = mod(k.subtract(ten.pow(j)), nBi);
            }
        }
        if ( k.compareTo(BigInteger.ONE) == 0 ) {
            r = r.add(BigInteger.ONE);
        }
        return r;
    }

    private static BigInteger mod(BigInteger m, BigInteger n) {
        BigInteger result = m.mod(n);
        if ( result.compareTo(BigInteger.ZERO) < 0 ) {
            result = result.add(n);
        }
        return result;
    }

    @SuppressWarnings("unused")
    private static int mod(int m, int n) {
        int result = m % n;
        if ( result < 0 ) {
            result += n;
        }
        return result;
    }
    
    @SuppressWarnings("unused")
    private static int pow(int base, int exp) {
        return (int) Math.pow(base, exp);
    }
}