Untitled Document - Google Docs
Untitled Document - Google Docs
1 olve the Water Jug Problem. Given two jugs with
S
capacities 3L and 5L, find a sequence of actions to
Measure 4 liters of water in a Jug.
AIM: Solve the Water Jug Problem. Given two jugs with capacities 3L and 5L, find a sequence of actions to
Measure 4 liters of water in a Jug.
CODE:
# initally a,b is 0
a=0;b=0
def fill (a,b):
op=input("Select Bottle You want to fill \n a or b : ")
if (op=="a"):
a=5
return (a,b)
if (op=="b"):
b=3
return (a,b)
def fill_from_atob(a,b):
c=3-b
a=a-c
b=b+c
return (a,b)
def fill_from_btoa(a,b):
if (a>=b):
c=5-a
a=a+c
b=b-c
return (a,b)
if(a<b):
c=b
a=a+b
b=b-c
return (a,b)
p rint("Initially Bottles are Empty")
print("Your Choices\n1.FILL \n2.Empty \n3.SWAP \n4.Fill from A_TO_B \n5.Fill from B_TO_A\n6.ABOAT")
while (True):
ch=int(input("What do you want to select from above choice : "))
if ch==1:
(a,b)=fill(a,b)
elif ch==2:
(a,b)=empty(a,b)
elif ch==3:
(a,b)=swap(a,b)
elif ch==4:
(a,b)=fill_from_atob(a,b)
elif ch==5:
(a,b)=fill_from_btoa(a,b)
elif ch==6:
break
else:
print("SELECT VALID CHOICE!!!")
p rint("current state",(a,b))
if (a,b)==(4,0):
print("Yeh you win")
break
OUTPUT:
INFERENCE:
he program implements the Water Jug Problem, where the goal is to obtain exactly 4 liters of water in Jug A
T
using two jugs with fixed capacities of 5 liters (Jug A) and 3 liters (Jug B). The program allows users to perform
operations such as filling, emptying, and transferring water between the jugs while maintaining the problem
constraints. The program enables interactive decision-making by providing a menu-driven approach, allowing
users to reach the desired water level step by step. The implementation demonstrates the use of logical
problem-solving techniques.
EXPERIMENT-2
AIM: 8-puzzle problems. Determine the optimal sequence of tile movements to transform an initial 8-puzzle
configuration into a specified goal state.
CODE:
def userpuzzle():
puzzle =[[0,0,0],[0,0,0],[0,0,0]]
print("Enter the Puzzle Values one by one (use 0 for blank spaces):")
for i in range(3):
for j in range(3):
puzzle[i][j]=int(input(f"Enter value at position({i+1},{j+1}):"))
return puzzle
def printpuzzle(puzzle):
print()
for row in puzzle :
print(row)
print()
def findzero(puzzle):
for i in range(3):
for j in range(3):
if puzzle[i][j]==0:
#print(f"({i,j})")
return i,j
def swap(puzzle,x1,y1,x2,y2):
puzzle[x1][y1],puzzle[x2][y2]=puzzle[x2][y2],puzzle[x1][y1]
def up(puzzle):
x,y=findzero(puzzle)
if x>0:
swap(puzzle,x,y,x-1,y)
else:
print("Motion out of range !!!!")
def down(puzzle):
x,y=findpuzzle(puzzle)
if x<2:
swap(puzzle,x,y,x+1,y)
else :
print("Motion out of range !!!")
def left(puzle):
x,y=findzero(puzzle)
if y>0:
swap(puzzle,x,y,x,y-1)
else:
print("Motion out of range !!!")
def right(puzzle):
x,y=findzero(puzzle)
if y<2:
swap(puzzle,x,y,x,y+1)
else:
print("Motion out of range !!!")
p uzzle=userpuzzle()
goal=[[1,2,3],[4,5,6],[7,8,0]]
print("Initial State : ")
printpuzzle(puzzle)
while puzzle!=goal:
move=input("Select Move(up,down,left,right").strip().lower()
if move=="up":
up(puzzle)
elif move=="down":
down(puzzle)
elif move=="left":
left(puzzle)
elif move=="right":
right(puzzle)
else:
print("Wrong Selection")
printpuzzle(puzzle)
print("Congo!! you reached the goal ")
print("goal state:")
printpuzzle(puzzle)
OUTPUT:
I NFERENCE:
The code implements the 8-puzzle problem, allowing users to rearrange numbered blocks and get a predefined
goal state. It uses NumPy for grid representation and has swap-based movement functions- Up, Down, Left, right
to enable block transitions. Users can interactively shift the empty block within the defined grid boundaries while
maintaining the integrity of the puzzle structure. The program enables user interaction, displaying the updated grid
after each move. The structured approach ensures logical block movements while maintaining interactive
puzzle-solving.
EXPERIMENT- 3
AIM: To solve the 8-Puzzle Problem using the Hill Climbing Algorithm with a heuristic-based approach.
CODE:
def findzero(puzzle):
for i in range(3):
for j in range(3):
if puzzle[i][j] == 0:
return i, j
def swap(puzzle, x1, y1, x2, y2):
puzzle[x1][y1], puzzle[x2][y2] = puzzle[x2][y2], puzzle[x1][y1]
def up(puzzle):
x, y = findzero(puzzle)
if x > 0:
new_puzzle = [row[:] for row in puzzle]
swap(new_puzzle, x, y, x - 1, y)
return new_puzzle
return None
def down(puzzle):
x, y = findzero(puzzle)
if x < 2:
new_puzzle = [row[:] for row in puzzle]
swap(new_puzzle, x, y, x + 1, y)
return new_puzzle
return None
def left(puzzle):
x, y = findzero(puzzle)
if y > 0:
new_puzzle = [row[:] for row in puzzle]
swap(new_puzzle, x, y, x, y - 1)
return new_puzzle
return None
def right(puzzle):
x, y = findzero(puzzle)
if y < 2:
new_puzzle = [row[:] for row in puzzle]
swap(new_puzzle, x, y, x, y + 1)
return new_puzzle
return None
p rintpuzzle(puzzle)
print("Initial Heuristic:", heuristic(puzzle, goal))
while True:
best_move = None
best_heuristic = heuristic(puzzle, goal)
p uzzle = best_puzzle
printpuzzle(puzzle)
print(f"Move: {best_move}, New Heuristic: {best_heuristic}")
I NFERENCE:
The program solves the 8-puzzle problem using the Hill Climbing algorithm, which helps find the correct block
arrangement by making the best possible move at each step. It uses a heuristic value, such as counting misplaced
tiles or calculating the distance of each tile from its correct position, to decide which move brings the puzzle closer
to the solution. By always choosing the move that improves the puzzle state, the algorithm efficiently guides the
grid toward the goal state. The use of NumPy arrays makes handling the grid easier and ensures smooth movement
of tiles. This implementation demonstrates how Hill Climbing can be used to solve puzzles logically and step by
step, making it a useful technique for 8 puzzle problem-solving.
EXPERIMENT-4
CODE:
graph={'a':['b','c'],
'b':['a','d'],
'c':['a','e'],
'd':['b','f'],
'e':['c','f'],
'f':['d','e']
}
def bfs(graph,start,goal):
visited=set()
queue=[start]
while queue:
node=queue.pop(0)
if node not in visited:
print(node,end="->")
visited.add(node)
if node == goal:
print(f"\n\n\tGoal {goal} found!")
return
queue.extend(graph[node])
def bfs(graph,start,goal):
visited=set()
queue=[start]
while queue:
node=queue.pop(0)
if node not in visited:
print(node,end="->")
visited.add(node)
if node == goal:
print(f"\n\n\tGoal {goal} found!")
return
queue.extend(graph[node])
def dfs(graph,start,goal):
visited=set()
stack=[start]
while stack:
node=stack.pop(0)
if node not in visited:
print(node,end="->")
visited.add(node)
if node == goal:
p rint(f"\n\n\tGoal {goal} found!")
return
stack.extend(reversed(graph[node]))
print("*"*30)
print("\tGRAPH TRAVERSAL")
print("*"*30)
a=input("Select Start Node : ")
b=a.lower()
c=input("Select Goal Node : ")
print("*"*30)
d=c.lower()
print()
print("*"*30)
print("\tBFS TRAVERSAL")
print("*"*30)
bfs(graph,b,d)
print("*"*30)
print()
print("*"*30)
print("\tDFS TRAVERSAL")
print("*"*30)
dfs(graph,b,d)
print("*"*30)
OUTPUT:
I NFERENCE:
The program implements BFS and DFS, two important methods for exploring graphs and trees. BFS visits nodes
level by level, making it useful for finding the shortest path, while DFS goes deep into one path before
backtracking, making it good for exploring all possibilities. BFS ensures finding the shortest route in an
unweighted graph, while DFS is useful when searching deep structures with less memory. This implementation
clearly demonstrates how graph traversal techniques can be applied in real-world problem-solving.