AI Python Lab Report CSIT 4th Semester Part II

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 28

BSc.

CSIT Artificial Intelligence Sanam Timilsina

LAB:2

1. WAP to implement BFS for a graph.

Source Code:
From collections import deque
class Graph:
def __init__(self):
self.graph = {}

def add_edge(self, node, neighbors):


self.graph[node] = neighbors

def bfs(self, start_node):


visited = set()
queue = deque([start_node])
while queue:
current_node = queue.popleft()
if current_node not in visited:
print(current_node, end=' ')
visited.add(current_node)

neighbors = self.graph[current_node]
for neighbor in neighbors:
if neighbor not in visited:
queue.append(neighbor)

# Example usage:

# Create a graph object


graph = Graph()

# Add edges to the graph


graph.add_edge('A', ['B', 'C'])
graph.add_edge('B', ['D', 'E'])
graph.add_edge('C', ['F'])
graph.add_edge('D', [])
graph.add_edge('E', [])
graph.add_edge('F', [])

# Perform BFS starting from node 'A'


start_node = 'A'
print("BFS traversal starting from node", start_node)
graph.bfs(start_node)

1 93/077
BSc.CSIT Artificial Intelligence Sanam Timilsina

Output:

Graph:

2. WAP to implement Uniform-cost search.

Source Code:
import heapq
class Graph:
def __init__(self, graph_dict):
self.graph_dict = graph_dict

def uniform_cost_search(self, start_node, goal_node):


priority_queue = [(0, start_node)]
visited = set()

while priority_queue:
cost, current_node = heapq.heappop(priority_queue)

if current_node == goal_node:
return cost

visited.add(current_node)

if current_node not in self.graph_dict:


continue

for neighbor, edge_cost in


self.graph_dict[current_node].items():
if neighbor not in visited:
heapq.heappush(priority_queue, (cost + edge_cost,
neighbor))

2 93/077
BSc.CSIT Artificial Intelligence Sanam Timilsina

return -1 # Goal node not found

# Example usage:

# Define the graph as a dictionary of dictionaries


graph_dict = {
'A': {'B': 5, 'C': 3},
'B': {'D': 2, 'E': 4},
'C': {'F': 6},
'D': {'G': 1},
'E': {'G': 3},
'F': {'H': 5},
'G': {'H': 2},
'H': {}
}

# Create the graph object


graph = Graph(graph_dict)

# Perform Uniform-Cost Search from node 'A' to node 'H'


start_node = 'A'
goal_node = 'H'
cost = graph.uniform_cost_search(start_node, goal_node)

if cost != -1:
print(f"The cost of the path from {start_node} to {goal_node} is:
{cost}")
else:
print(f"No path found from {start_node} to {goal_node}")

Output:

Graph:

3 93/077
BSc.CSIT Artificial Intelligence Sanam Timilsina

3. WAP to implement DFS for a graph.

Source Code:
class Graph:
def __init__(self, graph_dict):
self.graph_dict = graph_dict

def DFS(self, start_node):


visited = set()
self._recursive_dfs(start_node, visited)

def _recursive_dfs(self, current_node, visited):


print(current_node) # Print the current node
visited.add(current_node)

if current_node not in self.graph_dict:


return

for neighbor in self.graph_dict[current_node]:


if neighbor not in visited:
self._recursive_dfs(neighbor, visited)

# Example usage:

# Define the graph as a dictionary


graph_dict = {
'A': ['B', 'C'],
'B': ['D', 'E'],
'C': ['F'],
'D': [],
'E': [],
'F': ['G'],
'G': ['H'],
'H': []
}

# Create the graph object


graph = Graph(graph_dict)

# Perform Depth-First Search starting from node 'A'


graph.DFS('A')

4 93/077
BSc.CSIT Artificial Intelligence Sanam Timilsina

Output:

Graph:

4. WAP to implement Depth limited search for a graph.

Source Code
class Graph:
def __init__(self, graph_dict):
self.graph_dict = graph_dict

def DLS(self, start_node, goal_node, depth_limit):


return self._recursive_dls(start_node, goal_node, depth_limit)

def _recursive_dls(self, current_node, goal_node, depth_limit):


if current_node == goal_node:
return True

if depth_limit <= 0:
return False

if current_node not in self.graph_dict:


return False

for neighbor in self.graph_dict[current_node]:

5 93/077
BSc.CSIT Artificial Intelligence Sanam Timilsina

if self._recursive_dls(neighbor, goal_node, depth_limit -


1):
return True

return False

# Example usage:

# Define the graph as a dictionary


graph_dict = {
'A': ['B', 'C'],
'B': ['D', 'E'],
'C': ['F'],
'D': [],
'E': [],
'F': ['G'],
'G': ['H'],
'H': []
}

# Create the graph object


graph = Graph(graph_dict)

# Define the start node and the goal node


start_node = 'A'
goal_node = 'H'

# Define the depth limit


depth_limit = 3

# Perform Depth-Limited Search


result = graph.DLS(start_node, goal_node, depth_limit)

# Print the result


if result:
print(f"Goal node '{goal_node}' is reachable from start node
'{start_node}' within depth limit {depth_limit}")
else:
print(f"Goal node '{goal_node}' is not reachable from start node
'{start_node}' within depth limit {depth_limit}")

Output:

6 93/077
BSc.CSIT Artificial Intelligence Sanam Timilsina

Graph:

5. WAP to implement greedy best first search.

Source Code:
import heapq

class Node:
def __init__(self, state, parent=None, heuristic=0):
self.state = state
self.parent = parent
self.heuristic = heuristic

def __lt__(self, other):


return self.heuristic < other.heuristic

def greedy_best_first_search(initial_state, goal_state, heuristic,


successors):
open_list = []
closed_set = set()

start_node = Node(initial_state, None, heuristic(initial_state))


heapq.heappush(open_list, start_node)

while open_list:
current_node = heapq.heappop(open_list)

if current_node.state == goal_state:
return get_path(current_node)

closed_set.add(current_node.state)

for successor in successors(current_node.state):


if successor in closed_set:
continue

7 93/077
BSc.CSIT Artificial Intelligence Sanam Timilsina

successor_node = Node(successor, current_node,


heuristic(successor))

if is_node_in_open_list(successor_node, open_list):
continue

heapq.heappush(open_list, successor_node)

return None

def get_path(node):
path = []
current = node

while current:
path.append(current.state)
current = current.parent

path.reverse()
return path

def is_node_in_open_list(node, open_list):


for open_node in open_list:
if open_node.state == node.state:
return True

return False

# Example usage:

# Define the initial state, goal state, and the heuristic function
initial_state = 'A'
goal_state = 'H'

def heuristic(state):
# Define a heuristic function that estimates the cost from the
current state to the goal state
# In this example, we use a simple dictionary to store the heuristic
values for each state
heuristic_values = {
'A': 8,
'B': 6,
'C': 16,
'D': 1,
'E': 2,
'F': 3,
'G': 1,
'H': 0,
}

8 93/077
BSc.CSIT Artificial Intelligence Sanam Timilsina

return heuristic_values[state]

# Define the successors function


def successors(state):
# Define a successors function that returns the possible successors
of the given state
# In this example, we use a simple dictionary to store the
successors for each state
successors = {
'A': ['B', 'C'],
'B': ['D', 'E'],
'C': ['F'],
'D': ['G'],
'E': ['G'],
'F': ['H'],
'G': ['H'],
'H': [],
}
return successors[state]

# Solve the problem using Greedy Best-First Search


path = greedy_best_first_search(initial_state, goal_state, heuristic,
successors)

# Print the path


if path:
print("Path found:", path)
else:
print("No path found")

Output:

Graph:

9 93/077
BSc.CSIT Artificial Intelligence Sanam Timilsina

6. WAP to implement A* search.

Source Code:

import heapq

class Node:
def __init__(self, state, parent=None, g=0, h=0):
self.state = state
self.parent = parent
self.g = g # cost from start node to current node
self.h = h # heuristic cost from current node to goal node
self.f = g + h # total cost (f = g + h)

def __lt__(self, other):


return self.f < other.f

def astar_search(initial_state, goal_state, heuristic, successors):


open_list = []
closed_set = set()

start_node = Node(initial_state)
heapq.heappush(open_list, start_node)

while open_list:
current_node = heapq.heappop(open_list)

if current_node.state == goal_state:
return get_path(current_node)

closed_set.add(current_node.state)

for successor, cost in successors(current_node.state):


if successor in closed_set:
continue

g = current_node.g + cost
h = heuristic(successor, goal_state)
f = g + h

successor_node = Node(successor, current_node, g, h)

if is_node_in_open_list(successor_node, open_list):
continue

heapq.heappush(open_list, successor_node)

10 93/077
BSc.CSIT Artificial Intelligence Sanam Timilsina

return None

def get_path(node):
path = []
current = node

while current:
path.append(current.state)
current = current.parent

path.reverse()
return path

def is_node_in_open_list(node, open_list):


for open_node in open_list:
if open_node.state == node.state and open_node.f <= node.f:
return True

return False

# Example usage:

# Define the initial state, goal state, and the heuristic function
initial_state = 'A'
goal_state = 'H'

def heuristic(state, goal_state):


# Define a heuristic function that estimates the cost from the
current state to the goal state
# In this example, we use a simple dictionary to store the heuristic
values for each state
heuristic_values = {
'A': 8,
'B': 6,
'C': 4,
'D': 3,
'E': 2,
'F': 3,
'G': 1,
'H': 0,
}
return heuristic_values[state]

# Define the successors function


def successors(state):
# Define a successors function that returns the possible successors
of the given state and their costs
# In this example, we use a simple dictionary to store the
successors for each state along with their costs
successors = {

11 93/077
BSc.CSIT Artificial Intelligence Sanam Timilsina

'A': [('B', 4), ('C', 2)],


'B': [('D', 5), ('E', 10)],
'C': [('F', 3)],
'D': [('G', 6)],
'E': [('G', 8)],
'F': [('H', 3)],
'G': [('H', 2)],
'H': [],
}
return successors[state]

# Solve the problem using A* search


path = astar_search(initial_state, goal_state, heuristic, successors)

# Print the path


if path:
print("Path found:", path)
else:
print("No path found")

Output:

Graph:

12 93/077
BSc.CSIT Artificial Intelligence Sanam Timilsina

7. WAP to implement Hill Climbing (Steepest Ascent) Search.

Source Code:

def hill_climbing(problem, heuristic):


current_state = problem.get_initial_state()

while True:
neighbors = problem.get_neighbors(current_state)
best_neighbor = None
best_neighbor_cost = float('-inf')

for neighbor in neighbors:


neighbor_cost = heuristic(neighbor)

if neighbor_cost > best_neighbor_cost:


best_neighbor = neighbor
best_neighbor_cost = neighbor_cost

if best_neighbor_cost <= heuristic(current_state):


break

current_state = best_neighbor

return current_state

# Example usage:
# Define the problem class
class Problem:
def __init__(self):
self.initial_state = 3

def get_initial_state(self):
return self.initial_state

def get_neighbors(self, state):


return [state + 1, state - 1]

# Define the heuristic function


def heuristic(state):
return -abs(state - 5) # Negative distance from the goal state

# Create an instance of the problem


problem = Problem()

# Solve the problem using Hill Climbing (Steepest Ascent)

13 93/077
BSc.CSIT Artificial Intelligence Sanam Timilsina

solution = hill_climbing(problem, heuristic)

# Print the solution


print("Solution:", solution)

Output:

Graph:

8. WAP to solve any one Cryptarithmetic Problem (like TWO +TWO = FOUR or SEND
+MORE = MONEY ). (Recommended Language: Python)

Source Code:

from itertools import permutations

def solve_cryptarithmetic(puzzle):
unique_letters = set(char for word in puzzle for char in word if
char.isalpha())
letters = list(unique_letters)
num_letters = len(letters)
digits = range(10)

14 93/077
BSc.CSIT Artificial Intelligence Sanam Timilsina

for perm in permutations(digits, num_letters):


mapping = dict(zip(letters, perm))
if all(mapping[word[0]] != 0 for word in puzzle):
values = [int(''.join(str(mapping[char]) for char in
word)) for word in puzzle]
if values[0] + values[1] == values[2]:
return mapping

return None

# Example usage:
puzzle = ["TWO", "TWO", "FOUR"]
solution = solve_cryptarithmetic(puzzle)

if solution is not None:


print("Solution found:")
for word in puzzle:
print(''.join(str(solution[char]) for char in word), end=' ')
else:
print("No solution found.")

Output:

9. Implementing Frame (Recommended Language: C++ / use object pointers)


"Ram is a person living in Nepal. He was born on 15th December of year 1990. He is 6
inch tall and has 75 kg weight. He has a job. He works at 'ABC company' as AI
Researcher and earns 1.5 lakhs per month. The company is situated at Kathmandu."
Represent above information in frames diagrammatically and also implement it using the
concepts of class in C+.

Source Code:
#include <iostream>
#include <string>

class Person {

15 93/077
BSc.CSIT Artificial Intelligence Sanam Timilsina

private:
std::string name;
std::string country;
std::string dateOfBirth;
int height;
int weight;

public:
Person(std::string n, std::string c, std::string dob, int h, int
w)
: name(n), country(c), dateOfBirth(dob), height(h), weight(w)
{}

void displayInformation() {
std::cout << "+------------------------------------------+"
<< std::endl;
std::cout << "| Person |"
<< std::endl;
std::cout << "|------------------------------------------|"
<< std::endl;
std::cout << "| Name: " << name << std::endl;
std::cout << "| Country: " << country << std::endl;
std::cout << "| Date of Birth: " << dateOfBirth << std::endl;
std::cout << "| Height: " << height << " inch" <<
std::endl;
std::cout << "| Weight: " << weight << " kg" <<
std::endl;
std::cout << "+------------------------------------------+"
<< std::endl;
}
};

class Employee {
private:
std::string occupation;
double salary;
std::string company;
std::string location;

public:
Employee(std::string occ, double sal, std::string comp,
std::string loc)
: occupation(occ), salary(sal), company(comp), location(loc)
{}

void displayInformation() {

16 93/077
BSc.CSIT Artificial Intelligence Sanam Timilsina

std::cout << "+------------------------------------------+"


<< std::endl;
std::cout << "| Employee |"
<< std::endl;
std::cout << "|------------------------------------------|"
<< std::endl;
std::cout << "| Occupation: " << occupation << std::endl;
std::cout << "| Salary: " << salary << " lakhs per
month" << std::endl;
std::cout << "| Company: " << company << std::endl;
std::cout << "| Location: " << location << std::endl;
std::cout << "+------------------------------------------+"
<< std::endl;
}
};

int main() {
Person* ram = new Person("Ram", "Nepal", "15th December 1990", 6,
75);
Employee* ramJob = new Employee("AI Researcher", 1.5, "ABC
company", "Kathmandu");

ram->displayInformation();
ramJob->displayInformation();

delete ram;
delete ramJob;

return 0;
}

Output:

17 93/077
BSc.CSIT Artificial Intelligence Sanam Timilsina

10. Implementing Frame (Recommended Language: C++ / use object pointers)


"Ram is a person living in Nepal. He was born on 15th December of year 1990. He is 6
inch tall and has 75 kg weight. He has a job. He works at 'ABC company' as AI
Researcher and earns 1.5 lakhs per month. The company is situated at Kathmandu."
Represent above information in frames diagrammatically and also implement it using the
concepts of class in C++.

Source Code:
#include <iostream>
#include <string>
using namespace std;

class Person {
private:
string name;
string country;
string dateOfBirth;
int height;
int weight;

18 93/077
BSc.CSIT Artificial Intelligence Sanam Timilsina

public:
Person(string n, string c, string dob, int h, int w)
: name(n), country(c), dateOfBirth(dob), height(h), weight(w)
{}

void displayInformation() {
cout << "+------------------------------------------+" <<
endl;
cout << "| Person |" <<
endl;
cout << "|------------------------------------------|" <<
endl;
cout << "| Name: " << name << endl;
cout << "| Country: " << country << endl;
cout << "| Date of Birth: " << dateOfBirth << endl;
cout << "| Height: " << height << " inch" << endl;
cout << "| Weight: " << weight << " kg" << endl;
cout << "+------------------------------------------+" <<
endl;
}
};

class Employee {
private:
string occupation;
double salary;
string company;
string location;

public:
Employee(string occ, double sal, string comp, string loc)
: occupation(occ), salary(sal), company(comp), location(loc)
{}

void displayInformation() {
cout << "+------------------------------------------+" <<
endl;
cout << "| Employee |" <<
endl;
cout << "|------------------------------------------|" <<
endl;
cout << "| Occupation: " << occupation << endl;
cout << "| Salary: " << salary << " lakhs per month"
<< endl;
cout << "| Company: " << company << endl;
cout << "| Location: " << location << endl;

19 93/077
BSc.CSIT Artificial Intelligence Sanam Timilsina

cout << "+------------------------------------------+" <<


endl;
}
};

int main() {
Person ram("Ram", "Nepal", "15th December 1990", 6, 75);
Employee ramJob("AI Researcher", 1.5, "ABC company",
"Kathmandu");

ram.displayInformation();
ramJob.displayInformation();

return 0;
}

Output:

11. WAP to develop a sample medical expert system capable of diagnosing disease based on
the provided symptoms.

20 93/077
BSc.CSIT Artificial Intelligence Sanam Timilsina

Source Code:
class Disease:
def __init__(self, name, symptoms):
self.name = name
self.symptoms = symptoms
class MedicalExpertSystem:
def __init__(self):
self.diseases = []
def add_disease(self, name, symptoms):
disease = Disease(name, symptoms)
self.diseases.append(disease)

def diagnose(self, input_symptoms):


matched_diseases = []
for disease in self.diseases:
if set(disease.symptoms).issubset(input_symptoms):
matched_diseases.append(disease)
if len(matched_diseases) == 0:
print("No matching disease found.")
else:
print("Possible diseases:")
for disease in matched_diseases:
print("- ", disease.name)

# Create a medical expert system


expert_system = MedicalExpertSystem()

# Add diseases and their symptoms


expert_system.add_disease("Common Cold", ["sore throat", "runny
nose", "cough"])
expert_system.add_disease("Flu", ["fever", "headache", "muscle
pain"])
expert_system.add_disease("Allergies", ["sneezing", "itchy eyes",
"rash"])

# Get user input for symptoms


user_input = input("Enter the symptoms (comma-separated): ")
input_symptoms = user_input.split(", ")

# Diagnose the disease based on symptoms


expert_system.diagnose(input_symptoms)

21 93/077
BSc.CSIT Artificial Intelligence Sanam Timilsina

12. Realization of AND, OR and NOT gates using Artificial Neurons.

Source Code:
import numpy as np

# Activation function (step function)


def step_function(x):
return 1 if x >= 0 else 0

# AND gate
def AND_gate(x1, x2):
# Weight and bias values for the AND gate
weights = np.array([0.5, 0.5])
bias = -0.7

# Calculate the weighted sum


weighted_sum = np.dot([x1, x2], weights) + bias

# Apply the activation function


output = step_function(weighted_sum)
return output

# OR gate
def OR_gate(x1, x2):
# Weight and bias values for the OR gate
weights = np.array([0.5, 0.5])
bias = -0.2

# Calculate the weighted sum


weighted_sum = np.dot([x1, x2], weights) + bias

# Apply the activation function


output = step_function(weighted_sum)
return output

# NOT gate
def NOT_gate(x):
# Weight and bias values for the NOT gate
weight = -0.5
bias = 0.2

# Calculate the weighted sum


weighted_sum = x * weight + bias

# Apply the activation function


output = step_function(weighted_sum)

22 93/077
BSc.CSIT Artificial Intelligence Sanam Timilsina

return output

# Test the gates


print("AND gate:")
print("0 AND 0 =", AND_gate(0, 0))
print("0 AND 1 =", AND_gate(0, 1))
print("1 AND 0 =", AND_gate(1, 0))
print("1 AND 1 =", AND_gate(1, 1))

print("\nOR gate:")
print("0 OR 0 =", OR_gate(0, 0))
print("0 OR 1 =", OR_gate(0, 1))
print("1 OR 0 =", OR_gate(1, 0))
print("1 OR 1 =", OR_gate(1, 1))

print("\nNOT gate:")
print("NOT 0 =", NOT_gate(0))
print("NOT 1 =", NOT_gate(1))

Output:

23 93/077
BSc.CSIT Artificial Intelligence Sanam Timilsina

13. A Simple Example of Back Propagation Learning.

Source Code:
import numpy as np

# Define the sigmoid activation function


def sigmoid(x):
return 1 / (1 + np.exp(-x))

# Define the derivative of the sigmoid function


def sigmoid_derivative(x):
return x * (1 - x)

# Define the neural network class


class NeuralNetwork:
def __init__(self, input_size, hidden_size, output_size):
self.input_size = input_size
self.hidden_size = hidden_size
self.output_size = output_size

# Initialize the weights with random values


self.weights1 = np.random.randn(self.input_size,
self.hidden_size)
self.weights2 = np.random.randn(self.hidden_size,
self.output_size)

def forward(self, X):


# Perform forward propagation
self.hidden_layer = sigmoid(np.dot(X, self.weights1))
self.output_layer = sigmoid(np.dot(self.hidden_layer,
self.weights2))
return self.output_layer

def backward(self, X, y, learning_rate):


# Perform backward propagation and update the weights
output_error = y - self.output_layer
output_delta = output_error *
sigmoid_derivative(self.output_layer)

hidden_error = np.dot(output_delta, self.weights2.T)


hidden_delta = hidden_error *
sigmoid_derivative(self.hidden_layer)

self.weights2 += learning_rate * np.dot(self.hidden_layer.T,


output_delta)
self.weights1 += learning_rate * np.dot(X.T, hidden_delta)

24 93/077
BSc.CSIT Artificial Intelligence Sanam Timilsina

def train(self, X, y, epochs, learning_rate):


for epoch in range(epochs):
output = self.forward(X)
self.backward(X, y, learning_rate)

# Example usage:

# Define the training dataset


X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
y = np.array([[0], [1], [1], [0]])

# Create a neural network with 2 input neurons, 2 hidden neurons, and


1 output neuron
network = NeuralNetwork(2, 2, 1)

# Train the network for 10000 epochs with a learning rate of 0.1
network.train(X, y, epochs=10000, learning_rate=0.1)

# Test the trained network


print("Predictions:")
for i in range(len(X)):
prediction = network.forward(X[i])
print(f"Input: {X[i]}, Output: {prediction}")

Output:

14. WAP to solve the N Queen Problem. (Problem: To find an arrangement of N queens on a
chess board of size N×N, such that no queen can attack any other queens on the board)

Source Code:
def is_safe(board, row, col, N):
# Check if there is a queen in the same column
for i in range(row):
if board[i][col] == 1:

25 93/077
BSc.CSIT Artificial Intelligence Sanam Timilsina

return False

# Check if there is a queen in the upper left diagonal


i, j = row, col
while i >= 0 and j >= 0:
if board[i][j] == 1:
return False
i -= 1
j -= 1

# Check if there is a queen in the upper right diagonal


i, j = row, col
while i >= 0 and j < N:
if board[i][j] == 1:
return False
i -= 1
j += 1

return True

def solve_n_queen(board, row, N):


if row == N:
# Print the solution
for i in range(N):
for j in range(N):
print(board[i][j], end=" ")
print()
print()
return

for col in range(N):


if is_safe(board, row, col, N):
board[row][col] = 1
solve_n_queen(board, row + 1, N)
board[row][col] = 0

def n_queen(N):
board = [[0 for _ in range(N)] for _ in range(N)]
solve_n_queen(board, 0, N)

# Test the program


n_queen(4) # Solve 4-queen problem

Output:

26 93/077
BSc.CSIT Artificial Intelligence Sanam Timilsina

15. WAP to solve Water Jug Problem.(Problem statement: Given two jugs, a 4-gallon and 3-
gallon having no measuring markers on them. There is a pump that can be used to fill the
jugs with water and the water can be poured on the ground. How can you get exactly 2
gallons of water into 4-gallon jug?

Source Code:
from collections import deque
def water_jug_problem(target):
queue = deque([(0, 0)])
visited = set()

while queue:
jug_state = queue.popleft()
jug1 = jug_state[0]
jug2 = jug_state[1]

if jug1 == target:
return jug_state

if jug_state in visited:
continue

visited.add(jug_state)

# Fill jug1
queue.append((4, jug2))
# Fill jug2
queue.append((jug1, 3))
# Empty jug1
queue.append((0, jug2))
# Empty jug2

27 93/077
BSc.CSIT Artificial Intelligence Sanam Timilsina

queue.append((jug1, 0))
# Pour jug1 to jug2
amount = min(jug1, 3 - jug2)
queue.append((jug1 - amount, jug2 + amount))
# Pour jug2 to jug1
amount = min(jug2, 4 - jug1)
queue.append((jug1 + amount, jug2 - amount))

return None

# Solve the Water Jug Problem to get exactly 2 gallons in the 4-


gallon jug
target_amount = 2
result = water_jug_problem(target_amount)

if result:
print(f"Solution found: {result[0]} gallons in the 4-gallon jug
and {result[1]} gallons in the 3-gallon jug.")
else:
print("Solution not found.")

Output:

28 93/077

You might also like