Q1.
Design a Finite Automata (FA) that accepts all strings over S={0,
1} having three consecutive 1's as a substring. Write a program to
simulate this FA.
#include <iostream>
#include <string>
using namespace std;
// Function to simulate the FA
bool simulateFA(const string& input) {
// Initial state
int state = 0;
for (char c : input) {
if (c == '1') {
if (state == 0) state = 1; // Transition: q0 -> q1
else if (state == 1) state = 2; // Transition: q1 -> q2
else if (state == 2) state = 3; // Transition: q2 -> q3
else if (state == 3) state = 3; // Stay in q3
} else if (c == '0') {
if (state == 1 || state == 2) state = 0; // Transition: q1 or
q2 -> q0
else if (state == 3) state = 3; // Stay in q3
} else {
// Invalid input character
return false;
}
}
// Accept if final state is q3
return state == 3;
}
int main() {
string input;
cout << "Enter a binary string: ";
cin >> input;
if (simulateFA(input)) {
cout << "The string is accepted (contains '111')." << endl;
} else {
cout << "The string is rejected (does not contain '111')." <<
endl;
}
return 0;
}
OUTPUT:
Q2. Design a Finite Automata (FA) that accepts all strings over S={0,
1} having either exactly two 1's or exactly three 1's, not more nor less.
Write a program to simulate this FA.
#include <iostream>
#include <string>
using namespace std;
// Function to simulate the FA
bool simulateFA(const string& input) {
// Initial state
int state = 0;
for (char c : input) {
if (c == '1') {
if (state == 0) state = 1; // Transition: q0 -> q1
else if (state == 1) state = 2; // Transition: q1 -> q2
else if (state == 2) state = 3; // Transition: q2 -> q3
else if (state == 3) state = 4; // Transition: q3 -> q4
else if (state == 4) state = 4; // Stay in q4
} else if (c == '0') {
if (state == 0) state = 0; // Stay in q0
else if (state == 1) state = 1; // Stay in q1
else if (state == 2) state = 2; // Stay in q2
else if (state == 3) state = 3; // Stay in q3
else if (state == 4) state = 4; // Stay in q4
} else {
// Invalid input character
return false;
}
}
// Accept if final state is q2 or q3
return (state == 2 || state == 3);
}
int main() {
string input;
cout << "Enter a binary string: ";
cin >> input;
if (simulateFA(input)) {
cout << "The string is accepted (has exactly 2 or 3 ones)." <<
endl;
} else {
cout << "The string is rejected (does not meet the criteria)." <<
endl;
}
return 0;
}
OUTPUT:
Q3. Design a Finite Automata (FA) that accepts language L1, over
S={a, b}, comprising of all strings (of length 4 or more) having first
two characters same as the last two. Write a program to simulate this
FA.
#include <iostream>
#include <string>
using namespace std;
// Function to simulate the FA
bool simulateFA(const string& input) {
if (input.length() < 4) {
return false; // String is too short to be in the language
}
// Extract the first two and last two characters
char first1 = input[0];
char first2 = input[1];
char last1 = input[input.length() - 2];
char last2 = input[input.length() - 1];
// Check if the first two characters are the same as the last two
return (first1 == last1 && first2 == last2);
}
int main() {
string input;
cout << "Enter a string over {a, b}: ";
cin >> input;
if (simulateFA(input)) {
cout << "The string is accepted (belongs to L1)." << endl;
} else {
cout << "The string is rejected (does not belong to L1)." << endl;
}
return 0;
}
OUTPUT:
Q4. Design a Finite Automata (FA) that accepts language L2, over S=
{a, b} where L2= a(a+b)*b. Write a program to simulate this FA.
#include <iostream>
#include <string>
using namespace std;
// Function to simulate the FA
bool simulateFA(const string& input) {
int n = input.length();
// The string must be at least 2 characters (start with 'a' and end
with 'b')
if (n < 2) {
return false;
}
// Check the first character
if (input[0] != 'a') {
return false; // Must start with 'a'
}
// Check the last character
if (input[n - 1] != 'b') {
return false; // Must end with 'b'
}
// Intermediate characters can be any combination of 'a' and 'b'
for (int i = 1; i < n - 1; ++i) {
if (input[i] != 'a' && input[i] != 'b') {
return false; // Invalid character
}
}
return true; // If all checks pass, the string is accepted
}
int main() {
string input;
cout << "Enter a string over {a, b}: ";
cin >> input;
if (simulateFA(input)) {
cout << "The string is accepted (belongs to L2)." << endl;
} else {
cout << "The string is rejected (does not belong to L2)." << endl;
}
return 0;
}
OUTPUT:
Q5. Design a Finite Automata (FA) that accepts language EVEN-EVEN
over S={a, b}. Write a program to simulate this FA.
#include <iostream>
#include <string>
using namespace std;
// Function to simulate the FA
bool simulateFA(const string& input) {
// Initial state: q00 (even `a`s and even `b`s)
string state = "q00";
// Process the input string
for (char c : input) {
if (c == 'a') {
if (state == "q00") state = "q10";
else if (state == "q01") state = "q11";
else if (state == "q10") state = "q00";
else if (state == "q11") state = "q01";
} else if (c == 'b') {
if (state == "q00") state = "q01";
else if (state == "q01") state = "q00";
else if (state == "q10") state = "q11";
else if (state == "q11") state = "q10";
} else {
// Invalid character
return false;
// Accept if we end in q00
return state == "q00";
int main() {
string input;
cout << "Enter a string over {a, b}: ";
cin >> input;
if (simulateFA(input)) {
cout << "The string is accepted (belongs to EVEN-EVEN)." << endl;
} else {
cout << "The string is rejected (does not belong to EVEN-EVEN)."
<< endl;
return 0;
}
OUTPUT:
Q6. Write a program to simulate an FA that accepts a. Union of the
languages L1 and L2 b. Intersection of the languages L1 and L2 c.
Language L1 L2 (concatenation).
#include <iostream>
#include <string>
using namespace std;
bool isL1(const string& w) {
// Language L1: First two characters are the same as last two
if (w.length() < 4) return false;
string prefix = w.substr(0, 2);
string suffix = w.substr(w.length() - 2, 2);
return prefix == suffix;
}
bool isL2(const string& w) {
// Language L2: Starts with 'a' and ends with 'b'
return w.length() >= 2 && w[0] == 'a' && w[w.length() - 1] == 'b';
}
bool unionOperation(const string& w) {
// Union of L1 and L2
return isL1(w) || isL2(w);
}
bool intersectionOperation(const string& w) {
// Intersection of L1 and L2
return isL1(w) && isL2(w);
}
bool concatenationOperation(const string& w) {
// Concatenation of L1 and L2: We check if the first part satisfies L1
and the second part satisfies L2
for (size_t i = 1; i < w.length(); ++i) {
string firstPart = w.substr(0, i);
string secondPart = w.substr(i);
if (isL1(firstPart) && isL2(secondPart)) {
return true;
}
}
return false;
}
int main() {
int choice;
string inputString;
do {
cout << "Menu:\n";
cout << "1. Check Union of L1 and L2\n";
cout << "2. Check Intersection of L1 and L2\n";
cout << "3. Check Concatenation of L1 and L2\n";
cout << "4. Exit\n";
cout << "Enter your choice: ";
cin >> choice;
if (choice == 4) break;
cout << "Enter a binary string: ";
cin >> inputString;
bool result = false;
switch (choice) {
case 1:
result = unionOperation(inputString);
if (result) cout << "String is accepted by Union of L1 and
L2\n";
else cout << "String is rejected by Union of L1 and L2\n";
break;
case 2:
result = intersectionOperation(inputString);
if (result) cout << "String is accepted by Intersection of
L1 and L2\n";
else cout << "String is rejected by Intersection of L1 and
L2\n";
break;
case 3:
result = concatenationOperation(inputString);
if (result) cout << "String is accepted by Concatenation
of L1 and L2\n";
else cout << "String is rejected by Concatenation of L1
and L2\n";
break;
default:
cout << "Invalid choice. Please try again.\n";
}
} while (true);
return 0;
}
OUTPUT:
Q7. Design a PDA and write a program for simulating the machine
which accepts the language {anbn where n>0, S= {a, b}}.
#include <iostream>
#include <stack>
#include <string>
using namespace std;
// Function to simulate the PDA
bool simulatePDA(const string& input) {
stack<char> pdaStack; // Stack for the PDA
pdaStack.push('Z'); // Initial stack symbol
int i = 0;
int length = input.length();
// State: q0 (processing a's)
while (i < length && input[i] == 'a') {
pdaStack.push('X'); // Push X for each 'a'
i++;
}
// State: q1 (processing b's)
while (i < length && input[i] == 'b') {
if (!pdaStack.empty() && pdaStack.top() == 'X') {
pdaStack.pop(); // Pop X for each 'b'
} else {
return false; // Mismatch in number of 'a's and 'b's
}
i++;
}
// Accept state: qf
// Check if the stack contains only the initial symbol Z and all input
is processed
return (i == length && !pdaStack.empty() && pdaStack.top() == 'Z');
}
int main() {
string input;
cout << "Enter a string over {a, b}: ";
cin >> input;
if (simulatePDA(input)) {
cout << "The string is accepted by the PDA (belongs to the
language {a^n b^n | n > 0})." << endl;
} else {
cout << "The string is rejected by the PDA (does not belong to the
language)." << endl;
}
return 0;
}
OUTPUT:
Q8. Design a PDA and write a program for simulating the machine
which accepts the language {wXwr| w is any string over S={a, b} and
wr is reverse of that string and X is a special symbol }.
#include <iostream>
#include <stack>
#include <string>
using namespace std;
// Function to simulate the PDA
bool simulatePDA(const string& input) {
stack<char> pdaStack; // Stack for the PDA
pdaStack.push('Z'); // Initial stack symbol
int i = 0;
int length = input.length();
// Step 1: Push characters of w onto the stack (state q0)
while (i < length && input[i] != 'X') {
pdaStack.push(input[i]); // Push each character of w
i++;
}
// Check if X is present
if (i == length || input[i] != 'X') {
return false; // No separator X found
}
i++; // Move past X
// Step 2: Match characters with reverse w by popping the stack (state
q1)
while (i < length) {
if (pdaStack.empty() || pdaStack.top() == 'Z') {
return false; // Stack underflow or unmatched characters
}
if (input[i] != pdaStack.top()) {
return false; // Mismatch
}
pdaStack.pop(); // Pop matching character
i++;
}
// Step 3: Check if stack contains only the initial symbol Z (state
qf)
return (!pdaStack.empty() && pdaStack.top() == 'Z');
}
int main() {
string input;
cout << "Enter a string over {a, b, X}: ";
cin >> input;
if (simulatePDA(input)) {
cout << "The string is accepted by the PDA (belongs to the
language {wXw^r})." << endl;
} else {
cout << "The string is rejected by the PDA (does not belong to the
language)." << endl;
}
return 0;
}
OUTPUT:
Q9. Design and simulate a Turing Machine that accepts the language
anbncn where n >0.
#include <iostream>
#include <string>
#include <vector>
using namespace std; // Added to avoid std:: prefix
class TuringMachine {
private:
string tape;
int head_position;
enum State {
Q0, Q1, Q2, Q3, ACCEPT, REJECT
};
void move_head(int direction) {
head_position += direction;
if (head_position < 0) {
tape = '_' + tape;
head_position = 0;
}
if (head_position >= tape.length()) {
tape += '_';
}
}
public:
TuringMachine(const string& input) :
tape(input), head_position(0) {}
bool simulate() {
State current_state = Q0;
while (true) {
char current_symbol = tape[head_position];
switch (current_state) {
case Q0:
if (current_symbol == 'a') {
tape[head_position] = 'X';
move_head(1);
current_state = Q1;
} else {
current_state = REJECT;
}
break;
case Q1:
if (current_symbol == 'a') {
tape[head_position] = 'X';
move_head(1);
}
else if (current_symbol == 'b') {
tape[head_position] = 'Y';
move_head(1);
current_state = Q2;
}
else {
current_state = REJECT;
}
break;
case Q2:
if (current_symbol == 'b') {
tape[head_position] = 'Y';
move_head(1);
}
else if (current_symbol == 'c') {
tape[head_position] = 'Z';
move_head(1);
current_state = Q3;
}
else {
current_state = REJECT;
}
break;
case Q3:
if (current_symbol == 'c') {
tape[head_position] = 'Z';
move_head(1);
}
else if (current_symbol == '_') {
current_state = ACCEPT;
}
else {
current_state = REJECT;
}
break;
case ACCEPT:
return true;
case REJECT:
return false;
}
}
}
static bool validate_input(const string& input) {
// Simple symbol validation
for (size_t i = 0; i < input.length(); ++i) {
if (input[i] != 'a' && input[i] != 'b' && input[i] != 'c') {
return false;
}
}
// Count symbols
size_t a_count = 0, b_count = 0, c_count = 0;
for (size_t i = 0; i < input.length(); ++i) {
if (input[i] == 'a') a_count++;
else if (input[i] == 'b') b_count++;
else if (input[i] == 'c') c_count++;
}
// Ensure the counts of a, b, and c are the same
return a_count == b_count && b_count == c_count && a_count > 0;
}
};
int main() {
int choice;
string input;
while (true) {
// Display the menu
cout << "Menu:\n";
cout << "1. Enter Input String\n";
cout << "2. Exit\n";
cout << "Enter your choice: ";
cin >> choice;
if (choice == 1) {
cout << "Enter input string: ";
cin >> input;
if (!TuringMachine::validate_input(input)) {
cout << input << ": Rejected\n"; // Reject invalid
strings
} else {
TuringMachine tm(input);
bool result = tm.simulate();
cout << input << ": " << (result ? "Accepted" :
"Rejected") << endl;
}
}
else if (choice == 2) {
cout << "Exiting the program.\n";
break; // Exit the loop and terminate the program
}
else {
cout << "Invalid Choice. Please try again.\n"; // Invalid
choice
}
}
return 0;
}
OUTPUT:
Q10. Design and simulate a Turing Machine which will increment the
given binary number by 1.
#include <iostream>
#include <vector>
#include <string>
using namespace std;
// Function to simulate the Turing Machine for binary increment
string incrementBinary(string binaryNumber) {
// Add a blank space (denoted as '_') to both ends of the tape
string tape = "_" + binaryNumber + "_";
int head = tape.size() - 2; // Start at the last digit of the binary
number
char state = 'A'; // Initial state
while (state != 'H') { // Continue until the Halt state is reached
if (state == 'A') {
if (tape[head] == '1') {
tape[head] = '0'; // Change 1 to 0
head--; // Move left
} else if (tape[head] == '0') {
tape[head] = '1'; // Change 0 to 1
state = 'H'; // Halt the machine
} else if (tape[head] == '_') {
tape[head] = '1'; // Handle carry by adding 1
state = 'H'; // Halt the machine
}
}
}
// Remove leading and trailing blanks from the tape
tape.erase(0, tape.find_first_not_of('_'));
tape.erase(tape.find_last_not_of('_') + 1);
return tape;
}
int main() {
string binaryNumber;
cout << "Enter a binary number: ";
cin >> binaryNumber;
string incrementedNumber = incrementBinary(binaryNumber);
cout << "Incremented binary number: " << incrementedNumber << endl;
return 0;
}
OUTPUT: