I am challenging google foobar currently and met this question.
A "lucky triple" is a tuple (x, y, z) where x divides y and y divides z, such as (1, 2, 4).
Write a function solution(l) that takes a list of positive integers l and counts the number of "lucky triples" of (li, lj, lk) where the list indices meet the requirement i < j < k. The length of l is between 2 and 2000 inclusive. The elements of l are between 1 and 999999 inclusive. The solution fits within a signed 32-bit integer. Some of the lists are purposely generated without any access codes to throw off spies, so if no triples are found, return 0.
I have try some other method and keep failing on the 5th test. Somehow I found solution from Google Foobar Challenge 3 - Find the Access Codes , but I don't understand why my code don't work.
Here's the code that I refer the method from "Find the access codes" Google Foobar challenge
def solution(l):
i = 0
indexes = []
inputSize = len(l)
keyCounter = 0
while i < inputSize-1:
temp = i+1
matches = []
while temp < inputSize:
if(l[temp] % l[i] == 0):
matches.append(temp)
temp +=1
indexes.append(matches)
i+=1
m = 0
while m < len(indexes):
n=0
temp = indexes[m]
while n < len(temp)-1:
keyCounter += len(list(set(indexes[m]).intersection(indexes[temp[n]])))
n +=1
m+=1
return keyCounter
and my original attemps :
def solution(l):
i = 0
j = 1
k = 2
keyCounter = 0
while i < len(l)-2:
if(l[j] % l[i] == 0):
if(l[k] % l[j] == 0):
keyCounter +=1
if(k < len(l)-1):
k += 1
elif(j < len(l)-2):
j += 1
k = j + 1
else:
i += 1
j = i + 1
k = j + 1
else:
if(j < len(l)-2):
j += 1
k = j + 1
else:
i += 1
j = i + 1
k = j + 1
return keyCounter
I have this Rabin Karp implementation. Now the only thing I'm doing for rolling hash is subtract power*source[i] from the sourceHash. power is 31^target.size()-1 % mod
But I can't understand why we're adding mod to sourceHash when it becomes negative. I have tried adding other values but it doesn't work and it only works when we add mod. Why is this? Is there a specific reason why we're adding mod and not anything else (like a random big number for example).
int rbk(string source, string target){
int m = target.size();
int n = source.size();
int mod = 128;
int prime = 11;
int power = 1;
int targetHash = 0, sourceHash = 0;
for(int i = 0; i < m - 1; i++){
power =(power*prime) % mod;
}
for(int i = 0; i < target.size(); i++){
sourceHash = (sourceHash*prime + source[i]) % mod;
targetHash = (targetHash*prime + target[i]) % mod;
}
for(int i = 0; i < n-m+1; i++){
if(targetHash == sourceHash){
bool flag = true;
for(int j = 0; j < m; j++){
if(source[i+j] != target[j]){
flag = false;
break;
}
}
if(flag){
return 1;
}
}
if(i < n-m){
sourceHash = (prime*(sourceHash - source[i]*power) + source[i+m]) % mod;
if(sourceHash < 0){
sourceHash += mod;
}
}
}
return -1;
}
When using modulo arithmetics (mod n) we have just n distinct numbers: 0, 1, 2, ..., n - 1.
All the other numbers which out of 0 .. n - 1 are equal to some number in 0 .. n - 1:
-n ~ 0
-n + 1 ~ 1
-n + 2 ~ 2
...
-2 ~ n - 2
-1 ~ n - 1
or
n ~ 0
n + 1 ~ 1
n + 2 ~ 2
...
2 * n ~ 0
2 * n + 1 ~ 0
In general case A ~ B if and only if (A - B) % n = 0 (here % stands for remainder).
When implementing Rabin Karp algorithm we can have two potential problems:
Hash can be too large, we can face integer overflow
Negative remainder can be implemented in different way on different compilers: -5 % 3 == -2 == 1
To deal with both problems, we can normalize remainder and operate with numbers within safe 0 .. n - 1 range only.
For arbitrary value A we can put
A = (A % n + n) % n;
I tried to create a function which takes two variables n and k.
The function returns the number of positive integers that have prime factors all less than or equal to k. The number of positive integers is limited by n which is the largest positive integer.
For example, if k = 4 and n = 10; the positive integers which have all prime factors less than or equal to 4 are 1, 2, 3, 4, 6, 8, 9, 12...(1 is always part for some reason even though its not prime) but since n is 10, 12 and higher numbers are ignored.
So the function will return 7. The code I wrote works for smaller values of n while it just keeps on running for larger values.
How can I optimize this code? Should I start from scratch and come up with a better algorithm?
int generalisedHammingNumbers(int n, int k)
{
vector<int>store;
vector<int>each_prime = {};
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= i; ++j)
{
if (i%j == 0 && is_prime(j))
{
each_prime.push_back(j); //temporary vector of prime factors for each integer(i)
}
}
for (int m = 0; m<each_prime.size(); ++m)
{
while(each_prime[m] <= k && m<each_prime.size()-1) //search for prime factor greater than k
{
++m;
}
if (each_prime[m] > k); //do nothing for prime factor greater than k
else store.push_back(i); //if no prime factor greater than k, i is valid, store i
}
each_prime = {};
}
return (store.size()+1);
}
bool is_prime(int x)
{
vector<int>test;
if (x != 1)
{
for (int i = 2; i < x; ++i)
{
if (x%i == 0)test.push_back(i);
}
if (test.size() == 0)return true;
else return false;
}
return false;
}
int main()
{
long n;
int k;
cin >> n >> k;
long result = generalisedHammingNumbers(n, k);
cout << result << endl;
}
Should I start from scratch and come up with a better algorithm?
Yes... I think so.
This seems to me a work for the Sieve of Eratosthenes.
So I propose to
1) create a std::vector<bool> to detect, through Eratosthenes, the primes to n
2) remove primes starting from k+1, and their multiples, from the pool of your numbers (another std::vector<bool>)
3) count the true remained values in the pool vector
The following is a full working example
#include <vector>
#include <iostream>
#include <algorithm>
std::size_t foo (std::size_t n, std::size_t k)
{
std::vector<bool> primes(n+1U, true);
std::vector<bool> pool(n+1U, true);
std::size_t const sqrtOfN = std::sqrt(n);
// first remove the not primes from primes list (Sieve of Eratosthenes)
for ( auto i = 2U ; i <= sqrtOfN ; ++i )
if ( primes[i] )
for ( auto j = i << 1 ; j <= n ; j += i )
primes[j] = false;
// then remove from pool primes, bigger than k, and multiples
for ( auto i = k+1U ; i <= n ; ++i )
if ( primes[i] )
for ( auto j = i ; j <= n ; j += i )
pool[j] = false;
// last count the true value in pool (excluding the zero)
return std::count(pool.begin()+1U, pool.end(), true);
}
int main ()
{
std::cout << foo(10U, 4U) << std::endl;
}
Generate the primes using a sieve of Erastothenes, and then use a modified coin-change algorithm to find numbers which are products of only those primes. In fact, one can do both simultaneously like this (in Python, but is easily convertible to C++):
def limited_prime_factors(n, k):
ps = [False] * (k+1)
r = [True] * 2 + [False] * n
for p in xrange(2, k+1):
if ps[p]: continue
for i in xrange(p, k+1, p):
ps[i] = True
for i in xrange(p, n+1, p):
r[i] = r[i//p]
return [i for i, b in enumerate(r) if b]
print limited_prime_factors(100, 3)
The output is:
[0, 1, 2, 3, 4, 6, 8, 9, 12, 16, 18, 24, 27, 32, 36, 48, 54, 64, 72, 81, 96]
Here, each time we find a prime p, we strike out all multiples of p in the ps array (as a standard Sieve of Erastothenes), and then in the r array, mark all multiples of any number that's a multiple of p whether their prime factors are all less than or equal to p.
It runs in O(n) space and O(n log log k) time, assuming n>k.
A simpler O(n log k) solution tests if all the factors of a number are less than or equal to k:
def limited_prime_factors(n, k):
r = [True] * 2 + [False] * n
for p in xrange(2, k+1):
for i in xrange(p, n+1, p):
r[i] = r[i//p]
return [i for i, b in enumerate(r) if b]
Here's an Eulerian version in Python (seems about 1.5 times faster than Paul Hankin's). We generate only the numbers themselves by multiplying a list by each prime and its powers in turn.
import time
start = time.time()
n = 1000000
k = 100
total = 1
a = [None for i in range(0, n+1)]
s = []
p = 1
while (p < k):
p = p + 1
if a[p] is None:
#print("\n\nPrime: " + str(p))
a[p] = True
total = total + 1
s.append(p)
limit = n / p
new_s = []
for i in s:
j = i
while j <= limit:
new_s.append(j)
#print j*p
a[j * p] = True
total = total + 1
j = j * p
s = new_s
print("\n\nGilad's answer: " + str(total))
end = time.time()
print(end - start)
# Paul Hankin's solution
def limited_prime_factors(n, k):
ps = [False] * (k+1)
r = [True] * 2 + [False] * n
for p in xrange(2, k+1):
if ps[p]: continue
for i in xrange(p, k+1, p):
ps[i] = True
for i in xrange(p, n+1, p):
r[i] = r[i//p]
return len([i for i, b in enumerate(r) if b]) - 1
start = time.time()
print "\nPaul's answer:" + str(limited_prime_factors(1000000, 100))
end = time.time()
print(end - start)
I made this function that calculates the prime factorization of a number (n) which is obtained from the user. I am having issues with it due to the fact that It does not print the same factor more than once.
For Example:
The Prime Factorization of 3960 is:
11 5 3 3 2 2 2
However my program only prints out:
11 5 3 2
Can anyone help me to identify the cause and help me find a solution?
void primefact(int n)
{
Stack f;
assert(n >= 0);
bool prime;
for(int d = 2; d <= n; d++) // Test for factors > 1
{
if(n % d == 0)
{
prime = true;
for(int j = 2; j < d; j++) // Test for prime
{
if(d % j == 0) // It is not prime
prime = false;
}
if(prime)
f.push(d);
}
}
while(!f.empty())
{
cout << f.top() << endl;
f.pop();
}
}
You have to loop over the same prime as long as it divides the input.
Can anyone help me to identify the cause?
You're checking whether n is divisible by d, but then you move on to the next value. If n is divisible by d and d is prime, you need to actually divide n by d and check d again.
Let's take 12 as an example. Prime factors are [3, 2, 2]. Your code does this:
n = 12, d = 2
n % d == 0? Yes. Push d. d = d + 1
n % d == 0? Yes. Push d. d = d + 1
n % d == 0? No. d = d + 1
n % d == 0? No. d = d + 1
n % d == 0? No. d = d + 1
n % d == 0? No. d = d + 1
// and so on until d == n
You want code that does this:
n = 12, d = 2
n % d == 0? Yes. Push d. n = n/d // n is 6, d is 2
n % d == 0? Yes. Push d. n = n/d // n is 3, d is 2
n % d == 0? No. d = d + 1 // n is 3, d is 3
n % d == 0? Yes. Push d. n = n/d // n is 1 so you're done
You probably know yourself that your algorithm is far from optimal. So this won't hurt the performance much. Replace
if(prime)
f.push(d);
with
if (prime)
{
for (int d1 = d; n % d1 == 0; d1 *= d)
f.push(d);
}
Simplest code for prime factorization:-
for ( int i = 2; i <= num; ++i )
{
while ( num % i == 0 )
{
num /= i;
std::cout << i << std::endl;
}
}
''' Convert Arabic to Roman numeral and vice versa. '''
def arabic_to_roman(number):
''' Converts an integer to a Roman numeral. Notice
the patterns for computing M, C, and X are the
same. Computing D, L, and V follow the same pattern.
'''
output_string = ''
# compute M
roman = number / 1000
if number >= 900 and number < 1000:
output_string += 'CM'
number -= 900
else:
output_string += roman * 'M'
number -= roman * 1000
if number >= 900 and number < 1000:
output_string += 'CM'
number -= 900
# compute D
if number >= 400 and number < 900:
if number < 500:
output_string += 'CD'
number -= 400
else:
output_string += 'D'
number -= 500
# compute C
roman = number / 100
if number >= 90 and number < 100:
output_string += 'XC'
number -= 90
else:
output_string += roman * 'C'
number -= roman * 100
if number >= 90 and number < 100:
output_string += 'XC'
number -= 90
# compute L
if number >= 40 and number < 90:
if number < 50:
output_string += 'XL'
number -= 40
else:
output_string += 'L'
number -= 50
# compute X
roman = number / 10
if number == 9:
output_string += 'IX'
number -= 9
else:
output_string += roman * 'X'
number -= roman * 10
if number == 9:
output_string += 'IX'
number -= 9
# compute V
if number >= 4 and number < 9:
if number == 4:
output_string += 'IV'
number -= 4
else:
output_string += 'V'
number -= 5
# compute I
output_string += number * 'I'
number -= number
# output the result of the conversion
print '\nRoman numeral:', output_string
def roman_to_arabic(num_string):
''' Convert a Roman numeral to an Arabic numeral. '''
result = 0
result1 = 0
result2 = 0
result3 = 0
now = 0
previous = 0
index = -1
''' <Enter your code here ...> '''
for i in (num_string):
x = num_string[index]
y = num_string[index-1]
if x == 'I':
now = 1
if x == 'V':
now = 5
if x == 'X':
now = 10
if x == 'L':
now = 50
if x == 'C':
now = 100
if x == 'D':
now = 500
if x == 'M':
now = 1000
if y == 'I':
previous = 1
if y == 'V':
previous = 5
if y == 'X':
previous = 10
if y == 'L':
previous = 50
if y == 'C':
previous = 100
if y == 'D':
previous = 500
if y == 'M':
previous = 1000
if y == ' ':
previous = 0
if previous < now:
result1 = now - previous
print result1
result += result1
index += -1
elif previous == now:
result2 = previous + now
print result2
result += result2
index += -1
else:
result3 = now
print result3
result += result3
index += -1
print '\nArabic numeral:', result
print '\nArabic numeral:', result
def main():
''' The program driver. '''
conversion_option = raw_input('Conversion Options: \n (1) Arabic to Roman \n (2) Roman to Arabic \nYour choice? ')
print # prints an empty line
if conversion_option == '1':
arabic_num = int(raw_input('Enter an Arabic numeral between 1 and 3999: '))
arabic_to_roman(arabic_num)
else:
string_num = raw_input('Enter a Roman numeral between I and MMMCMXCIX: ')
string_num = " " + string_num
roman_to_arabic(string_num)
main()