The Solution About Foobar Challenge "Find The Access Code" - python-2.7

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

Related

Rabin Karp Algorithm Negative Hash

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;

Explanation of the algorithm to find a number 'm' made up of digits 0's and 1's which is divisible by the number n

Here's a piece of code from a udemy course that I am currently taking that uses the pigeon hole principle to find a number made up of 0's and 1's divisible by the number n.
void findNumber(int n) {
int cur_rem = 0;
for(int i = 1; i <= n; i++) {
cur_rem = (cur_rem * 10 + 1) % n;
if(cur_rem == 0) {
for(int j = 1; j <= i; j++)
cout << 1;
return;
}
if(fr[cur_rem] != 0) {
for(int j = 1; j <= i - fr[cur_rem]; j++)
cout << 1;
for(int j = 1; j <= fr[cur_rem]; j++)
cout << 0;
return;
}
fr[cur_rem] = i;
}
}
So, in this code we actually first take the numbers 1,11,111,...,111..1(n times) and see if they are divisible by the given integer n. If they are not divisible then we find the 2 numbers within 1,11,111,...111..1(n times) with the same remainder when divided by the number n and subtract them to get the number that is divisible by n. So, I understand the theory part but I did not understand one line of the code.
Can someone please explain to me this line of code: cur_rem = (cur_rem * 10 + 1) % n; how can we get the remainder of the current number by multiplying the remainder of the previous number by 10 and then adding 1 and then finding the mod by dividing the sum by the given integer n?
Suppose the last number 111... (we'll call it m), had remainder r.
m % n = r
m = kn + r
Now the next number, 111..., call it m', is one digit longer than m.
m' = 10 m + 1
m' % n = (10 m + 1) % n
= (10(kn + r) + 1) % n
= (10 kn + 10r + 1) % n
= ( 10r + 1) % n

Find the prime factors of a number - wrong output

The code is given below:
n = input("Enter n: ")
f = 0
j = 2
for i in range(1, n/2 + 1):
if n % i == 0:
if i % j == 0:
f = 1
break
if f ==0:
print i ,
j = j + 1
When I enter 21 as the input, I only get 1.
Can anyone correct my code ?
you can try this:
n = input("Enter n: ")
f = 0
j = 2
for i in range(1,n/2+1):
if n%i == 0:
for j in range(2,i/2+1): #you need another loop to insure i has no factors
if i%j == 0:
f+=1
if f==0:
print i ,
f = 0

Can someone please explain this algorithm in C++?

Quadratic Maximum contiguous subsequence sum algorithm
int maxSubSum2( const vector<int> & a)
{
int maxSum = 0;
for (int i = 0; i< a.size(); ++i)
{
int thisSum = 0;
for (int j = i; j < a.size(); ++j)
{
thisSum += a[j];
if (thisSum > maxSum)
maxSum = thisSum;
}
}
return maxSum;
}
I was wondering if anyone can explain how the algorithm works? I am good with for loops, I'm just bad at nested ones. Is "thisSum" always 0 every time the outer for loop on line 8 runs or is it static?
Thank you very much! I am trying really hard to understand the algorithm. Please help me! I really appreciate the time and effort.
The outer loop iterates over every element of the vector a. On each iteration, i will be the index of the current element, it resets thisSum to 0, and it then executes the inner loop.
The inner loop iterates over every element starting from i. On each iteration, j will be the index of its current element. It then calculates the sum of these elements in thisSum.
The outer loop replaces maxSum with thisSum if it's higher than what it already contains.
So if the vector contains:
1 7 -10 2 4
the successive iterations of the outer loop will calculate the following values of thisSum:
1 + 7 + -10 + 2 + 4 = 4
7 + -10 + 2 + 4 = 3
-10 + 2 + 4 = -4
2 + 4 = 6
4 = 4
The first iteration it will set maxSum to 4. After the 2nd and 3rd iterations, thisSum > maxSum will be false, so it won't change it. On the 4th iteration, 6 > 4, so it will set maxSum to 6. The last iteration won't change it. Finally, it will return 6.
Every time the outer for loop loops, this sum is reset to 0 because of the =0 that is on the first line of the outer loop.
I suggest you modify your function to print i, j, and thisSum in the inner loop so that you can see how they are changing.
Example a = [1, 2, 3, 4, 5]
j starts at the value of i, so it will first start at 0, then 1, then 2 and so on. Thus this second, inner loop is smaller each time the outer loop increments.
thisSum is reset to 0 each time as it is NOT static. If it was, it would be labeled static.
Basically, in this algorithm the outer loop is used to push the 'starting index' forward, with the inner loop used to actually add all the elements of the array / vector together.
So the executions of the inner loop for the example above would be like this:
Execution 1: 1 + 2 + 3 + 4 + 5
Execution 2: 2 + 3 + 4 + 5
Execution 3: 3 + 4 + 5
Execution 4: 4 + 5
Execution 5: 5
Hope that helps.
thisSum at your code line 8 is reset at beginning part of loop i,
but thisSum in your loop j is keep adding the array a[ ] element in loop j.
Normally I will substitute value and assume value to understand how the loop work.
Let assume vector a has 3 int elements 10,-20,100
therefore a.size() = 3
//maxSum is initialized in the function
int maxSum = 0;
//Start First i loop
int i = 0; i < 3;
int thisSum = 0;
int j = i = 0; j < 3;
thisSum += a[0];
//thisSum = 10
//10 > 0
if (thisSum > maxSum) maxSum = thisSum = 10;
int j = i = 1; j < 3;
thisSum += a[1];
//thisSum = -10
// -10 not > 10
int j = i = 2; j < 3;
thisSum += a[2];
//thisSum = 90
//90 > 10
if (thisSum > maxSum) maxSum = thisSum = 90;
//End First i loop
//Start 2nd i loop
int i = 1; i < 3;
int thisSum = 0;
int j = i = 1; j < 3;
thisSum += a[1];
//thisSum = -20
//-20 not > 90
int j = i = 2; j < 3;
thisSum += a[2];
//thisSum = 80
//80 not > 90
//End 2nd i loop
//Start 3rd i loop
int i = 2; i < 3;
int thisSum = 0;
int j = i = 2; j < 3;
thisSum += a[2];
//thisSum = 100
//100 > 90
if (thisSum > maxSum) maxSum = thisSum = 100;
//End 3rd i loop
//return 100
//return maxSum
The concept of the function is it try to get the maximum sum by step by step remove the item from smallest index element to the largest index argument.
1st loop i : maxSum = 90
2nd loop i : maxSum = 90 (remove 10)
3rd loop i : maxSum = 100 (remove 10,-20)

why a heap node of index i (starting from 1) and its height h satisfy (2^h)*i <= n < (2^(h+1)*i) where n is the heap size?

why a heap node of index i (starting from 1) and its height h satisfy (2^h)*i <= n < (2^(h+1)*i) where n is the heap size?
Case N:1
2^h <= 1 <= 2^(h+1)
Note height of node is log(n) = log(1) = 0
= 2^0 <= 1 <= 2^(0+1)
= 1 <= 1 <= 2
So you can see its true for case n = 1
Let replace h = log(n) into the original question
= 2^h <= n <= 2^(h+1)
= 2^(log(n)) <= n <= 2^(log(n)+1) #replace n = log(n)
= n <= n <= 2^log(n) * 2^1 #exponents property
= n <= n <= 2n
Note the index 'i' cancels out if we divide by 'i' on each side.