How to build a list of vectors taken from an other list that satisfy a constraint - z3py

It's my first try with z3.
I want to find which vectors taken in a list I have to sum to get a given result.
I've try this but that don't compile because R isn't an indice.
Tr_tuple = ((-1,1,0,1,0,0,0,-1),
(1,-1,1,0,0,0,-1,0),
(0,-1,-1,1,0,1,0,0),
(-1,0,1,-1,0,0,0,0),
(0,0,0,-1,-1,1,0,1),
(0,0,-1,0,1,-1,1,0),
(0,1,0,0,0,-1,-1,1),
(1,0,0,0,-1,0,1,-1),
(1,1,-1,-1,1,1,-1,-1),
(-1,-1,1,1,-1,-1,1,1))
Start_tuple = (1,-1,0,-1,0,0,0,1)
depth = 2
G = [Int('g_%s' % i) for i in range(8)]
R = [Int('r_%s' % i) for i in range(depth)]
R_c = [ And (R[i] >= 0, R[i] < 10) for i in range(depth) ]
G_c = [G[i] == Start_tuple[i] + sum([ Tr_tuple[j][i] for j in R]) for i in range(8)]
G_g = [G[i] == 0 for i in range(8)]

I found something but it's like brute force :
M = [[Int('m_%s_%s' % (j,i)) for i in range(8)] for j in range(depth)]
T = [Int('t_%s' % i) for i in range(8)]
M_c = And([
Or([
And([M[j][i] == Tr_tuple[k][i] for i in range(8)])
for k in range(10)])
for j in range(depth)])
G_c = (And([Start_tuple[i]+sum([M[j][i] for j in range(depth)]) == 0 for i in range(8)]))
s = Solver()
s.add(M_c)
s.add(G_c)
if s.check() == sat :
pp(s.model())
else:
print('No solution found')

Related

Algorithm problem about Google kick start round B 2021

I'm solving the longest progression problem in Google kick start 2021 Round B using python.
Here is the link to the problem: https://codingcompetitions.withgoogle.com/kickstart/round/0000000000435a5b
I have written the following code but it seems that there's always the wrong answer in a test case, I have tried all situations as far as I concerned, can someone give me the help that where's the problem in my code, thanks!
def solution(A, N):
i, j = 0, 1
ranges = {}
res = 0
left = {}
right = {}
while j < N:
diff = A[j] - A[i]
while j < N and A[j]-A[i] == (j-i)*diff:
j += 1
ranges[(i, j-1)] = diff
left[i] = (i, j-1)
right[j-1] = (i, j-1)
if j <= N-1 or i > 0:
res = max(res, j-i+1)
else:
res = max(res, j-i)
i = j-1
# check if two ranges can be merged
for i in range(1, N-1):
if i == 1:
if i+1 in left:
l1, r1 = left[i+1]
if A[i+1]-A[i-1] == 2*ranges[left[i+1]]:
res = max(res, r1-l1+3)
elif i == N-2:
if i-1 in right:
l1, r1 = right[i-1]
if A[i + 1] - A[i - 1] == 2 * ranges[right[i - 1]]:
res = max(res, r1 - l1 + 3)
else:
if i+1 in left and i-1 in right and ranges[right[i-1]] == ranges[left[i+1]]:
l1, r1 = right[i - 1]
l2, r2 = left[i+1]
if A[i+1]-A[i-1] == 2*ranges[left[i+1]]:
res = max(r1-l1+r2-l2+3, res)
return res
if __name__ == "__main__":
T = int(input().strip())
for i in range(T):
N = int(input().strip())
A = list(map(int, input().strip().split(" ")))
res = solution(A, N)
print("Case #{}: {}".format(i+1, res))
The merging logic is incorrect. The code only tries to merge the entire ranges. In a simple failing case
1 2 3 6 5 4
it misses that replacing 6 with 4 would produce 1 2 3 4 5.

logical matrix how to find efficiently row/column with true value

I'm trying to find a efficient solution for the next riddle:
i have a logical matrix at (n * n) size filled in false values
i need to create a function that will get zero or one as argument it will shift all
the values in the matrix one step to the left (meaning the first
element on the first row is deleted and the last element in the last
row is our new bit) and return true if there is a row/column in our
matrix contains only one's values.
No limitation on the data structure.
My naive solution in javascript:
const next = (bit, matrix) => {
matrix.shift()
matrix.push(bit);
const matrix_size = Math.sqrt(matrix.length);
let col_sum = 0;
let row_sum = 0;
for (let i = 0; i < matrix.length; ++i) {
col_sum = matrix[i];
row_sum += matrix[i];
if ((i + 1) % matrix_size === 0) {
if (row_sum === matrix_size) return true;
row_sum = 0;
}
for (let j = i + matrix_size;j < (i + ((matrix_size * matrix_size) - 1)); j += matrix_size) {
col_sum += matrix[j];
}
if (col_sum === matrix_size) return true;
}
return false;
}
i used 1d array as data structure but it doesn't really help my to reduce time complexity.
Love to hear some ideas :)
Let’s think about following example matrix:
[0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 1, 1,
1, 1, 1, 1]
and push zero 16 times.
Then, False, True, True, True, False, True, True, True, False, True, True, True, False, False False and False will be obtained.
There is cyclic behavior (False, True, True, True).
If the length of continued ones was fixed, it isn’t necessary to recalculate every time in update.
Updated the matrix, the length of continued ones at top-left and bottom-right can be change, and it can be needed to update the cyclic memory.
Maintaining continued ones sequences, maintaining total count of cyclic behavior affected by the sequences, the complexity for the rows will be in O(1).
In case of column, instead of shifting and pushing, let matrix[cur]=bit and cur = (cur+1)%(matrix_size*matrix_size) to represent cur as the actual upper-left of the matrix.
Maintaining col_sum of each column, maintaining total count satisfying the all-ones-condition, the complexity will be O(1).
class Matrix:
def __init__(self, n):
self.mat = [0] * (n*n)
self.seq_len = [0] * (n*n)
self.col_total = [0] * n
self.col_archive = 0
self.row_cycle_cnt = [0] * n
self.cur = 0
self.continued_one = 0
self.n = n
def update(self, bit):
prev_bit = self.mat[self.cur]
self.mat[self.cur] = bit
# update col total
col = self.cur % self.n
if self.col_total[col] == self.n:
self.col_archive -= 1
self.col_total[col] += bit - prev_bit
if self.col_total[col] == self.n:
self.col_archive += 1
# update row index
# process shift out
if prev_bit == 1:
prev_len = self.seq_len[self.cur]
if prev_len > 1:
self.seq_len[(self.cur + 1) % (self.n * self.n)] = prev_len-1
if self.n <= prev_len and prev_len < self.n*2:
self.row_cycle_cnt[self.cur % self.n] -= 1
# process new bit
if bit == 0:
self.continued_one = 0
else:
self.continued_one = min(self.continued_one + 1, self.n*self.n)
# write the length of continued_one at the head of sequence
self.seq_len[self.cur+1 - self.continued_one] = self.continued_one
if self.n <= self.continued_one and self.continued_one < self.n*2:
self.row_cycle_cnt[(self.cur+1) % self.n] += 1
# update cursor
self.cur = (self.cur + 1) % (self.n * self.n)
return (self.col_archive > 0) or (self.row_cycle_cnt[self.cur % self.n] > 0)
def check2(self):
for y in range(self.n):
cnt = 0
for x in range(self.n):
cnt += self.mat[(self.cur + y*self.n + x) % (self.n*self.n)]
if cnt == self.n:
return True
for x in range(self.n):
cnt = 0
for y in range(self.n):
cnt += self.mat[(self.cur + y*self.n + x) % (self.n*self.n)]
if cnt == self.n:
return True
return False
if __name__ == "__main__":
import random
random.seed(123)
m = Matrix(4)
for i in range(100000):
ans1 = m.update(random.randint(0, 1))
ans2 = m.check2()
assert(ans1 == ans2)
print("epoch:{} mat={} ans={}".format(i, m.mat[m.cur:] + m.mat[:m.cur], ans1))

Understanding Spark correlation algorithm

I was reading Spark correlation algorithm source code and while going through the code, I coulddn't understand this particular peace of code.
This is from the file : org/apache/spark/mllib/linalg/BLAS.scala
def spr(alpha: Double, v: Vector, U: Array[Double]): Unit = {
val n = v.size
v match {
case DenseVector(values) =>
NativeBLAS.dspr("U", n, alpha, values, 1, U)
case SparseVector(size, indices, values) =>
val nnz = indices.length
var colStartIdx = 0
var prevCol = 0
var col = 0
var j = 0
var i = 0
var av = 0.0
while (j < nnz) {
col = indices(j)
// Skip empty columns.
colStartIdx += (col - prevCol) * (col + prevCol + 1) / 2
av = alpha * values(j)
i = 0
while (i <= j) {
U(colStartIdx + indices(i)) += av * values(i)
i += 1
}
j += 1
prevCol = col
}
}
}
I do not know Scala and that could be the reason I could not understand it. Can someone explain what is happening here.
It is being called from Rowmatrix.scala
def computeGramianMatrix(): Matrix = {
val n = numCols().toInt
checkNumColumns(n)
// Computes n*(n+1)/2, avoiding overflow in the multiplication.
// This succeeds when n <= 65535, which is checked above
val nt = if (n % 2 == 0) ((n / 2) * (n + 1)) else (n * ((n + 1) / 2))
// Compute the upper triangular part of the gram matrix.
val GU = rows.treeAggregate(new BDV[Double](nt))(
seqOp = (U, v) => {
BLAS.spr(1.0, v, U.data)
U
}, combOp = (U1, U2) => U1 += U2)
RowMatrix.triuToFull(n, GU.data)
}
The correlation is defined here:
https://en.wikipedia.org/wiki/Pearson_correlation_coefficient
The final goal is to understand the Spark correlation algorithm.
Update 1: Relevent paper https://stanford.edu/~rezab/papers/linalg.pdf

Ford-Fulkerson Max Flow Implement in Python

Here is my python code to preform a Ford-Fulkerson operation on a multi-sink, multi-source graph (E) with sources S and sinks D
The max that will flow through is 2 million. I used dummy sources and dummy sinks to solve this problem. I know that I set up the dummy sources and sinks right. because my code passes if I use Geek for geek's implementation but I really want to understand why mine doesnt work. Any one have suggestions?
i_sources = len(E)
n = i_sources +1
x = [[0]*(len(E[0])+2) for i in range(len(E)+2)]
for i in range(0, len(E)):
E[i] += [0,0]
E += [[0]*len(E[0]) for i in range(2)]
for s in S: # set sources
E[i_sources][s] = 2000000
for d in D: # set Drains
E[d][n] = 2000000
l = [None]*len(E)
l[i_sources] = [float('Inf'), None, None]
q = [i_sources]
while(q != []): # queue not empty
i = q.pop(0)
for j in range(0, len(E)): # forward links
if(l[j] == None and j != i and E[i][j] != 0):
r = E[i][j]-x[i][j]
if r>0:
l[j] = [min(l[i][0], r), i, '+']
q.append(j)
for j in range(0, len(E)): #reverse links
if(l[j] == None and j != i and E[i][j] != 0):
if x[j][i]>0:
l[j] = [min(l[i][0], x[j][i]), i, '-']
q.append(j)
if(l[n] != None): # backtrack if needed
j = n
while (j != i_sources):
i = abs(l[j][1])
if(l[j][2] == '+'):
x[i][j] += l[n][0]
else:
x[j][i] -= l[n][0]
j=i
l = [None]*len(E)
l[i_sources] = [float('Inf'), None, None]
q = [i_sources]
sum_x = 0
for i in range(0, n):
sum_x += x[i][n]
return min(sum_x, 2000000)

Something wrong with my PollardP1_rho code but I don't know how to fix it

I tried to use MillerRabin + PollardP1_rho method to factorize an integer into primes in Python3 for reducing time complexity as much as I could.But it failed some tests,I knew where the problem was.But I am a tyro in algorithm, I didn't know how to fix it.So I will put all relative codes here.
import random
def gcd(a, b):
"""
a, b: integers
returns: a positive integer, the greatest common divisor of a & b.
"""
if a == 0:
return b
if a < 0:
return gcd(-a, b)
while b > 0:
c = a % b
a, b = b, c
return a
def mod_mul(a, b, n):
# Calculate a * b % n iterately.
result = 0
while b > 0:
if (b & 1) > 0:
result = (result + a) % n
a = (a + a) % n
b = (b >> 1)
return result
def mod_exp(a, b, n):
# Calculate (a ** b) % n iterately.
result = 1
while b > 0:
if (b & 1) > 0:
result = mod_mul(result, a, n)
a = mod_mul(a, a, n)
b = (b >> 1)
return result
def MillerRabinPrimeCheck(n):
if n in {2, 3, 5, 7, 11}:
return True
elif (n == 1 or n % 2 == 0 or n % 3 == 0 or n % 5 == 0 or n % 7 == 0 or n % 11 == 0):
return False
k = 0
u = n - 1
while not (u & 1) > 0:
k += 1
u = (u >> 1)
random.seed(0)
s = 5 #If the result isn't right, then add the var s.
for i in range(s):
x = random.randint(2, n - 1)
if x % n == 0:
continue
x = mod_exp(x, u, n)
pre = x
for j in range(k):
x = mod_mul(x, x, n)
if (x == 1 and pre != 1 and pre != n - 1):
return False
pre = x
if x != 1:
return False
return True
def PollardP1_rho(n, c):
'''
Consider c as a constant integer.
'''
i = 1
k = 2
x = random.randrange(1, n - 1) + 1
y = x
while 1:
i += 1
x = (mod_mul(x, x, n) + c) % n
d = gcd(y - x, n)
if 1 < d < n:
return d
elif x == y:
return n
elif i == k:
y = x
k = (k << 1)
result = []
def PrimeFactorsListGenerator(n):
if n <= 1:
pass
elif MillerRabinPrimeCheck(n) == True:
result.append(n)
else:
a = n
while a == n:
a = PollardP1_rho(n, random.randrange(1,n - 1) + 1)
PrimeFactorsListGenerator(a)
PrimeFactorsListGenerator(n // a)
When I tried to test this:
PrimeFactorsListGenerator(4)
It didn't stop and looped this:
PollardP1_rho(4, random.randrange(1,4 - 1) + 1)
I have already tested the functions before PollardP1_rho and they work normally,so I know the function PollardP1_rho cannot deal the number 4 correctly,also the number 5.How can I fix that?
I have solved it myself.
There is 1 mistake in the code.
I should not use a var 'result' outside of the function as a global var,I should define in the function and use result.extend() to ensure the availability of the whole recursive process.So I rewrote PollardP1_rho(n, c) and PrimeFactorsListGenerator(n):
def Pollard_rho(x, c):
'''
Consider c as a constant integer.
'''
i, k = 1, 2
x0 = random.randint(0, x)
y = x0
while 1:
i += 1
x0 = (mod_mul(x0, x0, x) + c) % x
d = gcd(y - x0, x)
if d != 1 and d != x:
return d
if y == x0:
return x
if i == k:
y = x0
k += k
def PrimeFactorsListGenerator(n):
result = []
if n <= 1:
return None
if MillerRabinPrimeCheck(n):
return [n]
p = n
while p >= n:
p = Pollard_rho(p, random.randint(1, n - 1))
result.extend(PrimeFactorsListGenerator(p))
result.extend(PrimeFactorsListGenerator(n // p))
return result
#PrimeFactorsListGenerator(400)
#PrimeFactorsListGenerator(40000)
There is an additional tip: You don't need to write a function mod_mul(a, b, n) at all, using Python built-in pow(a, b, n) will do the trick and it is fully optimized.

Resources