Code to check for symmetry fails some test cases - python

I am running into trouble trying to get this piece of code to run for all cases:
def symmetric(p):
""" returns true if list is symmetric"""
if p==[]:return True
n=len(p)
m=len(p[0])
if m !=n:
return False
i=0
j=0
t=False
while i < n:
while j < n:
if not p[i][j]==p[j][i]:
return False
j=j+1
i=i+1
return True
When I run this, it passes for some cases.
I can't seem to see what I am doing wrong.
I'd expect [['algebra', 'combinatorics', 'graphs'], ['combinatorics', 'topology', 'sets'], ['graphs', 'topology', 'sets']] to return False but it doesn't.

The break statement only ends the inner while loop.
Since you already found an asymmetry, just use return:
i, j = 0
while i < n:
while j < n:
if not p[i][j] == p[j][i]:
return False
j += 1
i += 1
return True
However, you are not comparing each row with each column at the same index here; because you never reset j back to 0, after the first while j < n loop you'll have j == n and you skip all the remaining loops.
Set j = 0 inside the first while:
i = 0
while i < n:
j = 0
while j < n:
if not p[i][j] == p[j][i]:
return False
j += 1
i += 1
return True
Better still, use for loops over range():
for i in range(n):
for j in range(n):
if not p[i][j] == p[j][i]:
return False
return True

Related

Not able to append List to List Python ( N-Queen Problem )

I'm a beginner in Leetcode & Python and I tried to solve the N-Queen Problem. Below is the solution in Python which passed submission
class Solution:
def solveNQueens(self, n: int) -> List[List[str]]:
def isSafe(row, x_col):
# check row
for x in range(n):
if placed[row][x] is True and x != x_col:
return False
# check column
for x in range(n):
if placed[x][x_col] is True and x != row:
return False
# check diagnol
i, j = row, x_col
while i > 0 and j < n - 1:
if placed[i - 1][j + 1] is True:
return False
i -= 1
j += 1
i, j = row, x_col
while i < n - 1 and j < 0:
if placed[i + 1][j - 1] is True:
return False
i -= 1
j += 1
# #check offdiagnol
i, j = row, x_col
while i > 0 and j > 0:
if placed[i - 1][j - 1] is True:
return False
i -= 1
j -= 1
i, j = row, x_col
while i < n-1 and j < n-1:
if placed[i][j] is True:
return False
i += 1
j += 1
return True
def process(currconfig, matrix, n, row):
#base condition
if row == n:
curr = []
for x in range(n):
curr.append(currconfig[x])
totalconfig.append(currconfig)
return
for x_col in range(n):
if isSafe(row, x_col):
path = x_col * '.' + 'Q' + (n - x_col - 1) * '.'
currconfig.append(path)
matrix[row][x_col] = True
#process recursively called
process(currconfig, matrix, n, row + 1)
currconfig.pop()
matrix[row][x_col] = False
configuration = []
totalconfig = []
placed = [[False for _ in range(n)] for _ in range(n)]
process(configuration, placed, n, 0)
return totalconfig
a = Solution()
print(a.solveNQueens(4))
I only have a doubt about the base condition of the process function. In the process function's base condition I initially did this and got empty Lists appended to totalconfig no matter what, CASE I:
def process(currconfig, matrix, n, row):
if row == n:
totalconfig.append(currconfig)
return
so spent a few hours trying to get around the problem and weirdly enough for me this worked, CASE II :
def process(currconfig, matrix, n, row):
if row == n:
curr = []
for x in range(n):
curr.append(currconfig[x])
totalconfig.append(currconfig)
return
I don't get why the CASE I did not work but CASE II worked. What am I missing...How is "currconfig" in CASE I different from "curr" in CASE II
it looks like you are not using functions (methods) in classes correctly.
Basically, the first argument is the self which refers to itself. In your case, currconfig is self.
So presumably the function should have looked like this:
def process(self, currconfig, matrix, n, row): # <---added self
if row == n:
totalconfig.append(currconfig)
return

Finding the sum of prime numbers between m and n (m and n included in the sum)

def isPrime(n, i):
if i == n-1:
return ("True")
elif n%i == 0:
return ("False")
else:
return isPrime(n, i+1)
def sumOfPrime(m,n):
if m > 0 and n > 0 and m <= n:
if isPrime(m,2)==True:
temp = temp + m
return temp
else:
return (sumOfPrime(m+1,n))
else:
return temp
how can I fix the error "UnboundLocalError: local variable 'temp' referenced before assignment" without using a global variable
I reviewed your code, and this is my proposal:
def isPrime(n, i=None):
if i is None:
i = n - 1
while i >= 2:
if n % i == 0:
return False
else:
return isPrime(n, i-1)
else:
return True
def sumOfPrime(m, n):
sum = 0
for value in range(m, n+1):
if isPrime(value):
sum = sum + value
return sum
# --- test ---
result = sumOfPrime(1, 9)
print (result) # <-- prints 18
If the difference between m and n is quite high, then it is recommended that you use some type of sieve, to filter primes out in a given range. Otherwise, iterating over numbers from m to n and checking if the number is prime, it is going to be expensive for large m and n.
def is_prime(n):
if n <= 2:
return n > 1
for i in range(2, int(n ** 0.5) + 1):
if n % i == 0:
return False
return True
def prime_range_sum(m, n):
return sum(i for i in range(m, n + 1) if is_prime(i))
print(prime_range_sum(1, 9))
# prints 17
Here's my version, which I kept as close as possible to the original, while fixing some errors and making some adjustments.
def isPrime(n, i=2): # since you always use 2, just make it default
if i == n-1:
return True # return a boolean True instead of a string
elif n%i == 0:
return False # return a boolean False instead of a string
else:
return isPrime(n, i+1)
def sumOfPrime(m,n,total=0): # we will need to carry the total around, make default to 0
if 0 < m <= n: # we can simplify this complex condition
if isPrime(m):
total += m # if it's prime, increase the total...
return sumOfPrime(m+1, n, total) # and pass it to the next recursion
return total # if this is the last recursion, return total
# Example run
total = sumOfPrime(10,45)
print(total) # prints 264

Backtracking permuting a list

I am trying to permute a list but I cannot do it, it goes infinite cycle. I tried different things but somehow the only thing that it shows me is 1 2 3 ... 1 2 3 etc
This is the code:
def prints(v,k):
s = ''
for i in range(k + 1):
s += str(v[i]) + ' '
print(s)
def continuare(v,k):
ok = True
for i in range(k):
if v[i] == v[k]:
ok = False
break
return ok
def back(v,a):
k = 0
caut = False
while k>-1:
caut = False
pos = 0
while pos < len(a) and caut == False:
v[k] = a[pos]
pos += 1
if continuare(v,k):
caut = True
if caut == False:
k -= 1
elif k == len(a) - 1:
prints(v,k)
else:
k += 1
a = [1,2,3]
v = []
for x in range(len(a)):
v.append(a[0])
back(v,a)
Here's a trivial Python transcription from http://www.geeksforgeeks.org/write-a-c-program-to-print-all-permutations-of-a-given-string/ :
def swap(a, i, j):
a[i], a[j] = a[j], a[i]
def permute(a, i, n):
if i == n:
print(a)
return
for j in range(i, n+1):
swap(a, i, j)
permute(a, i+1, n)
swap(a, i, j) # backtrack
def main():
a = list('ABC')
permute(a, 0, 2)
if __name__ == '__main__':
main()
I'd rather have permute be a generator yielding the permutations, with main looping on them and printing them, but this may be closer to the C original and thus easier to follow. Note that one difference is a must: what's being permuted here is a list, not a string as in the C original, because strings are immutable in Python (so swap would require substantially different logic, returning the "string with swapped characters" rather than being able to work in-place as the "backtracking" logic requires).

return in python error only returns one value

I am having some trouble with the return. I want to add numbers produced from the function to a list already created but when I return, I just get one value, but if I use print it is fine.
Does the return only produce one value?
def aFunction(n):
for j in range(2,n):
for i in range(2,j):
if (j % i ==0):
break
else:
return(j)
break
print(aFunction(10))
Ok so this time i have edited the code slightly, how can i use p to divide n(which is an int)so that if no remainder remains i can append it to p?
def function(n):
p = [2,]
for j in range(3,n):
if (j // p) == 0:
p.append(j)
return(p)
print(function(20))
Because return terminate the function, so when condition goes to else clause, it terminate the functions,
Use generators:-
def aFunction(n):
for j in range(2,n):
for i in range(2,j):
if j % i == 0:
break
else:
yield j
break
print list(aFunction(10))
Because return terminates the function and returns the value.
You should add these values to a list and then print the list:
def aFunction(n):
l = []
for j in range(2,n):
i in range(2,j):
if (j % i != 0):
l.append(j)
return l
print(aFunction(10))
In Python, you can write a better code:
[j for j in range(2,n) for i in range(2,j) if j % i != 0]

Python: break out of multiple levels of loop

I have this pseudocode for a Miller-Rabin primality tester:
function isPrime(n, k=5)
if n < 2 then return False
for p in [2,3,5,7,11,13,17,19,23,29]
if n % p == 0 then return n == p
s, d = 0, n-1
while d % 2 == 0
s, d = s+1, d/2
for i from 0 to k
x = powerMod(randint(2, n-1), d, n)
if x == 1 or x == n-1 then next i
for r from 1 to s
x = (x * x) % n
if x == 1 then return False
if x == n-1 then next i
return False
return True
But translating that to Python is hard because of the next i statement in the inner for loop, which must break two loops. There is no goto in Python. Other questioners who have asked this question on Stack Overflow have been told to use a local function with a return, or a try/except condition, or an additional boolean flag, but those solutions either don't apply here or would greatly uglify this lovely pseudocode.
What is the Pythonic approach to this problem?
I think the pythonic approach would be try/except, readability would prefer a method or a boolean, but I think that this is solvable by adding a single line:
for i in xrange(k):
x = powerMod(randint(2, n-1), d, n)
if x == 1 or x == n-1: continue
for r in xrange(1,s):
x = (x * x) % n
if x == 1: return False
if x == n-1: break #*
if x != n-1: #added line
return False
return True
breaking on the line marked with #* is problematic because it returns false, but if we fix that it's just like "next i".
Another solution, suggested by tobias_k, is to use for/else:
for i in xrange(k):
x = powerMod(randint(2, n-1), d, n)
if x == 1 or x == n-1: continue
for r in xrange(1,s):
x = (x * x) % n
if x == 1: return False
if x == n-1: break
else: #added line
return False
return True
return False statement would not be called if the loop was break-ed - only if it was exhausted.
You can use break and continue witn a for: else.
for i from 0 to k
x = powerMod(randint(2, n-1), d, n)
# Use 'continue' to go to next i (skip inner loop).
if x == 1 or x == n-1 then next i
for r from 1 to s
x = (x * x) % n
if x == 1 then return False
# Use 'break' to exit this loop and go to next i
# since this loop is at the end of the i loop.
if x == n-1 then next i
else:
# This is only reached if no `break` occurred
return False
return True

Categories