Project Euler #43: Sub-string divisibility

Sort by

recency

|

30 Discussions

|

  • + 0 comments

    Here is my C++ solution and it's simple approach.**

    #include <string>
    #include <iostream>
    #include <algorithm>
    
    // convert a string to a number
    unsigned long long str2num(const std::string& x)
    {
      // process string from left to right
      unsigned long long result = 0;
      for (auto c : x)
      {
          // shift digits
          result *= 10;
          // add new digit on the right-hand side
          result += c - '0'; // was ASCII
      }
      return result;
    }
    
    int main()
    {
      // available digits
      std::string pan = "0123456789"; // unlike other problems, zero is allowed this time
    
      // remove a few digits if test case requires this
      unsigned int maxDigit;
      std::cin >> maxDigit;
      pan.erase(maxDigit + 1);
    
      // all divisors
      const unsigned int primes[] = { 2,3,5,7,11,13,17 };
    
      // result
      unsigned long long sum = 0;
    
      // look at all permutations
      do
      {
        // let's assume it's a great number ;-)
        bool ok = true;
    
        // check each 3-digit substring for divisibility
        for (unsigned int i = 0; i + 2 < maxDigit; i++)
        {
          // check pan[1..3] against primes[0],
          // check pan[2..4] against primes[1],
          // check pan[3..5] against primes[2] ...
          std::string check = pan.substr(i + 1, 3);
          if (str2num(check) % primes[i] != 0)
          {
            // nope ...
            ok = false;
            break;
          }
        }
    
        // passed all tests, it's great indeed !
        if (ok)
          sum += str2num(pan);
      } while (std::next_permutation(pan.begin(), pan.end()));
    
      std::cout << sum << std::endl;
      return 0;
    1. }
    
  • + 1 comment

    THE QUESTION IS INCORRECT! INSTEAD OF "Find the sum of all 0 to N pandigital numbers with this property." WRITE THE CODE FOR "Find the sum of all N pandigital numbers with this property."

    I WAS STUCK FOR AN HOUR JUST TO FIGURE OUT THAT THE QUESTION THEY ASKED WAS INCORRECT!!

    • + 0 comments

      Thanks for the heads-up!

  • + 3 comments

    My codes take 10s in Colab and can't pass test case 6. Can anyone help me optimize?

    Thanks in advance!

    from itertools import permutations
     
    def Substring_Divisibility(n):
      ### This part takes so much time
      permStr = []
      for i in permutations(range(0,n+1)):
        s = ''.join(map(str,i)) 
        permStr.append(s)
      ### __________________
      
      total = 0
      for s in permStr:
        if len(s[1:4]) == 3: 
          if int(s[1:4])%2 == 0: pass
          else: continue
        else: 
          pass
    
        if len(s[2:5]) == 3: 
          if int(s[2:5])%3 == 0: pass
          else: continue
        else: 
          pass
    
        if len(s[3:6]) == 3: 
          if int(s[3:6])%5 == 0: pass
          else: continue
        else: 
          pass
    
        if len(s[4:7]) == 3: 
          if int(s[4:7])%7 == 0: pass
          else: continue
        else: 
          pass
    
        if len(s[5:8]) == 3: 
          if int(s[5:8])%11 == 0: pass
          else: continue
        else: 
          pass
    
        if len(s[6:9]) == 3: 
          if int(s[6:9])%13 == 0: pass
          else: continue
        else: 
          pass
    
        if len(s[7:10]) == 3: 
          if int(s[7:10])%17 == 0: pass
          else: continue
        else: 
          pass
          
        total += int(s)
          
      return total
    
    if __name__ == '__main__':
      n = int(input())
      print(Substring_Divisibility(n))
    
    • + 0 comments

      If you got TLE, you may consider using generator instead of regular for loop or listcomp. I used for loop first, then moved on to listcomp, nothing worked. Finally, using generator I got over test case 6. There's nothing wrong in your code, so far I am concerned

    • + 0 comments

      If it's just 1/2 cases run the same code in pypy3. It works.

    • + 1 comment

      Try this code:

      Note:-

      The main difference between your approach and my approach is How to generate permutations and check for divisibility

      Approach:- This code takes an integer input n and defines a function solve() to find the sum of all numbers formed by permutations of the digits 0 to n, which satisfy a certain divisibility condition. The divisible_test() function checks if a given number formed by the permutation satisfies the divisibility condition for a set of prime numbers. The condition checks if the sub-strings of length 3 in the number are divisible by the corresponding prime numbers in the divisible list.

      The solve() function iterates through all permutations of the numbers 0 to n and checks if each permutation satisfies the divisibility condition using divisible_test(). If a permutation satisfies the condition, it converts the permutation into an integer and adds it to the sum. Finally, the function returns the sum of all such numbers.

      The code uses the itertools.permutations function to generate all permutations of the numbers 0 to n. It then applies the divisible_test() function to each permutation to check for divisibility. If a permutation satisfies the divisibility condition, its corresponding number is added to the sum.

      ''' from itertools import permutations n = int(input()) def solve(): return sum(int(''.join(map(str, num))) for num in permutations(range(n+1)) if divisible_test(num)) divisible=[2, 3, 5, 7, 11, 13, 17] def divisible_test(num): return all((num[i+1]*100+num[i+2]*10+num[i+3]) %p == 0 for i, p in enumerate(divisible[:n-2])) print(solve()) '''

      • + 0 comments

        ''' from itertools import permutations n = int(input()) def solve(): return sum(int(''.join(map(str, num))) for num in permutations(range(n+1)) if divisible_test(num)) divisible=[2, 3, 5, 7, 11, 13, 17] def divisible_test(num): return all((num[i+1]*100+num[i+2]*10+num[i+3]) %p == 0 for i, p in enumerate(divisible[:n-2])) print(solve()) '''

  • + 0 comments

    C++ Solution :

    #include <bits/stdc++.h>
    using namespace std;
    #define all(v) (v).begin(), (v).end()
    #define debug(x) cout << #x << " = " << x << endl
    typedef long long ll;
    typedef pair<int, int> pii;
    typedef pair<ll, ll> pll;
    inline ll Mod(ll x, ll mod) { return x % mod >= 0 ? x % mod : x % mod + mod; }
    
    ll sum[10] = {0};
    int nums[] = {2, 3, 5, 7, 11, 13, 17};
    
    bool is_strange(string s)
    {
        int y = s.length();
        for (int i = 1; i <= y - 3; i++)
        {
            int p = (s[i] - '0') * 100 + (s[i + 1] - '0') * 10 + (s[i + 2] - '0');
            if (p % nums[i - 1] != 0)
                return 0;
        }
        return 1;
    }
    
    int main()
    {
        ios_base::sync_with_stdio(false);
        cin.tie(0);
        string ss[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
        string s = "012";
        for (int i = 3; i <= 9; i++)
        {
            s += ss[i];
            if (is_strange(s))
            {
                string p = s;
                if (s[0] == '0')
                {
                    int y = s.length();
                    p = s.substr(1, y - 1);
                }
                sum[i] += (stoll(p));
            }
    
            while (next_permutation(all(s)))
            {
                if (is_strange(s))
                {
                    string p = s;
                    if (s[0] == '0')
                    {
                        int y = s.length();
                        p = s.substr(1, y - 1);
                    }
                    sum[i] += (stoll(p));
                    //cout << p << " " << flush ;
                }
            }
        }
        int n;
        cin >> n;
        cout << sum[n];
    }
    
  • + 0 comments

    There are only 44 combinations of 3 unique numbers (0-9) that are divisable by 17.

    The problem has very lax requirements, but for N=9, you can do this in 2 ms using Python 3.