In this post, we will solve HackerRank Lucky Numbers Problem Solution.
A number is called lucky if the sum of its digits, as well as the sum of the squares of its digits is a prime number. How many numbers between a and b inclusive, are lucky?
For example, a = 20 and b = 25. Each number is tested below:
digit digit squares
value sum squares sum
20 2 4,0 4
21 3 4,1 5
22 4 4,4 8
23 5 4,9 13
24 6 4,16 20
25 7 4,25 29
We see that two numbers, 21, 23 and 25 are lucky.
Note: These lucky numbers are not to be confused with Lucky Numbers
Function Description
Complete the luckyNumbers function in the editor below. It should return an integer that represents the number of lucky numbers in the given range.
luckyNumbers has the following parameter(s):
- a: an integer, the lower range bound
- b: an integer, the higher range bound
Input Format
The first line contains the number of test cases T.
Each of the next T lines contains two space-separated integers, a and b.
Output Format
Output T lines, one for each test case in the order given.
Sample Input
2
1 20
120 130
Sample Output
4
1
Explanation
For the first case, the lucky numbers are 11, 12, 14, and 16.
For the second case, the only lucky number is 120.
Lucky Numbers C Solution
#include "stdio.h"
#define L 18
#define D 9
#define MAX1 (L*D)
#define MAX2 (L*D*D)
int prime[MAX2+1];
long long power[L+1], cnt[L+1][MAX1+1][MAX2+1];
void precompute()
{
int i, j, k, d;
power[0] = 1;
for( i = 1; i <= L; i++ ) power[i] = power[i-1] * ( D + 1 );
for( i = 2; i <= MAX2; i++ ) prime[i] = 1;
for( i = 2; i <= MAX2; i++ ) if( prime[i] ) for( j = 2 * i; j <= MAX2; j += i ) prime[j] = 0;
for( j = 0; j <= MAX1; j++ ) for( k = 0; k <= MAX2; k++ ) cnt[0][j][k] = prime[j] && prime[k];
for( i = 1; i <= L; i++ )
for( j = 0; j <= MAX1; j++ )
for( k = 0; k <= MAX2; k++ )
for( d = 0; d <= D; d++ )
if( j + d <= MAX1 && k + d * d <= MAX2 )
cnt[i][j][k] += cnt[i-1][j+d][k+d*d];
}
long long ways_rec( long long n, int i, int s1, int s2 )
{
if( i < 0 ) return 0;
int d = n / power[i];
long long ans = ways_rec( n - d * power[i], i - 1, s1 + d, s2 + d * d );
while( --d >= 0 ) ans += cnt[i][s1+d][s2+d*d];
return ans;
}
long long ways( long long n ) { return ways_rec( n, L, 0, 0 ); }
int main()
{
precompute();
long long a, b;
int t;
scanf( "%d", &t );
while(t--)
{
scanf( "%lld%lld", &a, &b );
printf( "%lld\n", ways( b + 1 ) - ways( a ) );
}
}
Lucky Numbers C++ Solution
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int max_num = 1458;
const int max_sum = 162;
const int max_length = 19;
LL dp[max_length + 1][max_sum + 1][max_num + 1];
int digits[max_length + 1];
bool composite[max_num + 1];
int len;
void get_primes(){
composite[0] = composite[1] = true;
for(long long i = 2; i * i <= max_num; i++){
if(!composite[i]){
for(long long j = i * i; j <= max_num; j+= i){
composite[j] = true;
}
}
}
}
LL rec(int pos, int s1, int s2, int chk)
{
if(pos == -1)
return !composite[s1] && !composite[s2];
if(!chk && dp[pos][s1][s2] != -1)
return dp[pos][s1][s2];
LL ans = 0;
int end = chk ? digits[pos] : 9;
for(int d = 0 ; d <= end; d++) {
ans += rec(pos - 1 , s1 + d , s2 + d * d, chk && d == end);
}
if(!chk)
dp[pos][s1][s2] = ans;
return ans;
}
LL get_ans(LL num) {
if(num == 0)
return 0;
len = 0;
while(num){
digits[len++] = num % 10;
num /= 10;
}
LL ans = rec(len - 1, 0, 0, 1);
return ans;
}
int main()
{
ios::sync_with_stdio(false);cin.tie(0);
int t;
get_primes();
memset(dp,-1,sizeof(dp));
cin >> t;
while(t--) {
LL a, b;
cin >> a >> b;
cout << get_ans(b) - get_ans(a - 1) << endl;
}
return 0;
}
Lucky Numbers C Sharp Solution
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Lucky_Numbers_daa
{
class Program
{
static bool[] primes = new bool[2000];
static bool isprime(int n)
{
for (int i = 2; i * i <= n; i++)
if ((n % i) == 0)
return false;
return true;
}
static long?[, ,] mem = new long?[200, 2000, 19];
static long dp(int sum, int sum_sq, int z)
{
if (mem[sum, sum_sq, z].HasValue)
return mem[sum, sum_sq, z].Value;
long count = 0;
if (z == 0)
count = (primes[sum] && primes[sum_sq]) ? 1 : 0;
else
for (int i = 0; i < 10; i++)
count += dp(sum + i, sum_sq + i * i, z - 1);
mem[sum, sum_sq, z] = count;
return count;
}
static long LuckyUpto(long A)
{
long b = 0;
long f = 1000000000000000000;
int sum = 0;
int sum_sq = 0;
int z = 18;
while (f > A)
{
f /= 10;
z--;
}
long count = 0;// dp(0, 0, z);
for (; z >= 0; z--)
{
for (int i = 0; i < 10; i++)
{
long max = b + f * (i + 1) - 1;
if (A == max)
{
count += dp(sum + i, sum_sq + i * i, z);
return count;
}
else if (A > max)
{
count += dp(sum + i, sum_sq + i * i, z);
}
else
{
sum += i;
sum_sq += i * i;
b += i * f;
f /= 10;
break;
}
}
}
return count;
}
static void Main(string[] args)
{
for (int i = 2; i < primes.Length; i++)
primes[i] = isprime(i);
int T = int.Parse(Console.ReadLine());
for (int i = 0; i < T; i++)
{
string[] line = Console.ReadLine().Split();
long A = long.Parse(line[0]);
long B = long.Parse(line[1]);
if (A == 1000000000000000000)
A--;
if (B == 1000000000000000000)
B--;
Console.WriteLine(LuckyUpto(B) - LuckyUpto(A - 1));
}
}
}
}
Lucky Numbers Java Solution
import java.io.*;
import java.math.*;
import java.text.*;
import java.util.*;
import java.util.regex.*;
public class Solution {
/*
* Complete the luckyNumbers function below.
*/
static long luckyNumbers(long a, long b) {
return Method1.luckyNumbers(a, b);
}
static class Method1 {
static final int max_bit = 19;
static final int max_digit_sum = 9 * 18 + 1;
static final int max_squre_digit_sum = 9 * 9 * 18 + 1;
static long[][][] sum = new long[max_bit][max_digit_sum][max_squre_digit_sum];
static long[][][] left_sum = new long[max_bit][max_digit_sum][max_squre_digit_sum];
static boolean[] is_prime = new boolean[max_squre_digit_sum];
static long[] bit_sum = new long[max_bit];
static int tot = 231, max1, max2;
static int[] prime = new int[tot];
static {
Arrays.fill(is_prime, true);
int ct = 0;
is_prime[0] = is_prime[1] = false;
for (int i = 2; i < max_squre_digit_sum; i++)
if (is_prime[i]) {
for (int j = i + i; j < max_squre_digit_sum; j += i)
is_prime[j] = false;
prime[ct++] = i;
if (i < max_digit_sum)
max1 = Math.max(max1, i);
max2 = Math.max(max2, i);
}
sum[0][0][0] = 1;
for (int i = 0; prime[i] <= max1; i++)
for (int j = 0; j < tot && prime[j] <= max2; j++) {
left_sum[0][prime[i]][prime[j]] += 1;
}
for (int i = 0; i < max_bit - 1; i++) {
for (int next = 0; next < 10; next++) {
for (int j = 0; j + next < max_digit_sum; j++)
for (int k = 0; k + next * next < max_squre_digit_sum; k++) {
sum[i + 1][j + next][k + next * next] += sum[i][j][k];
if (next > 0 && is_prime[j + next] && is_prime[k + next * next])
bit_sum[i + 1] += sum[i][j][k];
}
for (int j = next; j < max_digit_sum; j++)
for (int k = next * next; k < max_squre_digit_sum; k++) {
left_sum[i + 1][j - next][k - next * next] += left_sum[i][j][k];
}
}
}
}
static long luckyNumbers(long a, long b) {
return go(b) - go(a - 1);
}
static long go(long N) {
if (N == 0)
return 0;
long ret = 0;
boolean first = true;
int pre_digit_sum = 0, pre_sdigit_sum = 0;
for (int i = 19; i > 0; i--) {
int bit = get_bit(N, i - 1);
int least;
if (bit != 0 && first) {
least = 1;
first = false;
for (int j = 1; j < i; j++)
ret += bit_sum[j];
} else {
least = 0;
}
for (int nbit = least; nbit < bit; nbit++) {
int digit_sum = pre_digit_sum + nbit;
int sdigit_sum = pre_sdigit_sum + nbit * nbit;
ret += left_sum[i - 1][digit_sum][sdigit_sum];
}
pre_digit_sum += bit;
pre_sdigit_sum += bit * bit;
}
if (is_prime[pre_digit_sum] && is_prime[pre_sdigit_sum])
ret += 1;
return ret;
}
static int get_bit(long n, int m) {
for (int i = 0; i < m; i++)
n /= 10;
return (int) (n % 10);
}
}
private static final Scanner scanner = new Scanner(System.in);
public static void main(String[] args) throws IOException {
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(System.getenv("OUTPUT_PATH")));
int t = Integer.parseInt(scanner.nextLine().trim());
for (int tItr = 0; tItr < t; tItr++) {
String[] ab = scanner.nextLine().split(" ");
long a = Long.parseLong(ab[0].trim());
long b = Long.parseLong(ab[1].trim());
long result = luckyNumbers(a, b);
bufferedWriter.write(String.valueOf(result));
bufferedWriter.newLine();
}
bufferedWriter.close();
}
}
Lucky Numbers Python Solution
def lucky(N):
p = [int(x) for x in str(N)]
numDigits = len(p)
total = 0
curSum = 0
curSumSq = 0
while len(p):
for a in range(p[0]):
total += resolve(numDigits - 1, curSum + a, curSumSq + a**2)
numDigits -= 1
curSum += p[0]
curSumSq += p[0]**2
p.pop(0)
return total
def resolve(n, s, sq):
if (n,s,sq) in memo:
return memo[(n,s,sq)]
if n == 0:
if s in primes and sq in primes:
memo[(n,s,sq)] = 1
return 1
memo[(n,s,sq)] = 0
return 0
c = 0
for b in range(10):
c += resolve(n-1, s + b, sq + b**2)
memo[(n,s,sq)] = c
return c
memo = {}
primes = set([2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997, 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297, 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861, 2879, 2887, 2897, 2903, 2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999])
for test in range(int(input())):
[A,B] = [int(x) for x in input().split(' ')]
print(lucky(B+1)-lucky(A))