In this HackerRank Prime Digit Sums problem solution we have a query consists of an integer n and for each n find and print the number of positive n digits number modulo by 10 to power 9 plus 7. that satisfy all the three of Chloe's rules means the every three four and five consecutive digits sum to a prime number.

hackerrank prime digit sums problem solution


Problem solution in Java.

 
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;
import java.util.Set;

public class Solution {
    static boolean[] P = new boolean[62];

    static final long MOD = (long) Math.pow(10, 9) + 7l;
    static Map<Integer, ThreeDigit> DIGITMAP = new HashMap<Integer, ThreeDigit>();
    static Map<Long, Long> tab = new HashMap<Long, Long>();

    static long[] depNUM = new long[400001];
    static int NL = 400005;

    public static void main(String[] args) throws Exception {
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt();

        P[2] = true;
        P[3] = true;
        List<Integer> list = new ArrayList<Integer>();
        list.add(2);
        list.add(3);

        for (int i = 5; i < 50; i += 6) {
            int i1 = i;
            int i2 = i + 2;
            boolean bi1 = true;
            boolean bi2 = true;
            int se = (int) Math.sqrt(i2);

            for (int p : list) {
                if (i1 % p == 0)
                    bi1 = false;
                if (i2 % p == 0)
                    bi2 = false;
                if (p > se) {
                    break;
                }
                if (!bi1 && !bi2)
                    break;
            }
            if (bi1) {
                P[i1] = true;
                list.add(i1);
            }
            if (bi2) {
                P[i2] = true;
                list.add(i2);
            }

        }

        for (int i = 2; i < 1000; i++) {
            int temp = i / 100 + i / 10 % 10 + i % 10;

            if (P[temp]) {
                DIGITMAP.put(i, new ThreeDigit(i));
            }
        }
        for (ThreeDigit td : DIGITMAP.values()) {
            initDigit(td);
        }

        Map<Integer, Long> fourNums = new HashMap<Integer, Long>();
        ThreeDigit[] tds = new ThreeDigit[1000];
        int[] depSum = new int[NL + 1];
        for (ThreeDigit td : DIGITMAP.values()) {
            if (td.v > 100) {
                fourNums.put(td.v, 1l);
                depSum[3]++;
            }  
            tds[td.v] = td;
        }
        depSum[1] = 9;
        depSum[2] = 90;
        for (int i = 4; i <= NL; i++) {
            Map<Integer, Long> fourNums2 = new HashMap<Integer, Long>();
            travel(fourNums, fourNums2, tds, depSum, i);
            fourNums = fourNums2;
        }

        while (N-- > 0) {
            System.out.println(depSum[sc.nextInt()]);
        }
        sc.close();
    }

    public static void travel(Map<Integer, Long> fourNums, Map<Integer, Long> fourNums2, ThreeDigit[] tds, int[] depSum,
            int dep) {

        for (Entry<Integer, Long> entry : fourNums.entrySet()) {
            int fourNum = entry.getKey();
            long num = entry.getValue();
            int first = fourNum / 1000;
            ThreeDigit td = tds[fourNum % 1000];
            for (ThreeDigit ttd : td.set) {
                if (P[first + td.threeSum + ttd.last]) {
                    depSum[dep] += num;
                    depSum[dep] %= MOD;
                    Long v = fourNums2.get(td.v * 10 + ttd.last);
                    if (v == null)
                        fourNums2.put(td.v * 10 + ttd.last, num);
                    else
                        fourNums2.put(td.v * 10 + ttd.last, (v + num) % MOD);

                }
            }
        }

    }

    public static void initDigit(ThreeDigit td) {
        for (int i = 0; i < 10; i++) {
            if (P[td.threeSum + i] && P[td.twoSum + i]) {
                ThreeDigit gettd = DIGITMAP.get(td.v % 100 * 10 + i);
                if (!td.set.contains(gettd)) {
                    td.set.add(gettd);
                }
            }
        }
    }

    public static class ThreeDigit {
        private int v;
        private int threeSum;
        private int twoSum;
        private int first;
        private int last;
        private Set<ThreeDigit> set = new HashSet<ThreeDigit>();

        public void addNextDigit() {

        }

        public ThreeDigit(int v) {
            this.v = v;
            this.last = v % 10;
            this.twoSum = this.last + v / 10 % 10;
            this.threeSum = this.twoSum + v / 100;
            this.first = this.v / 100;
        }

        public int hashCode() {
            return this.v;
        }

        public boolean equals(Object o) {
            ThreeDigit o1 = (ThreeDigit) o;
            return this.v == o1.v;
        }
    }
}

{"mode":"full","isActive":false}


Problem solution in C++.

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 415, Q = 4e5+5, MOD = 1e9+7;
bool prime[100];
int sum(int n){
    if(n == 0)
        return 0;
    return sum(n/10)+n%10;
}
bool is_ok(int n){
    return prime[sum(n)] && prime[sum(n/10)] && prime[sum(n%1000)];
}
bool conn(int a, int b){
    return ((a%1000) == b/10 && prime[sum(a) + b%10]);
}
int table[Q];
bool vacuum(int x){
    if(x < 100)
        return true;
    if(!prime[sum(x%1000)])
        return false;
    return true;
}
int solve(){
    int n;
    cin >> n;
    return table[n];
}
vector<int> nodes;
vector<int> adj[N];
void prep(){
    for(int n = 1; n <= 3; ++n){
        int mx = 1;
        for(int i = 0; i < n; ++i)
            mx *= 10;
        for(int i = mx/10; i < mx; ++i)
            table[n] += vacuum(i);
    }
    vector<int> dp(N,0);
    for(int i = 0; i < N; ++i)
        if(nodes[i] >= 1000){
            dp[i] = 1;
            ++table[4];
        }
    for(int i = 5; i < Q; ++i){
        vector<int> nxt(N,0);
        for(int j = 0; j < N; ++j)
            for(int v : adj[j])
                nxt[v] = (nxt[v]+dp[j])%MOD;
        ll sum = 0;
        for(int val : nxt)
            sum += val;
        table[i] = sum%MOD;
        dp = nxt;
    }
}
int main(){
    fill(prime+2,prime+100,true);
    for(int i = 2; i < 100; ++i)
        if(prime[i])
            for(int j = 2*i; j < 100; j += i)
                prime[j] = false;
   for(int i = 0; i < 10000; ++i)
       if(is_ok(i))
           nodes.push_back(i);
   int ans = 0;
   for(int i = 0; i < nodes.size(); ++i)
       for(int j = 0; j < nodes.size(); ++j){
           int a = nodes[i], b = nodes[j];
           if(conn(a,b)){
               adj[i].push_back(j);
//               cout << i << ' ' << j << '\n';
           }
       }
   prep();
   int q;
   cin >> q;
   while(q--)
       cout << solve() << '\n';
}

{"mode":"full","isActive":false}