import os
from collections import counter
cwd = os.getcwd()
filename1 = cwd + "/sudoku1.txt"
grid1 = []
with open(filename1) as f:
for line in f:
grid1.append([int(i) for i in line.split()])
cwd = os.getcwd()
filename2 = cwd + "/sudoku2.txt"
grid2 = []
with open(filename2) as f:
for line in f:
grid2.append([int(i) for i in line.split()])
cwd = os.getcwd()
filename3 = cwd + "/sudoku3.txt"
grid3 = []
with open(filename3) as f:
for line in f:
grid3.append([int(i) for i in line.split()])
def allDifferent1D(l):
for i in l:
if i != 0:
if l.count(i)>1:
return False
return True
def allDifferent2D(l):
for row in l:
if not allDifferent1D(row):
return False
for c in range(len(l)):
col = []
for r in range(len(l)):
col.append(l[r][c])
if not allDifferent1D(col):
return False
return True
def checkAll3By3s(grid):
for i in [0,3,6]:
for j in [0,3,6]:
subGrid = [grid[i][j:j+3]]
subGrid.append(grid[i+1][j:j+3])
subGrid.append(grid[i+2][j:j+3])
if not check3By3(subGrid):
return False
return True
def check3By3(grid):
contains = dict()
for i in range(0,10):
contains[i] = False
for i in range(3):
for j in range(3):
if contains[grid[i][j]]:
return False
else:
contains[grid[i][j]] = True
return True
def isValidSudoku(grid):
# Check all rows and columns
if (not allDifferent2D(grid)):
return False
if (not checkAll3By3s(grid)):
return False
return True
def complete(grid):
#checks the grid for any zeros or negatives. Takes priority over the sudoku checking aspect as it is implied to be invalid
for i in range(len(grid)):
for j in range(len(grid[i])):
if grid[i][j]<=0:
return False
if (not allDifferent2D(grid)):
return False
if (not checkAll3By3s(grid)):
return False
return True
def compatableValue(grid,k):
# creates a dictionary for each row/column that, for the purpose of this function, takes k and compares it with other values in the row/column, giving it a value of 1 if it is unique for the grid[i][j] value solveSudoku is iterating over
for i in range(len(grid)):
seenValues=dict()
for j in range(len(grid[i])):
a=collections.counter(grid[i][j])
if k != 0 and k in seenValues:
return False
seenValues[k] += 1
return seenValues[k]
def solveSudoku(grid):
#if the grid isnt a sudoku solution, the function sets out to fill in blank spaces(as pre filled in spots are the conditions for the grid and thus necessary
if complete(grid)==True:
return(grid)
for i in range(0,9):
for j in range(0,9):
#only proceeds to change a value if it is zero. Calls compatableValue to see if each prospective value has been used
if grid[i][j]==0:
for k in range(1,10):
if compatableValue(grid,k)==1:
grid[i][j]=k
print(grid)
result=solveSudoku(grid)
if result != False:
solveSudoku(grid)
#changes values back to zero for next attempt at solving the problem
grid[i][j]=0
return False
return True
print(solveSudoku(grid2))
I am trying to solve the sudoku puzzle in which empty spaces are represented with zeros, and fill them in based on whether or not a counter has found them already in the row/column/3by3 grid. I am using python 3.4.1 and the counter does not work. I do not know what I am doing wrong.
Your import is:
from collections import counter
but then you try to use collections.counter instead. You never imported collections, so that will be a NameError exception. To fix it, change your import to
import collections
Also, as #DSM mentions in a comment, Counter must be spelled with an uppercase C.
I believe you have many other mistakes in that long, extremely repetitive code, for example you're trying to do a=collections.counter(grid[i][j]) -- counter called with a number makes no sense (and will fail), and then you ignore a anyway, I believe.
But the number of bugs per question should be low, so by fixing one I think I've done my part for now:-)
From the python docs:
c = Counter() # a new, empty counter
c = Counter('gallahad') # a new counter from an iterable
c = Counter({'red': 4, 'blue': 2}) # a new counter from a mapping
c = Counter(cats=4, dogs=8) # a new counter from keyword args
Counter() returns a counter object, and you can pass it either nothing, an iterable, a mapping or multiple named amounts. The idea behind a counter object is that it will count how many times a value is added to it. Say, if I want to count fruits in a bowl, I can do things like:
bowl = Counter()
bowl['banana'] = 3
bowl['banana'] += 4
Now in your code, you seem to be passing the content of a single sudoku cell to the Counter's constructor. I'm not sure about what you're trying to do with the counter, but I don't think you need one in the first place. You're not even using the counter after its failed creation. And I don't understand what the seenValues dict is used for. Perhaps you should try writing what you're trying to do in English first so we can understand what you're trying to achieve.
Related
I'm solving this LeetCode problem and here's my code:
class Solution:
def alienOrder(self, words: List[str]) -> str:
adjacent = defaultdict(set)
for i in range(1, len(words)):
w1, w2 = words[i - 1], words[i]
min_len = min(len(w1), len(w2))
if len(w1) > len(w2) and w1[:min_len] == w2[:min_len]:
return ""
for j in range(min_len):
if w1[j] != w2[j]:
adjacent[w1[j]].add(w2[j]) # modify, not in the loop causing error
break
visited = dict()
res = []
def dfs(c):
if c in visited:
return visited[c]
visited[c] = True
for neighbor in adjacent[c]: # read only
if dfs(neighbor):
return True
visited[c] = False
res.append(c)
return False
for c in adjacent: # RuntimeError: dictionary changed size during iteration
if dfs(c):
return ''
return ''.join(reversed(res))
The line for c in adjacent throws "RuntimeError: dictionary changed size during iteration", which I don't understand. I'm not modifying adjacent in dfs(), am I?
The main Problem is when dfs method is called it uses this line
for neighbor in adjacent[c]:
This just returns the associated value if it exists in defaultdict, if it doesn't exist in it, it creates and adds a key if you try to access key that doesn't exist.
Potential line that triggers accessing adjacent defaultdict without knowing whether it exist or not is
if dfs(neighbor):
neighbor might be or might not be in adjacent defaultdict this causes defaultdict to change. You might check if it exists if not u might want to skip.
#gilf0yle points out the problem is with defaultdict potentially inserting new keys. The solution is to "freeze" it before iteration by casting to a normal dict
adjacent = dict(adjacent) # No more default key insertion from here on
for c in adjacent:
if dfs(c):
return ''
return ''.join(reversed(res))
I'm attempting to generate all n choose k combinations of a list (not checking for uniqueness) recursively by following the strategy of either include or not include an element for each recursive call. I can definitely print out the combinations but I for the life of me cannot figure out how to return the correct list in Python. Here are some attempts below:
class getCombinationsClass:
def __init__(self,array,k):
#initialize empty array
self.new_array = []
for i in xrange(k):
self.new_array.append(0)
self.final = []
self.combinationUtil(array,0,self.new_array,0,k)
def combinationUtil(self,array,array_index,current_combo, current_combo_index,k):
if current_combo_index == k:
self.final.append(current_combo)
return
if array_index >= len(array):
return
current_combo[current_combo_index] = array[array_index]
#if current item included
self.combinationUtil(array,array_index+1,current_combo,current_combo_index+1,k)
#if current item not included
self.combinationUtil(array,array_index+1,current_combo,current_combo_index,k)
In the above example I tried to append the result to an external list which didn't seem to work. I also tried implementing this by recursively constructing a list which is finally returned:
def getCombinations(array,k):
#initialize empty array
new_array = []
for i in xrange(k):
new_array.append(0)
return getCombinationsUtil(array,0,new_array,0,k)
def getCombinationsUtil(array,array_index,current_combo, current_combo_index,k):
if current_combo_index == k:
return [current_combo]
if array_index >= len(array):
return []
current_combo[current_combo_index] = array[array_index]
#if current item included & not included
return getCombinationsUtil(array,array_index+1,current_combo,current_combo_index+1,k) + getCombinationsUtil(array,array_index+1,current_combo,current_combo_index,k)
When I tested this out for the list [1,2,3] and k = 2, for both implementations, I kept getting back the result [[3,3],[3,3],[3,3]]. However, if I actually print out the 'current_combo' variable within the inner (current_combo_index == k) if statement, the correct combinations print out. What gives? I am misunderstanding something to do with variable scope or Python lists?
The second method goes wrong because the line
return [current_combo]
returns a reference to current_combo. At the end of the program, all the combinations returned are references to the same current_combo.
You can fix this by making a copy of the current_combo by changing the line to:
return [current_combo[:]]
The first method fails for the same reason, you need to change:
self.final.append(current_combo)
to
self.final.append(current_combo[:])
Check this out: itertools.combinations. You can take a look at the implementation as well.
I want to be able to validate parenthesis so they enclose and ignore any type of characters. As long as there is the valid use of enclosure of strings with parenthesis then True else `False.
I am still new to python so I'm not sure how to properly create an if statement for this certain condition. I am trying to create an fi statement such that when I .pop() an empty deque() I will be able to return False instead of receiving the error message:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: pop from an empty deque
Perhaps there is another better method around solving this problem. If so I would be glad to see how someone else would solve it
For example:
a = 'sdf(sadf(sdf)sdf)sdfsd0sdf)sdf(sdf0)' # false
b = 'dsf))))(((((dsfsdf' # false
c = '()()()()' # true
d = '((((asd(asd)asd)()()asd))' # true
my code:
# any letter is ignored
# jsut make sure that the parenthesis are equal
from collections import *
def str_valid(stringy):
param_stack = deque()
for n in stringy:
if n ==')':
param_stack.pop()
if n == '(':
param_stack.append('(')
if param_stack == []:
return True
else:
return False
a = 'sdf(sadf(sdf)sdf)sdfsd0sdf)sdf(sdf0)' # false
b = 'dsf))))(((((dsfsdf' # false
c = '()()()()' # true
d = '((((asd(asd)asd)()()asd))' # true
print str_valid(a)
print str_valid(b)
print str_valid(c)
print str_valid(d)
If you just want an if statement to check if the deque is empty before pop(), you can use
if n ==')':
if param_stack:
param_stack.pop()
else:
return false
...
if param_stack will implicitly convert it to a boolean which return true if it contains some elements and false otherwise.
A few things to note: first, the only methods of deque you're using are append() and pop. So it's more natural to use an ordinary Python list. A deque isn't more efficient than a list unless you need to put things on, or take things off, "the left end".
Second, you already know how to test for an empty deque! You did that here:
if param_stack == []:
Now that's a little odd, because you're comparing a deque to a list, but it works. With a little more experience, you'll write that as:
if len(param_stack) == 0:
and with more experience still, you may use:
if not param_stack:
(an empty container generally behaves like False in truth-y contexts).
But however you write it, rather than introduce try/except blocks, it's easier and clearer to do something like:
if n ==')':
if param_stack: # i.e., if it's not empty
param_stack.pop()
else: # it's empty
return False
Clear?
If you just want to pop() an empty deque without problems:
from collections import deque
d = deque()
try:
d.pop()
except IndexError:
pass # do whatever you want in the case that there is nothing there
return False # is this what you want?
else:
pass # do whatever you want in the case that there is something there
Just a warning in case you don't know: keep the amount of code inside any of try/except/else/finally as short and focused as possible. It's easy to end up with errors popping up inside error handlers and leading to surprises.
If that's not what you need, please clarify what in your code is not working.
Simply catch the error and return False:
for n in stringy:
if n ==')':
try:
param_stack.pop()
except IndexError:
return False
Use try, except to catch the IndexError exception and then return False
try:
param_stack.pop()
except IndexError:
# catch your IndexError exception and do what you want
return False
As other people already mentioned you don't really need a queue, a simple counter is enough:
def str_valid(txt):
ctr = 0
for n in txt:
if n == '(':
ctr = ctr + 1
if n == ')':
ctr = ctr - 1
if ctr < 0:
return False
return ctr == 0
Or shorter:
def str_valid(txt):
ctr = 0
for n in txt:
ctr = ctr + (n == '(') - (n == ')')
if ctr < 0:
return False
return ctr == 0
Or a "hacky" one-liner :)
def str_valid(txt):
return not reduce(lambda t, c: t if t < 0 else t + (c == '(') - (c == ')'), txt, 0)
I'm wondering how to do the following in Python.
If I have a function with a for loop, it is possible to with an if statement to skip certain numbers.
This is an implementation of fisher-yates d got from activestate.com.
import random
def shuffle(ary):
a=len(ary)
b=a-1
for d in range(b,0,-1):
e=random.randint(0,d)
if e == d:
continue
ary[d],ary[e]=ary[e],ary[d]
return ary
Now continue simply goes to the next value for d. How can I, instead of doing continue, rerun the function with the original parameter ary?
Note that the function is just some example code, I'm curious on how to do this in general.
Also, maintaining a copy of the array might not be possible if the list is big, so thats not really a solution imo.
This is a common recursive pattern. However, your case is a little different than usual because here you need to make a copy of your input list to use when you recurse if the shuffling fails.:
import random
def shuffle(ary):
initial = ary[:]
a=len(ary)
b=a-1
for d in range(b,0,-1):
e=random.randint(0,d)
if e == d:
return shuffle(initial)
ary[d],ary[e]=ary[e],ary[d]
return ary
ary = [1,2,3,4,5,6]
print shuffle(ary)
Also note that Wikipedia gives a (non-recursive) python implementation of the very similar Sattolo's algorithm.
from random import randrange
def sattoloCycle(items):
i = len(items)
while i > 1:
i = i - 1
j = randrange(i) # 0 <= j <= i-1
items[j], items[i] = items[i], items[j]
return
If I read the article correctly, to re-acquire Fisher-Yates, you'd just do one simple change:
from random import randrange
def FisherYates(items):
i = len(items)
while i > 1:
i = i - 1
j = randrange(i+1) # 0 <= j <= i
items[j], items[i] = items[i], items[j]
return
def function(list):
len(list)-1
for i in range(len(list)-1,0,-1):
e= randint(0,i)
while e > i:
e= randint(0,i)
"do something to the list"
return array
?
def function(list):
for i in (a for a in range(len(list)-1,0,-1) if randint(0,a) > a):
#do something with list
#do something else with remainder.
Not exactly what you asked for. Just wanted to remind you of this possibility.
you can copy the parameter to a temp variable. then call the function with the temp variable and use return;
def function(list):
listCopy = list;
len(list)-1
for i in range(len(list)-1,0,-1):
e= randint(0,i)
if e > i:
return function(listCopy)
else
"do something with the list"
return array
I am currently working on a BASIC simulator in Python, as the title suggests. Here is my code for this problem:
def getBASIC():
l = []
x = 1
while x == 1:
i = input()
l.append(i)
if len(i.split()) != 3:
x = 0
return l
def findLine(prog, target):
for l in range(0, len(prog)):
progX = prog[l].split()
if progX[0] == target:
return l
def execute(prog):
location = 0
visited = [False] * len(prog)
while True:
T = prog[location].split()[2]
location = findLine(prog, T)
visited[location] = True
if visited[len(visited)-1] == False:
return "infinite loop"
else:
return "success"
The first function does what it is intended to do -- convert input of BASIC code into a list. The second function, findLine also does what it is intended to do, in that it finds the item which contains the string equal to the input. The last function, however, I cannot get to work. I know what I have to do, and that is to check whether or not a part of it has been visited twice. I cannot figure out how to do this, due to the existence of the while loop. As a result of this, the second half of that function is just placeholder. If you could help me figure out how to solve this, it would be greatly appreciated. Thanks.
You keep a list of places that have been visited (you already do this) and then when you encounter a goto, you check if it does to a line that already have been visited, and if it has been visited, you exit.
One mistake right now is that you make a list that is as long as the program is. That's pretty pointless. Just keep a list of the visited line numbers instead, and check with
if current_line in visited:
Try adding an if statement declaring a line in the visited list to be true when it is encountered in the loop. This is my solution:
def execute(prog):
location = 0
visited=[False]*len(prog)
while True:
if location==len(prog)-1:
return "success"
if visited[location]==True:
return "infinite loop"
if visited[location]==False:
visited[location]=True
line2strings=prog[location].split()
T=line2strings[-1]
location=findLine(prog, T)