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


C#: using System;
using System.Collections.Generic;
using static System.Console;
 
class Program {
 
  static string B10(int n) {
    int[] pow = new int[n + 1], val = new int[29];
    for (int count = 0, ten = 1, x = 1; x <= n; x++) {
      val[x] = ten;
      for (int j = 0, t; j <= n; j++)
        if (pow[j] != 0 && pow[j] != x && pow[t = (j + ten) % n] == 0)
          pow[t] = x;
      if (pow[ten] == 0) pow[ten] = x;
      ten = (10 * ten) % n;
      if (pow[0] != 0) {
        x = n;
        string s = ""; 
        while (x != 0) {
          int p = pow[x % n];
          if (count > p) s += new string('0', count - p);
          count = p - 1;
          s += "1";
          x = (n + x - val[p]) % n;
        }
        if (count > 0) s += new string('0', count);
        return s;
      }
    } 
    return "1";
  }
 
  static void Main(string[] args) {
    string fmt = "{0,4} * {1,24} = {2,-28}\n";
    int[] m = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
      95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
      297, 576, 594, 891, 909, 999, 1998, 2079, 2251, 2277, 2439, 2997, 4878 };
    string[] r = new string[m.Length]; 
    WriteLine(fmt + new string('-', 62), "n", "multiplier", "B10");
    var sw = System.Diagnostics.Stopwatch.StartNew();
    for (int i = 0; i < m.Length; i++) r[i] = B10(m[i]);
    sw.Stop();
    for (int i = 0; i < m.Length; i++) Write(fmt, m[i], decimal.Parse(r[i]) / m[i], r[i]);
    Write("\nTook {0}ms", sw.Elapsed.TotalMilliseconds);
  }
}