Here is my Sudoku Solver written in python language, When I run this program there seems to be a problem with in Update function and Solve function.
No matter how much time I look over and move the codes around, I seem to have no luck
Can anyone Help me?
import copy
def display (A):
if A:
for i in range (9):
for j in range (9):
if type (A[i][j]) == type ([]): print A[i][j][0],
else: print A[i][j]
print
print
else: print A
def has_conflict(A):
for i in range(9):
for j in range(9):
for (x,y) in get_neighbors(i,j):
if len(A[i][j])==1 and A[i][j]==A[x][y]: return True
return False
def get_neighbors(x,y):
neighbors = []
for i in range(3):
for j in range(3):
a = 3*(x / 3)+i
b = 3*(y / 3)+j
if (x,y) != (a,b):
neighbors += [(a,b)]
for i in range(9):
if (x,y) != (x,i) and (x,i) not in neighbors:
neighbors += [(x,i)]
if (x,y) != (i,y) and (i,y) not in neighbors:
neighbors += [(i,y)]
return neighbors
def update(A,x,y,value):
B = copy.deepcopy(A)
B[x][y] = [value]
for (i,j) in get_neighbors(x,y):
if B[i][j] == B[x][y]:
if len(B[i][j]) > 1: B[i][j].remove(value)
else: return []
if has_conflict(B) == True: return []
else: return B
def solve(A):
for x in range (9):
for y in range(9):
if len(A[x][y]) == 1: return A[x][y]
if len(A[x][y]) > 1:
lst = update(A,x,y,A[x][y])
if len(lst[x][y]) > 1: solve(lst)
if lst == []: return []
if len(lst[x][y]) == 1: return lst
else: return A[x][y]
A=[]
infile = open('puzzle1.txt','r')
for i in range(9):
A += [[]]
for j in range(9):
num = int(infile.read(2))
if num: A[i] += [[num]]
else: A[i] += [[1,2,3,4,5,6,7,8,9]]
for i in range(9):
for j in range(9):
if len(A[i][j])==1: A = update(A, i, j, A[i][j][0])
if A == []: break
if A==[]: break
if A<>[]: A = solve(A)
display(A)
Here are some puzzles:
Puzzle 1
0 0 0 2 6 0 7 0 1
6 8 0 0 7 0 0 9 0
1 9 0 0 0 4 5 0 0
8 2 0 1 0 0 0 4 0
0 0 4 6 0 2 9 0 0
0 5 0 0 0 3 0 2 8
0 0 9 3 0 0 0 7 4
0 4 0 0 5 0 0 3 6
7 0 3 0 1 8 0 0 0
Puzzle 2
1 0 0 4 8 9 0 0 6
7 3 0 0 0 0 0 4 0
0 0 0 0 0 1 2 9 5
0 0 7 1 2 0 6 0 0
5 0 0 7 0 3 0 0 8
0 0 6 0 9 5 7 0 0
9 1 4 6 0 0 0 0 0
0 2 0 0 0 0 0 3 7
8 0 0 5 1 2 0 0 4
Puzzle 3
0 2 0 6 0 8 0 0 0
5 8 0 0 0 9 7 0 0
0 0 0 0 4 0 0 0 0
3 7 0 0 0 0 5 0 0
6 0 0 0 0 0 0 0 4
0 0 8 0 0 0 0 1 3
0 0 0 0 2 0 0 0 0
0 0 9 8 0 0 0 3 6
0 0 0 3 0 6 0 9 0
I would avoid things like "move the codes around". This is called "Programming by Coincidence" (see The Pragmatic Programmer). Programming like this won't make you a better programmer.
Instead, you should take out a paper and pencil, and start thinking how things should work. Then, read the code and carefully write what it actually does. Only when you understand, go back to the computer terminal.
If you want to stabilize your code, then write small test cases for each function which make sure that they work correctly.
In your case, run a puzzle, and determine which field is wrong. Then guess which function might produce the wrong output. Call it with the input to see what it really does. Repeat for every bug you find.
[EDIT] The module unittest is your friend.
I'd like to help you in a way that you can write the actual code, so here is some explanation, and some pseudo-code.
Those sudoku solvers that don't mimic human deduction logic are bruteforce-based. Basically, you'll need a backtrack algorithm. You have your has_conflict method, which checks whether the candidate is ok at first look. Then you write the backtrack algorithm like this:
Solve(s):
Pick a candidate.
Does it have a conflict? If yes, go back, and pick another one.
No more empty cells? Then cool, return True.
Have you run out of candidates? Then it cant be solved, return False.
At this point, it seems ok. So call Solve(s) again, lets see how it works
out with the new candidate.
If Solve returned false, then after all it was a bad candidate. Go
back to picking another one.
If Solve returned True, then you solved the sudoku!
The main idea here is that if your guess was wrong, despite not having a conflict at first look, then a confliction will reveal itself somewhere deeper in the call tree.
The original sudokus have only one solution. You can extend this method to different solutions for sudokus that have them by trying any candidates despite the return value of Solve (but that will be very slow with this approach).
There's a nice trick to find out if a sudoku has more than one solutions. First try the candidates in natural order in every call of solve. Then try them backwards. Then do these two steps again, but this time run the algorithm from the last cell of the sudoku, stepping backwards. If these four solutions are identical, then it has only one solution. Unfortunately I don't have a formal proof, but it seemed to work all the time. I tried to prove it, but I'm not that great with graphs.
Solving sudoku need some bruteforcing method, I dont see those in your codes.
I also tried to do before, but finally I saw norvig's codes, its just working perfect.
and ended up with learning his codes finally.
Related
for k in range(8):
for i in range(2): #number of columns
for j in range(4): #number of row
print(k,j,i)
I want an output like this. no repetition of first for loop
k,j,i
-----
0 0 0
1 1 0
2 2 0
3 3 0
4 0 1
5 1 1
6 2 1
7 3 1
How I will achieve this?
Normally i would do
for i in range(8):
print(i, i%4, i%2)
Output:
0 0 0
1 1 1
2 2 0
3 3 1
4 0 0
5 1 1
6 2 0
7 3 1
But to reproduce your exact output:
for i in range(8):
print(i, i%4, int(i>3))
Output:
0 0 0
1 1 0
2 2 0
3 3 0
4 0 0
5 1 1
6 2 1
7 3 1
You can use if statements to say things like if k == 7 or something along those lines. This will only allow it to loop the first loop before moving on to the second loop.
Other answers have shown similar ways to produce your exact output, but this is another way to do it, and this would still work if you wanted the number of rows to be more than 8 and you wanted i to keep increasing
for i in range(8):
print(i, i%4, i//4)
I hope this is useful, sorry if it isn't
Looking at i and j, you have the cartesian product of {0,1} and {0,1,2,3}. You can compute that with itertools.product(range(2), range(4)), then use enumerate to number them for your k value.
from itertools import product
for k, (i, j) in enumerate(product(range(2), range(4))):
print(k, j, i)
Earlier arguments to product vary more slowly than later arguments.
Problem
The program takes input that has information on mobiles (the kind that consists of wires and strings supsending weights). The program should check if the mobile is in equilibrium, that is the weight of the mobile is equal on both sides. Done by this equation weightLeft * distanceLeft = weightRight * distanceRight. However one mobiles weight on one side can be the result of another subMobile hanging below. So in the example that will be shown there is a whole "tree" of mobiles connected to one antoher.
More specific explanation here: https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=780
Example input
First line consists of how many testcases are to follow. Each line contaning numbers is a description of a mobile according to this templete (weightLeft, distanceLeft, weightRight, distanceLeft). If there is a zero on the weight value then the weight is the total weight of a submobile below. If a mobile has two zeros then both the weights come from different mobiles on the following lines, first the left then the right always.
5
0 2 0 4
0 3 0 1
1 2 1 1
2 4 4 2
1 6 3 2
0 2 0 4
0 3 0 1
2 1 1 1
2 4 4 2
1 6 3 2
0 2 0 4
0 3 0 1
1 1 1 1
2 4 4 2
1 6 3 2
0 2 0 4
0 3 0 1
1 1 1 1
2 4 4 2
1 6 3 2
0 2 0 4
0 3 0 1
1 1 1 1
2 4 4 2
1 6 3 2
My Code
My code is below and it does work acording to the input i typed my self according to the description (i think). No error, nothing wrong. But when i submit it to the online judge, it fails. I get a runtime error and a have no idea why. Anyone who could help my out would be much appreciated.
testcases = int(input())
input()
equal = True
def begin():
global equal
input_data = input().split()
left_side = int(input_data[0])
right_side = int(input_data[2])
if input_data[0] == '0':
left_side = begin()
if input_data[2] == '0':
right_side = begin()
if (left_side * int(input_data[1])) != (right_side * int(input_data[3])):
equal = False
return left_side + right_side
for x in range(testcases):
equal = True
begin()
if equal:
print("YES")
else:
print("NO")
print("")
input()
The Answer
After trying and playing around with the input i noticed that the program was reading input and printing at the end of the testcase no matter what. This caused problems at the end of the input because the very last row of the porgram reads input when there is no more input. So after making these changes to the code, i got the program accepted by the UVA Judge
for x in range(testcases):
equal = True
begin()
if equal:
print("YES")
else:
print("NO")
if not x == (testcases -1):
print()
input()
I'm very new to learning python, though I understand the basics of the looping, I am unable to understand the method in which output is arrived at.
In particular, how does the mapping of all three for loops happen to give the desired output, as I finding it impossible to understand the logic to be applied, when I try to write the output on paper without referring to IDE.
Code:
n = 4
a = 3
z = 2
for i in range(n):
for j in range(a):
for p in range(z):
print(i, j, p)
Output is:
0 0 0
0 0 1
0 1 0
0 1 1
0 2 0
0 2 1
1 0 0
1 0 1
1 1 0
1 1 1
1 2 0
1 2 1
2 0 0
2 0 1
2 1 0
2 1 1
2 2 0
2 2 1
3 0 0
3 0 1
3 1 0
3 1 1
3 2 0
3 2 1
The first loop iterates four times.
The second loop iterates three times. However since it is embedded inside the first loop, it actually iterates twelve times (4 * 3.)
The third loop iterates two times. However since it is embedded inside the first and second loops, it actually iterates twenty-four times (4 * 3 * 2).
I am very new to python and coding. I have this homework that I have to do:
You will receive on the first line the rows of the matrix (n) and on the next n lines you will get each row of the matrix as a string (zeros and ones separated by a single space). You have to calculate how many blocks you have (connected ones horizontally or diagonally) Here are examples:
Input:
5
1 1 0 0 0
1 1 0 0 0
0 0 0 0 0
0 0 0 1 1
0 0 0 1 1
Output:
2
Input:
6
1 1 0 1 0 1
0 1 1 1 1 1
0 1 0 0 0 0
0 1 1 0 0 0
0 1 1 1 1 0
0 0 0 1 1 0
Output:
1
Input:
4
0 1 0 1 1 0
1 0 1 1 0 1
1 0 0 0 0 0
0 0 0 1 0 0
Output:
5
the code I came up with for now is :
n = int(input())
blocks = 0
matrix = [[int(i) for i in input().split()] for j in range(n)]
#loop or something to find the blocks in the matrix
print(blocks)
Any help will be greatly appreciated.
def valid(y,x):
if y>=0 and x>=0 and y<N and x<horizontal_len:
return True
def find_blocks(y,x):
Q.append(y)
Q.append(x)
#search around 4 directions (up, right, left, down)
dy = [0,1,0,-1]
dx = [1,0,-1,0]
# if nothing is in Q then terminate counting block
while Q:
y = Q.pop(0)
x = Q.pop(0)
for dir in range(len(dy)):
next_y = y + dy[dir]
next_x = x + dx[dir]
#if around component is valid range(inside the matrix) and it is 1(not 0) then include it as a part of block
if valid(next_y,next_x) and matrix[next_y][next_x] == 1:
Q.append(next_y)
Q.append(next_x)
matrix[next_y][next_x] = -1
N = int(input())
matrix = []
for rows in range(N):
row = list(map(int, input().split()))
matrix.append(row)
#row length
horizontal_len = len(matrix[0])
blocks = 0
#search from matrix[0][0] to matrix[N][horizontal_len]
for start_y in range(N):
for start_x in range(horizontal_len):
#if a number is 1 then start calculating
if matrix[start_y][start_x] == 1:
#make 1s to -1 for not to calculate again
matrix[start_y][start_x] = -1
Q=[]
#start function
find_blocks(start_y, start_x)
blocks +=1
print(blocks)
I used BFS algorithm to solve this question. The quotations are may not enough to understand the logic.
If you have questions about this solution, let me know!
I want to know how can I make the source code of the following problem based on Python.
I have a dataframe that contain this column:
Column X
1
0
0
0
1
1
0
0
1
I want to create a list b counting the sum of successive 0 value for getting something like that :
List X
1
3
3
3
1
1
2
2
1
If I understand your question correctly, you want to replace all the zeros with the number of consecutive zeros in the current streak, but leave non-zero numbers untouched. So
1 0 0 0 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0
becomes
1 4 4 4 4 1 1 1 1 2 2 1 1 1 5 5 5 5 5
To do that, this should work, assuming your input column (a pandas Series) is called x.
result = []
i = 0
while i < len(x):
if x[i] != 0:
result.append(x[i])
i += 1
else:
# See how many times zero occurs in a row
j = i
n_zeros = 0
while j < len(x) and x[j] == 0:
n_zeros += 1
j += 1
result.extend([n_zeros] * n_zeros)
i += n_zeros
result
Adding screenshot below to make usage clearer