I'm making a Sudoku that runs in terminal with python, and I can't assign numbers to fill up the board with numbers. Here is my code with all functions and main program. I think the error is in the checker for the number.
def createBoard ():
rows = 9
columns = 9
matrix = []
for r in range(rows):
matrix.append([]) # agregar lista
for c in range(columns):
matrix[r].append("")
return matrix
def printBoard (board):
for i in range (len(board)):
print (board[i])
def defineSubMatrix (row, column):
subMatrix = -1
if row >= 0 and row <= 2:
if column >= 0 and column <= 2:
subMatrix = 0
if column >= 3 and column <= 5:
subMatrix = 1
if column >= 6 and column <= 8:
subMatrix = 2
if row >= 3 and row <= 5:
if column >= 0 and column <= 2:
subMatrix = 3
if column >= 3 and column <= 5:
subMatrix = 4
if column >= 6 and column <= 8:
subMatrix = 5
if row >= 3 and row <= 5:
if column >= 0 and column <= 2:
subMatrix = 6
if column >= 3 and column <= 5:
subMatrix = 7
if column >= 6 and column <= 8:
subMatrix = 8
return subMatrix
def createLevel (board):
for i in range (0, 8):
for j in range (0, 8):
num = random.randint (1, 9)
check = checker(board, num, i, j)
while check == False:
if check == False:
num = random.randint (1, 9)
check = checker(board, num, i, j)
board[i][j] = num
board[i][j] = num
return board
def checker (board, num, posX, posY):
### ok = True cuando check == 0
ok = False
checkT = 0
checkR = 0
checkC = 0
checkSM = 0
###Check row right
i = posX
while i + 1 <= 8:
if board[i][posY] == num:
checkR += 1
i = i + 1
###Check row left
i = posX
while i - 1 >= 0:
if board[i][posY] == num:
checkR += 1
i = i - 1
###Check column down
j = posY
while j + 1 <= 8:
if board[posX][j] == num:
checkC += 1
j = j + 1
###Check column up
j = posY
while j - 1 >= 0:
if board[posX][j] == num:
checkC += 1
j = j - 1
###Check Submatrix
subMatrix = defineSubMatrix(posX, posY)
if subMatrix == 0:
for i in range (0, 2):
for j in range (0, 2):
if board[i][j] == num:
checkSM += 1
if subMatrix == 1:
for i in range (3, 5):
for j in range (0, 2):
if board[i][j] == num:
checkSM += 1
if subMatrix == 2:
for i in range (6, 8):
for j in range (0, 2):
if board[i][j] == num:
checkSM += 1
if subMatrix == 3:
for i in range (0, 2):
for j in range (3, 5):
if board[i][j] == num:
checkSM += 1
if subMatrix == 4:
for i in range (3, 5):
for j in range (3, 5):
if board[i][j] == num:
checkSM += 1
if subMatrix == 5:
for i in range (6, 8):
for j in range (3, 5):
if board[i][j] == num:
checkSM += 1
if subMatrix == 6:
for i in range (0, 2):
for j in range (6, 8):
if board[i][j] == num:
checkSM += 1
if subMatrix == 7:
for i in range (3, 5):
for j in range (6, 8):
if board[i][j] == num:
checkSM += 1
if subMatrix == 8:
for i in range (6, 8):
for j in range (6, 8):
if board[i][j] == num:
checkSM += 1
checkT = checkR + checkSM + checkC
if checkT == 0:
ok = True
return ok
def main ():
board = createBoard()
subma = defineSubMatrix(0, 6)
print (subma)
printBoard(board)
print ("Board Created")
level = createLevel(board)
print ("Level created")
printBoard(level)
###PROGRAMA
main()
You can't create a Sudoku this way, by just making random selections. You quickly get into a situation like this:
1 2 3 4 5 6 7 8 9
4 5 6 1 2 3 . . .
and now there are no possibilities for the next cells.
Many Sudoku algorithms create the grids the same way humans solve them, using complicated heuristics. It is possible to use brute force. Consider that every Sudoku puzzle can be derived from every other Sudoku puzzle, by using a combination of (a) swapping rows, (b) swapping columns, (c) swapping sets of 3 rows, (d) swapping sets of 3 columns, (e) rotating 90 degrees, and (f) mirroring across one of the axes. Given that, you can start with a well ordered matrix like this:
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
2 3 4 5 6 7 8 9 1
5 6 7 8 9 2 3 4 5
8 9 1 2 3 4 5 6 7
3 4 5 6 7 8 9 1 2
6 7 8 9 1 2 3 4 5
9 1 2 3 4 5 6 7 8
and then doing random swaps, rotates, and mirrors, just like shuffling a deck of cards. See this article:
https://www.algosome.com/articles/create-a-solved-sudoku.html
Related
I'm trying to write two for loops that will return a score for different inputs, and create a new field with the new score. The first loop works fine but the second loop never returns the correct score.
import pandas as pd
d = {'a':['foo','bar'], 'b':[1,3]}
df = pd.DataFrame(d)
score1 = df.loc[df['a'] == 'foo']
score2 = df.loc[df['a'] == 'bar']
for i in score1['b']:
if i < 3:
score1['c'] = 0
elif i <= 3 and i < 4:
score1['c'] = 1
elif i >= 4 and i < 5:
score1['c'] = 2
elif i >= 5 and i < 8:
score1['c'] = 3
elif i == 8:
score1['c'] = 4
for j in score2['b']:
if j < 2:
score2['c'] = 0
elif j <= 2 and i < 4:
score2['c'] = 1
elif j >= 4 and i < 6:
score2['c'] = 2
elif j >= 6 and i < 8:
score2['c'] = 3
elif j == 8:
score2['c'] = 4
print(score1)
print(score2)
When I run script it returns the following:
print(score1)
a b c
0 foo 1 0
print(score2)
a b
1 bar 3
Why doesn't score2 create the new field "c" or a score?
Avoid the use of for loops to conditionally update DataFrame columns which are not Python lists. Use vectorized methods of Pandas and Numpy such as numpy.select which scales to millions of rows! Remember these data science tools calculate much differently than general use Python:
# LIST OF BOOLEAN CONDITIONS
conds = [
score1['b'].lt(3), # EQUIVALENT TO < 3
score1['b'].between(3, 4, inclusive="left"), # EQUIVALENT TO >= 3 or < 4
score1['b'].between(4, 5, inclusive="left"), # EQUIVALENT TO >= 4 or < 5
score1['b'].between(5, 8, inclusive="left"), # EQUIVALENT TO >= 5 or < 8
score1['b'].eq(8) # EQUIVALENT TO == 8
]
# LIST OF VALUES
vals = [0, 1, 2, 3, 4]
# VECTORIZED ASSIGNMENT
score1['c'] = numpy.select(conds, vals, default=numpy.nan)
# LIST OF BOOLEAN CONDITIONS
conds = [
score2['b'].lt(2),
score2['b'].between(2, 4, inclusive="left"),
score2['b'].between(4, 6, inclusive="left"),
score2['b'].between(6, 8, inclusive="left"),
score2['b'].eq(8)
]
# LIST OF VALUES
vals = [0, 1, 2, 3, 4]
# VECTORIZED ASSIGNMENT
score2['c'] = numpy.select(conds, vals, default=numpy.nan)
On the first iteration of second for loop, j will be in 3. so that none your condition satisfies.
for j in score2['b']:
if j < 3:
score2['c'] = 0
elif j <= 3 and i < 5:
score2['c'] = 1
elif j >= 5 and i < 7:
score2['c'] = 2
elif j >= 7 and i < 9:
score2['c'] = 3
elif j == 9:
score2['c'] = 4
I have got an a number: like 5
i need to split it into 3 sets like
2
1 4
2
2 3
1
5
Or the number 8:
2
8 4
2
7 5
4
1 2 3 6
I try to
def partition(n):
if n < 5:
return
s = n * (n + 1) // 2
if s % 3 != 0:
return
s //= 3
lst, result = [i for i in range(1, n + 1)], []
for _ in range(2):
subset, s_current = [], s
while s_current > 0:
idx_max = bisect_right(lst, s_current) - 1
subset.append(lst[idx_max])
s_current -= lst[idx_max]
lst.pop(idx_max)
result.append(subset)
result.append(lst)
return result
If it can't make 3 sets, should return -1
But it doesn't work what i want
please, help
This is my code for getting a 3 digit combination.
a = input("Enter first number: ")
b = input("Enter second number: ")
c = input("Enter third number: ")
d = []
d.append(a)
d.append(b)
d.append(c)
for i in range(0, 4):
for j in range(0, 4):
for k in range(0, 4):
if(i !=j & j!=k & k!=i):
for count, i in enumerate(range(4),1):
print(i,j,k)
Input:
1,2,3
and
Output:
0 1 2
1 1 2
2 1 2
3 1 2
0 2 0
1 2 0
2 2 0
3 2 0 & more....
My question is how can I get the count of how many combinations I have got?
Thank you so much for your attention and participation.
Outside of your loop, create an integer variable and set it equal to 0. Where you print out the combinations (within the loop), add 1 to this integer variable. Finally at the end of your program outside the loop, print the value of the counter variable.
For example:
counter = 0
for i in range(0, 4):
for j in range(0, 4):
for k in range(0, 4):
if (i != j & j != k & k != i):
for count, i in enumerate(range(4), 1):
print(i, j, k)
counter += 1
print(counter)
My code :
R = int(input("Enter the Size of Square Matrix : "))
matrix = []
print("\nEnter the entries row-wise : ")
for i in range(R):
a = []
for j in range(R):
a.append(int(input()))
matrix.append(a)
print("\nMatrix : \n")
for i in range(R):
for j in range(R):
print(matrix[i][j], end=" ")
print()
print("\n")
print("\nBoundary Matrix\n")
for i in range(R):
for j in range(R):
if (i == 0):
print(matrix[i][j])
elif (i == R - 1):
print(matrix[i][j])
elif (j == 0):
print(matrix[i][j])
elif (j == R - 1):
print(matrix[i][j])
else:
print(" "),
print()
output :
Boundary
Matrix
1
2
3
4
6
7
8
9
I'm not able to print the boundary elements in form of a matrix. the output is in form of a straight line.
Please help me to do so.
Note: I have tried changing the position of print() but that didn't help much.
print("\nBoundary Matrix\n")
for i in range(R):
print(
"{}{}{}".format(
"\t".join(map(str, matrix[i])) if i in (0, R - 1) else matrix[i][0],
"" if i in (0, R - 1) else (" \t" * (R - 1)),
"" if i in (0, R - 1) else matrix[i][R - 1],
)
)
Matrix :
1 2 3 4
5 6 7 8
9 10 11 12
13 1 4 15
Boundary Matrix
1 2 3 4
5 8
9 12
13 1 4 15
I'm wondering how to modify the Damerau-Levenshtein algorithm to track the specific character transformations required to change a source string to a target string. This question has been answered for the Levenshtein distance, but I couldn't find any answers for DL distance.
I looked at the py-Levenshtein module: it provides exactly what I need, but for Levenshtein distance:
Levenshtein.editops("FBBDE", "BCDASD")
[('delete', 0, 0), ('replace', 2, 1), ('insert', 4, 3), ('insert', 4,
4), ('replace', 4, 5)]
The code for editops was difficult to decipher since it's written in C. I wonder how tracking transformations the can be done efficiently: I imagine it is possible from the distance matrix, which looks something like:
r e p u b l i c a n
0 1 2 3 4 5 6 7 8 9 10
d 1 1 2 3 4 5 6 7 8 9 10
e 2 2 1 2 3 4 5 6 7 8 9
m 3 3 2 2 3 4 5 6 7 8 9
o 4 4 3 3 3 4 5 6 7 8 9
c 5 5 4 4 4 4 5 6 6 7 8
r 6 5 5 5 5 5 5 6 7 7 8
a 7 6 6 6 6 6 6 6 7 7 8
t 8 7 7 7 7 7 7 7 7 8 8
import numpy as np
def levenshtein_distance(string1, string2):
n1 = len(string1)
n2 = len(string2)
return _levenshtein_distance_matrix(string1, string2)[n1, n2]
def damerau_levenshtein_distance(string1, string2):
n1 = len(string1)
n2 = len(string2)
return _levenshtein_distance_matrix(string1, string2, True)[n1, n2]
def get_ops(string1, string2, is_damerau=False):
i, j = _levenshtein_distance_matrix(string1, string2, is_damerau).shape
i -= 1
j -= 1
ops = list()
while i != -1 and j != -1:
if is_damerau:
if i > 1 and j > 1 and string1[i-1] == string2[j-2] and string1[i-2] == string2[j-1]:
if dist_matrix[i-2, j-2] < dist_matrix[i, j]:
ops.insert(0, ('transpose', i - 1, i - 2))
i -= 2
j -= 2
continue
index = np.argmin([dist_matrix[i-1, j-1], dist_matrix[i, j-1], dist_matrix[i-1, j]])
if index == 0:
if dist_matrix[i, j] > dist_matrix[i-1, j-1]:
ops.insert(0, ('replace', i - 1, j - 1))
i -= 1
j -= 1
elif index == 1:
ops.insert(0, ('insert', i - 1, j - 1))
j -= 1
elif index == 2:
ops.insert(0, ('delete', i - 1, i - 1))
i -= 1
return ops
def execute_ops(ops, string1, string2):
strings = [string1]
string = list(string1)
shift = 0
for op in ops:
i, j = op[1], op[2]
if op[0] == 'delete':
del string[i + shift]
shift -= 1
elif op[0] == 'insert':
string.insert(i + shift + 1, string2[j])
shift += 1
elif op[0] == 'replace':
string[i + shift] = string2[j]
elif op[0] == 'transpose':
string[i + shift], string[j + shift] = string[j + shift], string[i + shift]
strings.append(''.join(string))
return strings
def _levenshtein_distance_matrix(string1, string2, is_damerau=False):
n1 = len(string1)
n2 = len(string2)
d = np.zeros((n1 + 1, n2 + 1), dtype=int)
for i in range(n1 + 1):
d[i, 0] = i
for j in range(n2 + 1):
d[0, j] = j
for i in range(n1):
for j in range(n2):
if string1[i] == string2[j]:
cost = 0
else:
cost = 1
d[i+1, j+1] = min(d[i, j+1] + 1, # insert
d[i+1, j] + 1, # delete
d[i, j] + cost) # replace
if is_damerau:
if i > 0 and j > 0 and string1[i] == string2[j-1] and string1[i-1] == string2[j]:
d[i+1, j+1] = min(d[i+1, j+1], d[i-1, j-1] + cost) # transpose
return d
if __name__ == "__main__":
# GIFTS PROFIT
# FBBDE BCDASD
# SPARTAN PART
# PLASMA ALTRUISM
# REPUBLICAN DEMOCRAT
# PLASMA PLASMA
# FISH IFSH
# STAES STATES
string1 = 'FISH'
string2 = 'IFSH'
for is_damerau in [True, False]:
if is_damerau:
print('=== damerau_levenshtein_distance ===')
else:
print('=== levenshtein_distance ===')
dist_matrix = _levenshtein_distance_matrix(string1, string2, is_damerau=is_damerau)
print(dist_matrix)
ops = get_ops(string1, string2, is_damerau=is_damerau)
print(ops)
res = execute_ops(ops, string1, string2)
print(res)
Output:
=== damerau_levenshtein_distance ===
[[0 1 2 3 4]
[1 1 1 2 3]
[2 1 1 2 3]
[3 2 2 1 2]
[4 3 3 2 1]]
[('transpose', 1, 0)]
['FISH', 'IFSH']
=== levenshtein_distance ===
[[0 1 2 3 4]
[1 1 1 2 3]
[2 1 2 2 3]
[3 2 2 2 3]
[4 3 3 3 2]]
[('replace', 0, 0), ('replace', 1, 1)]
['FISH', 'IISH', 'IFSH']