I continue my Sudoku but i need your help. I'm blocked here :
def grid_index(grid, value):
for i, row in enumerate(grid):
for j, cell in enumerate(row):
if cell == value:
return i, j
return -1, -1
def can_fill_cell(sudoku, coords):
row = sudoku[0]
for cell in row:
if cell == value_to_input:
return False
column = [row[0] for row in sudoku]
for cell in column:
if cell == value_to_input:
return False
square = [sudoku[x][y] for x in range(3) for y in range(3)]
for cell in square:
if cell == value_to_input:
return False
return True
def solve_next_unsolved(sudoku):
"""
for x in range(9):
for y in range(9):
coords = x,y
"""
coords = (2,2)
if can_fill_cell(sudoku, coords):
sudoku[coords[0]][coords[1]] = value_to_input
print(sudoku)
So, in grid_index, i get all cell coordinates.
In my can_fill_cell function i said : "If a value is equal to the value to input, break the for and get out the function to return False and not input the value"
The problem i have right now, it's i don't know how to verify all row, column and region...
Do you have any idea please ?
Thx,
Ravaniss
EDIT : Just for information, i get my sudoku like this :
value_to_input = "1"
def import_sudoku():
with open("sudoku.txt") as f:
lines = f.read()
sudoku = [[character for character in line if not character == " "] for line in lines.split("\n")]
return sudoku
sudoku = import_sudoku()
print(sudoku)
Si, right now i can verify :
.2.
.2.
...
that's not print the result, so it's false but i can do this :
...
1..
...
.2.
22.
...
for example. what i need to verify. How can i verify all of this and make my sudoku work ?
Thx for your help !
So it sounds like your sudoku is a list of lists, e.g.
[ [1, 2, 3, 4, 5, 6, 7, 8, 9],
[4, 5, 6, 7, 8, 9, 1, 2, 3],
[7, 8, 9, 1, 2, 3, 4, 5, 6],
... ]
You'll need to verify rows and columns separately, but those are the easy ones.
for row in sudoku:
verify(row)
for col in zip(*sudoku):
verify(col)
# zip(*iterable) is a very useful idiom for flipping rows to columns
The harder one is the 3x3s. Since this is a known quantity (9x9 sudoku), it's probably easier to just enumerate it rather than calculate it yourself.
grids = [ [s[0][0], s[0][1], s[0][2],
s[1][0], s[1][1], s[1][2],
s[2][0], s[2][1], s[2][2]],
... ]
Though this is certainly time consuming, it's also straightforward which counts for a lot. You could use itertools.product to simplify this instead:
grids = [ [s[y][x] for x, y in itertools.product(range(i, i+3), repeat=2)]
for i in range(1, 8, 3) ]
Either way you have a new set of numbers to check.
for grid in grids:
verify(grid)
verify in this case is probably easiest to implement just by checking for duplicates
def verify(group):
return len(group) == len(set(group))
Though you could verify it against the literal if you like
def verify(group):
return sorted(group) == [1,2,3,4,5,6,7,8,9]
Related
I know how to find the 1st highest value but don't know the rest. Keep in mind i need to print the position of the 1st 2nd and 3rd highest value.Thank You and try to keep it simple as i have only been coding for 2 months. Also they can be joint ranks
def linearSearch(Fscore_list):
pos_list = []
target = (max(Fscore_list))
for i in range(len(Fscore_list)):
if Fscore_list[i] >= target:
pos_list.append(i)
return pos_list
This will create a list of the 3 largest items, and a list of the corresponding indices:
lst = [9,7,43,2,4,7,8,5,4]
values = []
values = zip(*sorted( [(x,i) for (i,x) in enumerate(f_test)],
reverse=True )[:3] )[0]
posns = []
posns = zip(*sorted( [(x,i) for (i,x) in enumerate(f_test)],
reverse=True )[:3] )[1]
Things are a bit more complicated if the same value can appear multiple times (this will show the highest position for a value):
lst = [9,7,43,2,4,7,8,5,4]
ranks = sorted( [(x,i) for (i,x) in enumerate(lst)], reverse=True
)
values = []
for x,i in ranks:
if x not in values:
values.append( x )
posns.append( i )
if len(values) == 3:
break
print zip( values, posns )
Use heapq.nlargest:
>>> import heapq
>>> [i
... for x, i
... in heapq.nlargest(
... 3,
... ((x, i) for i, x in enumerate((0,5,8,7,2,4,3,9,1))))]
[7, 2, 3]
Add all the values in the list to a set. This will ensure you have each value only once.
Sort the set.
Find the index of the top three values in the set in the original list.
Make sense?
Edit
thelist = [1, 45, 88, 1, 45, 88, 5, 2, 103, 103, 7, 8]
theset = frozenset(thelist)
theset = sorted(theset, reverse=True)
print('1st = ' + str(theset[0]) + ' at ' + str(thelist.index(theset[0])))
print('2nd = ' + str(theset[1]) + ' at ' + str(thelist.index(theset[1])))
print('3rd = ' + str(theset[2]) + ' at ' + str(thelist.index(theset[2])))
Edit
You still haven't told us how to handle 'joint winners' but looking at your responses to other answers I am guessing this might possibly be what you are trying to do, maybe? If this is not the output you want please give us an example of the output you are hoping to get.
thelist = [1, 45, 88, 1, 45, 88, 5, 2, 103, 103, 7, 8]
theset = frozenset(thelist)
theset = sorted(theset, reverse=True)
thedict = {}
for j in range(3):
positions = [i for i, x in enumerate(thelist) if x == theset[j]]
thedict[theset[j]] = positions
print('1st = ' + str(theset[0]) + ' at ' + str(thedict.get(theset[0])))
print('2nd = ' + str(theset[1]) + ' at ' + str(thedict.get(theset[1])))
print('3rd = ' + str(theset[2]) + ' at ' + str(thedict.get(theset[2])))
Output
1st = 103 at [8, 9]
2nd = 88 at [2, 5]
3rd = 45 at [1, 4]
BTW : What if all the values are the same (equal first) or for some other reason there is no third place? (or second place?). Do you need to protect against that? If you do then I'm sure you can work out appropriate safety shields to add to the code.
Jupyter image of the code working
This question was on my Udemy machine learning course way too soon. Scott Hunter helped me the most on this problem, but didn't get me to a pass on the site. Having to really think about the issue deeper on my own. Here is my solution, since couldn't find it anywhere else online--in terms that I understood everything that was going on*:
lst = [9,7,43,2,4,7,8,9,4]
ranks = sorted( [(x,i) for (i,x) in enumerate(lst)], reverse=True )
box = []
for x,i in ranks:
if i&x not in box:
box.append( x )
if len(box) == 3:
break
print(box)
So we have a list of numbers. To rank the numbers we sort the value with its position for every position that has a value when we enumerate/iterate the list. Then we put the highest values on top by reversing it. Now we need a box to put our information in to pull out of later, so we build that box []. Now for every value with a position put that in the box, if the value and position isn't already in the box--meaning if the value is already in the box, but the position isn't, still put in the box. And we only want three answers. Finally tell me what is in the variable called box.
*Many of these answers, on this post, will most likely work.
Input : [4, 5, 1, 2, 9]
N = 2
Output : [9, 5]
Input : [81, 52, 45, 10, 3, 2, 96]
N = 3
Output : [81, 96, 52]
# Python program to find N largest
# element from given list of integers
l = [1000,298,3579,100,200,-45,900]
n = 4
l.sort()
print(l[-n:])
Output:
[298, 900, 1000, 3579]
lst = [9,7,43,2,4,7,8,9,4]
temp1 = lst
print(temp1)
#First Highest value:
print(max(temp1))
temp1.remove(max(temp1))
#output: 43
# Second Highest value:
print(max(temp1))
temp1.remove(max(temp1))
#output: 9
# Third Highest Value:
print(max(temp1))
#output: 7
There's a complicated O(n) algorithm, but the simplest way is to sort it, which is O(n * log n), then take the top. The trickiest part here is to sort the data while keeping the indices information.
from operator import itemgetter
def find_top_n_indices(data, top=3):
indexed = enumerate(data) # create pairs [(0, v1), (1, v2)...]
sorted_data = sorted(indexed,
key=itemgetter(1), # sort pairs by value
reversed=True) # in reversed order
return [d[0] for d in sorted_data[:top]] # take first N indices
data = [5, 3, 6, 3, 7, 8, 2, 7, 9, 1]
print find_top_n_indices(data) # should be [8, 5, 4]
Similarly, it can be done with heapq.nlargest(), but still you need to pack the initial data into tuples and unpack afterwards.
To have a list filtered and returned in descending order with duplicates removed try using this function.
You can pass in how many descending values you want it to return as keyword argument.
Also a side note, if the keyword argument (ordered_nums_to_return) is greater than the length of the list, it will return the whole list in descending order. if you need it to raise an exception, you can add a check to the function. If no args is passed it will return the highest value, again you can change this behaviour if you need.
list_of_nums = [2, 4, 23, 7, 4, 1]
def find_highest_values(list_to_search, ordered_nums_to_return=None):
if ordered_nums_to_return:
return sorted(set(list_to_search), reverse=True)[0:ordered_nums_to_return]
return [sorted(list_to_search, reverse=True)[0]]
print find_highest_values(list_of_nums, ordered_nums_to_return=4)
If values can appear in your list repeatedly you can try this solution.
def search(Fscore_list, num=3):
l = Fscore_list
res = dict([(v, []) for v in sorted(set(l), reverse=True)[:num]])
for index, val in enumerate(l):
if val in res:
res[val].append(index)
return sorted(res.items(), key=lambda x: x[0], reverse=True)
First it find num=3 highest values and create dict with empty list for indexes for it. Next it goes over the list and for every of the highest values (val in res) save it's indexes. Then just return sorted list of tuples like [(highest_1, [indexes ...]), ..]. e.g.
>>> l = [9, 7, 43, 2, 4, 7, 43, 8, 5, 8, 4]
>>> print(search(l))
[(43, [2, 6]), (9, [0]), (8, [7, 9])]
To print the positions do something like:
>>> Fscore_list = [9, 7, 43, 2, 4, 7, 43, 8, 5, 8, 4, 43, 43, 43]
>>> result = search(Fscore_list)
>>> print("1st. %d on positions %s" % (result[0][0], result[0][1]))
1st. 43 on positions [2, 6, 11, 12, 13]
>>> print("2nd. %d on positions %s" % (result[1][0], result[1][1]))
2nd. 9 on positions [0]
>>> print("3rd. %d on positions %s" % (result[2][0], result[2][1]))
3rd. 8 on positions [7, 9]
In one line:
lst = [9,7,43,2,8,4]
index = [i[1] for i in sorted([(x,i) for (i,x) in enumerate(lst)])[-3:]]
print(index)
[2, 0, 1]
None is always considered smaller than any number.
>>> None<4
True
>>> None>4
False
Find the highest element, and its index.
Replace it by None. Find the new highest element, and its index. This would be the second highest in the original list. Replace it by None. Find the new highest element, which is actually the third one.
Optional: restore the found elements to the list.
This is O(number of highest elements * list size), so it scales poorly if your "three" grows, but right now it's O(3n).
so recently I was attempting to write a backtracking method to solve a sudoku puzzle (2d list), and I came upon some errors I can't seem to figure out debugging.
My code:
def areLegalValues(values: list):
if len(values) in [1,4,9,16,25]:
for value in values:
if value <= len(values):
if value != 0 and values.count(value)>1:
return False
else:
return False
return True
return False
def isLegalRow(board: list, row: list):
compareList = [ ]
for r in range(len(board)):
if r == row:
for c in range(len(board[0])):
#print(board[r][c])
compareList.append(board[r][c])
return areLegalValues(compareList)
def isLegalCol(board: list, col: list):
compareList = [ ]
for r in range(len(board)):
for c in range(len(board[0])):
if c == col:
compareList.append(board[r][c])
#print(compareList)
return areLegalValues(compareList)
def isLegalBlock(board: list, block: list):
compareList = [ ]
N = int((len(board))**(1/2))
blockRowNumber = int(block//N)
blockColNumber = int(block%N)
for row in range(blockRowNumber*N, blockRowNumber*N+N):
#print(row)
for col in range(len(board[0])):
if col in range(blockColNumber*N, blockColNumber*N+N):
#print(board[row][col])
compareList.append(board[row][col])
# print(compareList)
return areLegalValues(compareList)
def isLegalSudoku(board: list):
boardLength = len(board)
for row in range(len(board)):
if isLegalRow(board,row) != True:
return False
for col in range(len(board[0])):
if isLegalCol(board,col) != True:
return False
for block in range(boardLength):
if isLegalBlock(board, block) != True:
return False
return True
def solveSudoku(board, row=0):
if row == len(board):
return board
else:
for col in range(len(board[row])):
if board[row][col] == 0:
for number in range(1, len(board)+1):
board[row][col] == number
if isLegalSudoku(board) == True:
solution = solveSudoku(board, row+1)
if solution != None:
return solution
board[row][col] == 0
return None
Test Code:
def testSolveSudoku():
print('Testing solveSudoku()...', end='')
Board = [
[1, 0, 3, 0],
[4, 3, 0, 1],
[2, 0, 1, 0],
[0, 0, 4, 2]
]
Sol = [
[1, 2, 3, 4],
[4, 3, 2, 1],
[2, 4, 1, 3],
[3, 1, 4, 2]
]
print(solveSudoku(Board))
assert(solveSudoku(Board) == Sol)
print('Passed!')
*As the names might suggest, isLegalValues takes in a list and returns if that list contains legal values, aka, the list cannot have duplicates of non zero numbers, 0's can work. isLegalRow and isLegalCol iterate through the sudoku board and build up a list with values of the certain row/column and plug them into isLegalValues. isLegalBlock finds the blocks in the board, and takes in a block number and plugs it into isLegalValues. (Through extensive testing it seems like these all work)
I currently am running into the problem in which, for some reason, my code finish solving the puzzle but manages to finish running.
example:
[1, 2, 3, 0],
[4, 3, 2, 1],
[2, 4, 1, 0],
[3, 0, 4, 2]
should be changed to
[1, 2, 3, 4],
[4, 3, 2, 1],
[2, 4, 1, 3],
[3, 1, 4, 2]
But I keep returning the code 2 lines above. (the one with 0's)
It seems that part of the code is working, as all the values that were replaced are valid, but it seems the backtracking has issues. I was wondering if someone could point out what is going wrong and how might I go about fixing it?
Thanks
Basically, I was making the error in which I was constantly skipping values in the same column with this code, and also was never attempting to solve the last column.
Solution:
def solveSudoku(board: list):
"""takes in a sudoku board and solves the board through use of backtracking
and returns the dectructively changed board"""
checkZeroes = True
for row in range(len(board)):
for col in range(len(board[0])):
if board[row][col] == 0:
checkZeroes = False
if checkZeroes == True:
return board
else:
for row in range(len(board)):
for col in range(len(board[0])):
if board[row][col] == 0:
for number in range(1,len(board)+1):
board[row][col] = number
if isLegalSudoku(board) == True:
solution = solveSudoku(board)
if solution != None:
return solution
board[row][col] = 0
return None
This accomplishes the task, albeit a bit slow, by first checking if the whole board has 0's (base case), after that, it loops through all values in the board and if the value is a 0, it tests all possible (legal) numbers. Then it checks if the whole board is legal or not, and continues on. If there is an error, it backtracks. If there is no solution, None is returned.
I would like to know if there exists a base solution to do something like this:
for n in range(length=8, start_position= 3, direction= forward)
The problem I'm encountering is I would like the loop to continue past the final index, and pick up again at idx =0, then idx=1, etc. and stop at idx= 3, the start_position.
To give context, I seek all possible complete solutions to the n-queen problem.
Based on your latest edit, you need a "normal" range and the modulo operator:
for i in range(START, START + LEN):
do_something_with(i % LEN)
from itertools import chain
for n in chain(range(3,8), range(3)):
...
The chain() returns an iterator with 3, 4, ..., 7, 0, 1, 2
Another option for solving this is to use modular arithmetic. You could do something like this, for example:
for i in range(8)
idx = (i + 3) % 8
# use idx
This easily can be generalized to work with different lengths and offsets.
def loop_around_range(length, start_position, direction='forward'):
looped_range = [k % length for k in range(start_position, start_position+length)]
if direction == 'forward':
return looped_range
else:
return looped_range[::-1]
You could implement this for an arbitrary iterable by using itertools.cycle.
from itertools import cycle
def circular_iterator(iterable, skip=0, length=None, reverse=False):
"""Produces a full cycle of #iterable#, skipping the first #skip# elements
then tacking them on to the end.
if #iterable# does not implement #__len__#, you must provide #length#
"""
if reverse:
iterable = reversed(iterable)
cyc_iter = cycle(iterable)
for _ in range(skip):
next(cyc_iter, None)
if length:
total_length = length
else:
total_length = len(iterable)
for _ in range(total_length):
yield next(cyc_iter, None)
>>> lst = [x for x in range(1, 9)]
# [1, 2, 3, 4, 5, 6, 7, 8]
>>> list(circular_iterator(lst, skip=3))
[4, 5, 6, 7, 8, 1, 2, 3]
I need a vector that stores the median values of the medians of the main list "v". I have tried something with the following code but I am only able to write some values in the correct way.
v=[1,2,3,4,5,6,7,8,9,10]
final=[]
nfac=0
for j in range (0,4):
nfac=j+1
for k in range (0,nfac):
if k%2==0:
final.append(v[10/2**(nfac)-1])
else:
final.append(v[9-10/2**(nfac)])
The first median in v=[1,2,3,4,5,6,7,8,9,10] is 5
Then I want the medians of the remaining sublists [1,2,3,4] and [6,7,8,9,10]. I.e. 2 and 8 respectively. And so on.
The list "final" must be in the following form:
final=[5,2,8,1,3,6,9,4,7,10]
Please take a note that the task as you defined it is basically equivalent to constructing a binary heap from an array.
Definitely start by defining a helper function for finding the median:
def split_by_median(l):
median_ind = (len(l)-1) // 2
median = l[median_ind]
left = l[:median_ind]
right = l[median_ind+1:] if len(l) > 1 else []
return median, left, right
Following the example you give, you want to process the resulting sublists in a breadth-first manner, so we need a queue to remember the following tasks:
from collections import deque
def construct_heap(v):
lists_to_process = deque([sorted(v)])
nodes = []
while lists_to_process:
head = lists_to_process.popleft()
if len(head) == 0:
continue
median, left, right = split_by_median(head)
nodes.append(median)
lists_to_process.append(left)
lists_to_process.append(right)
return nodes
So calling the function finally:
print(construct_heap([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])) # [5, 2, 8, 1, 3, 6, 9, 4, 7, 10]
print(construct_heap([5, 1, 2])) # [2, 1, 5]
print(construct_heap([1, 0, 0.5, -1])) # [0, -1, 0.5, 1]
print(construct_heap([])) # []
i dont know how to find the index of minimum value in matrix, can you help me? i didnt find anythin on the internet about this
def printMatrix(matrix):
for i in matrix:
for j in i:
print(j, end=' ')
print()
m=[ [1, 1, 2, 5, 6, 1] , [5, 6, 8, 5, 6, 7] , [10, 12, 10, 12, 11, 11] , [8, 10, 5, 6, 8, 9] , [6, 5, 10, 12, 15, 19]]
printMatrix(m)
This turns a 2D array into a 1D array, then finds the index of the minimum.
def maxIndex(matrix):
matrix2 = []
for a in range(len(matrix)):
for b in range(len(matrix[a])):
matrix2.append(matrix[a][b])
val = -(10)^99
index = 10^99
for a in range(len(matrix2)):
if matrix2[a]<val:
val = matrix2[a]
index = a
return index
Before asking questions on this site about Python, you should first learn the basics of Python. I suggest the book "Hello World!" by Carter and Warren Sande.
First, let's make a sample matrix:
import numpy as np
np.random.seed(100)
mat = np.random.rand(3, 3)
print(mat)
Here's our matrix:
[[ 0.54340494 0.27836939 0.42451759]
[ 0.84477613 0.00471886 0.12156912]
[ 0.67074908 0.82585276 0.13670659]]
Then, we can set our initial "minimum" test value and the location of that value in the matrix:
min_val = mat[0][0]
min_idx = (0, 0)
Next, we can iterate through each row in the matrix, using enumerate to keep track of the index of the row we're in, and np.argmin to find the index of the smallest element in each row:
for idx, row in enumerate(mat):
if min(row) < min_val:
min_val = min(row)
min_idx = (idx, np.argmin(row))
print(min_val, min_idx)
And, voilĂ ! The minimum value and index is:
0.00471885619097 (1, 1)
If you just need the first occurence:
>>> minimum = min(map(min, m))
>>> for i, thing in enumerate(m):
try:
j = thing.index(minimum)
print('minimum is at m[{}][{}]'.format(i,j))
except ValueError as e:
pass
minimum is at m[0][0]
If you need the indices of all occurrences:
>>> minimum = min(map(min, m))
>>> for i, thing in enumerate(m):
for j, x in enumerate(thing):
if x == minimum:
print('minimum is at m[{}][{}]'.format(i,j))
minimum is at m[0][0]
minimum is at m[0][1]
minimum is at m[0][5]
>>>