0% found this document useful (0 votes)
121 views20 pages

Solved Problem

The document discusses Sudoku puzzles and provides an example Python program to solve Sudoku puzzles using backtracking. It begins by explaining that Sudoku puzzles involve filling a 9x9 grid with numbers 1-9 such that each number appears only once in each row, column, and 3x3 subgrid. It then provides the Python code to implement the backtracking algorithm to solve Sudoku puzzles. The code uses a 2D list to represent the puzzle grid, and recursively tries different number placements, backtracking when a placement leads to an invalid partial solution.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
121 views20 pages

Solved Problem

The document discusses Sudoku puzzles and provides an example Python program to solve Sudoku puzzles using backtracking. It begins by explaining that Sudoku puzzles involve filling a 9x9 grid with numbers 1-9 such that each number appears only once in each row, column, and 3x3 subgrid. It then provides the Python code to implement the backtracking algorithm to solve Sudoku puzzles. The code uses a 2D list to represent the puzzle grid, and recursively tries different number placements, backtracking when a placement leads to an invalid partial solution.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 20

What is a Sudoku Puzzle ?

In the Sudoku puzzle we need to fill in every empty box with an integer between 1 and 9 in such a way
that every number from 1 up to 9 appears once in every row, every column and every one of the small 3
by 3 boxes highlighted with thick borders.

The difficulty of this puzzle might vary. The more the difficulty level of Sudoku puzzles, the more
challenging research problem it becomes for the computational scientists. Difficult puzzles mostly have
less prescribed symbols.

The Sudoku puzzles which are published for entertainment have unique solutions. A Sudoku puzzle is
believed to be a well-formed if it has a unique solution. Another challenging research problem is to
determine how few boxes need to be filled for a Sudoku puzzle to be well-formed. Well-formed Sudoku
with 17 symbols exist. It is unknown whether or not there exists a well formed puzzle with only 16 clues.

Steps to solve the sudoku puzzle in Python

In this method for solving the sudoku puzzle, first we assign the size of the 2D matrix to variable M
(M*M).

Then we assign the utility function (puzzle) to print the grid.

Later it will assign num to the row and col.

If we find same num in the same row or same column or in the specific 3*3 matrix, ‘false’ will be
returned.

Then we will check if we have reached the 8th row and 9th column and return true for stopping the
further backtracking.

Next we will check if the column value becomes 9 then we move to the next row and column.

Further now we see if the current position of the grid has value greater than 0, then we iterate for next
column.

After checking if it is a safe place , we move to the next column and then assign num in current (row ,col)
position of the grid. Later we check for next possibility with next column.

As our assumption was wrong, we discard the assigned num and then we go for the next assumption
with different num value
Implementing the sudoku solver in Python

We’ll use the backtracking method to create our sudoku solver in Python. Backtracking means switching
back to the previous step as soon as we determine that our current solution cannot be continued into a
complete one. We use this principle of backtracking to implement the sudoku algorithm.

Program :

M=9

def puzzle(a):

for i in range(M):

for j in range(M):

print(a[i][j],end = " ")

print()

def solve(grid, row, col, num):

for x in range(9):

if grid[row][x] == num:

return False

for x in range(9):

if grid[x][col] == num:

return False

startRow = row - row % 3

startCol = col - col % 3

for i in range(3):
for j in range(3):

if grid[i + startRow][j + startCol] == num:

return False

return True

def Suduko(grid, row, col):

if (row == M - 1 and col == M):

return True

if col == M:

row += 1

col = 0

if grid[row][col] > 0:

return Suduko(grid, row, col + 1)

for num in range(1, M + 1, 1):

if solve(grid, row, col, num):

grid[row][col] = num

if Suduko(grid, row, col + 1):

return True

grid[row][col] = 0

return False

'''0 means the cells where no value is assigned'''


grid = [[2, 5, 0, 0, 3, 0, 9, 0, 1],

[0, 1, 0, 0, 0, 4, 0, 0, 0],

[4, 0, 7, 0, 0, 0, 2, 0, 8],

[0, 0, 5, 2, 0, 0, 0, 0, 0],

[0, 0, 0, 0, 9, 8, 1, 0, 0],

[0, 4, 0, 0, 0, 3, 0, 0, 0],

[0, 0, 0, 3, 6, 0, 0, 7, 2],

[0, 7, 0, 0, 0, 0, 0, 0, 3],

[9, 0, 3, 0, 0, 0, 6, 0, 4]]

if (Suduko(grid, 0, 0)):

puzzle(grid)

else:

print("Solution does not exist:(")

Solution :

258736941

619824357

437915268

395271486

762498135

841653729

184369572

576142893

923587614
You can import the sudoku py-sudoku.PyPI module from https://pypi.org/project/py-sudoku/.

Graph coloring (also called vertex coloring) is a way of coloring a graph’s vertices such that no two
adjacent vertices share the same color. This post will discuss a greedy algorithm for graph coloring and
minimize the total number of colors used.

For example, consider the following graph:

We can color it in many ways by using the minimum of 3 colors.

We have used greedy algorithm method for color graphs,

Program :

# A class to represent a graph object

class Graph:

# Constructor

def __init__(self, edges, N):

self.adj = [[] for _ in range(N)]

# add edges to the undirected graph


for (src, dest) in edges:

self.adj[src].append(dest)

self.adj[dest].append(src)

# Function to assign colors to vertices of a graph

def colorGraph(graph):

# keep track of the color assigned to each vertex

result = {}

# assign a color to vertex one by one

for u in range(N):

# check colors of adjacent vertices of `u` and store them in a set

assigned = set([result.get(i) for i in graph.adj[u] if i in result])

# check for the first free color

color = 1

for c in assigned:

if color != c:

break

color = color + 1

# assign vertex `u` the first available color


result[u] = color

for v in range(N):

print("Color assigned to vertex", v, "is", colors[result[v]])

# Greedy coloring of a graph

if __name__ == '__main__':

# Add more colors for graphs with many more vertices

colors = ["", "BLUE", "GREEN", "RED", "YELLOW", "ORANGE", "PINK",

"BLACK", "BROWN", "WHITE", "PURPLE", "VOILET"]

# of graph edges as per the above diagram

edges = [(0, 1), (0, 4), (0, 5), (4, 5), (1, 4), (1, 3), (2, 3), (2, 4)]

# total number of nodes in the graph

N=6

# build a graph from the given edges

graph = Graph(edges, N)

# color graph using the greedy algorithm

colorGraph(graph)
Solution :

Color assigned to vertex 0 is BLUE

Color assigned to vertex 1 is GREEN

Color assigned to vertex 2 is BLUE

Color assigned to vertex 3 is RED

Color assigned to vertex 4 is RED

Color assigned to vertex 5 is GREEN

[Program finished]

Breadth First Search in Python (with Code) | BFS Algorithm

Breadth-First Search (BFS) is an algorithm used for traversing graphs or trees. Traversing means visiting
each node of the graph. Breadth-First Search is a recursive algorithm to search all the vertices of a graph
or a tree. BFS in python can be implemented by using data structures like a dictionary and lists. Breadth-
First Search in tree and graph is almost the same. The only difference is that the graph may contain
cycles, so we may traverse to the same node again.

As breadth-first search is the process of traversing each node of the graph, a standard BFS algorithm
traverses each vertex of the graph into two parts: 1) Visited 2) Not Visited. So, the purpose of the
algorithm is to visit all the vertex while avoiding cycles.

BFS implementation in Python (Source Code)

Now, we will see how the source code of the program for implementing breadth first search in python.

Consider the following graph which is implemented in the code below:


Program :

graph = {

'5' : ['3','7'],

'3' : ['2', '4'],

'7' : ['8'],

'2' : [],

'4' : ['8'],

'8' : []

visited = [] # List for visited nodes.

queue = [] #Initialize a queue

def bfs(visited, graph, node): #function for BFS

visited.append(node)

queue.append(node)
while queue: # Creating loop to visit each node

m = queue.pop(0)

print (m, end = " ")

for neighbour in graph[m]:

if neighbour not in visited:

visited.append(neighbour)

queue.append(neighbour)

# Driver Code

print("Following is the Breadth-First Search")

bfs(visited, graph, '5') # function calling

Solution :

The output of the above code will be as follow:

Following is the Breadth-First Search

537248

[Program finished]

In the above code, first, we will create the graph for which we will use the breadth-first search. After
creation, we will create two lists, one to store the visited node of the graph and another one for storing
the nodes in the queue.

After the above process, we will declare a function with the parameters as visited nodes, the graph itself
and the node respectively. And inside a function, we will keep appending the visited and queue lists.

Then we will run the while loop for the queue for visiting the nodes and then will remove the same node
and print it as it is visited.

At last, we will run the for loop to check the not visited nodes and then append the same from the
visited and queue list.As the driver code, we will call the user to define the bfs function with the first
node we wish to visit..
Depth First Search (DFS)

Depth first Search or Depth first traversal is a recursive algorithm for searching all the vertices of a graph
or tree data structure. Traversal means visiting all the nodes of a graph.

Depth First Search algorithm works with an example. We use an undirected graph with 5 vertices.

Depth First Search Algorithm

A standard DFS implementation puts each vertex of the graph into one of two categories:

1) Visited
2) Not Visited

The purpose of the algorithm is to mark each vertex as visited while avoiding cycles.

The DFS algorithm works as follows:

 Start by putting any one of the graph's vertices on top of a stack.


 Take the top item of the stack and add it to the visited list.
 Create a list of that vertex's adjacent nodes. Add the ones which aren't in the visited list to the
top of the stack.
 Keep repeating steps 2 and 3 until the stack is empty.

Depth First Search Example.

We use an undirected graph with 5 vertices.

We start from vertex 0, the DFS algorithm starts by putting it in the Visited list and putting all its
adjacent vertices in the stack.
Next, we visit the element at the top of stack i.e. 1 and go to its adjacent nodes. Since 0 has already
been visited, we visit 2 instead.

Vertex 2 has an unvisited adjacent vertex in 4, so we add that to the top of the stack and visit it.

After we visit the last element 3, it doesn't have any unvisited adjacent nodes, so we have completed
the Depth First Traversal of the graph.

DFS Pseudocode (recursive implementation)

The pseudocode for DFS is shown below. In the init() function, notice that we run the DFS function on
every node. This is because the graph might have two different disconnected parts so to make sure that
we cover every vertex, we can also run the DFS algorithm on every node.
DFS algorithm in Python

# DFS algorithm

def dfs(graph, start, visited=None):

if visited is None:

visited = set()

visited.add(start)

print(start)

for next in graph[start] - visited:

dfs(graph, next, visited)

return visited

graph = {'0': set(['1', '2']),

'1': set(['0', '3', '4']),

'2': set(['0']),

'3': set(['1']),

'4': set(['2', '3'])}

Output :
0

[Program finished]

3) depth limited search in python with a graph :

#The Algorithm (In English):

# 1) Pick any node.

# 2) If it is unvisited, mark it as visited and recur on all its

# adjacent nodes.
# 3) Repeat until all the nodes are visited, or the node to be

# searched is found.

Program :

graph = {

'A' : ['B','C'],

'B' : ['D', 'E'],

'C' : ['F'],

'D' : [],

'E' : ['F'],

'F' : []

visited = set() # Set to keep track of visited nodes.

##################

# The Algorithm (In Code)

def dfs(visited, graph, node):

if node not in visited:

print (node)

visited.add(node)

for neighbour in graph[node]:

dfs(visited, graph, neighbour)


# Driver Code to test in python yourself.

# Note that when calling this, you need to

# call the starting node. In this case it is 'A'.

dfs(visited, graph, 'A')

# NOTE: There are a few ways to do DFS, depending on what your

# variables are and/or what you want returned. This specific

# example is the most fleshed-out, yet still understandable,

# explanation I could find.

Output :

[Program finished]

4) Iterative Deepening Depth First Search(IDDFS)

IDDFS combines depth-first search’s space-efficiency and breadth-first search’s fast search (for nodes
closer to root).
IDDFS calls DFS for different depths starting from an initial value. In every call, DFS is restricted from
going beyond given depth. So basically we do DFS in a BFS fashion.

# Python program to print DFS traversal from a given

# given graph

from collections import defaultdict

# This class represents a directed graph using adjacency

# list representation

class Graph:

def __init__(self,vertices):

# No. of vertices

self.V = vertices

# default dictionary to store graph

self.graph = defaultdict(list)

# function to add an edge to graph

def addEdge(self,u,v):
self.graph[u].append(v)

# A function to perform a Depth-Limited search

# from given source 'src'

def DLS(self,src,target,maxDepth):

if src == target : return True

# If reached the maximum depth, stop recursing.

if maxDepth <= 0 : return False

# Recur for all the vertices adjacent to this vertex

for i in self.graph[src]:

if(self.DLS(i,target,maxDepth-1)):

return True

return False

# IDDFS to search if target is reachable from v.

# It uses recursive DLS()

def IDDFS(self,src, target, maxDepth):

# Repeatedly depth-limit search till the

# maximum depth

for i in range(maxDepth):

if (self.DLS(src, target, i)):

return True
return False

# Create a graph given in the above diagram

g = Graph (7);

g.addEdge(0, 1)

g.addEdge(0, 2)

g.addEdge(1, 3)

g.addEdge(1, 4)

g.addEdge(2, 5)

g.addEdge(2, 6)

target = 6; maxDepth = 3; src = 0

if g.IDDFS(src, target, maxDepth) == True:

print ("Target is reachable from source " + "within max depth")

else :

print ("Target is NOT reachable from source " + "within max depth"Target is reachable from source
within max depth

[Program finished]

Output :

Target is reachable from source within max depth

[Program finished]

You might also like