diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 00000000..ac7ba862 Binary files /dev/null and b/.DS_Store differ diff --git a/.github/workflows/environment.yml b/.github/workflows/environment.yml new file mode 100644 index 00000000..e8f5b84b --- /dev/null +++ b/.github/workflows/environment.yml @@ -0,0 +1,8 @@ +name: base +channels: + - defaults +dependencies: + - python=3.10 + - pip + - flake8 + - pytest diff --git a/C++ Code/bellman_ford.cpp b/C++ Code/bellman_ford.cpp new file mode 100644 index 00000000..8573672e --- /dev/null +++ b/C++ Code/bellman_ford.cpp @@ -0,0 +1,41 @@ +#include +using namespace std; + +struct Edge { + int u, v, w; +}; + +void bellmanFord(int n, int start, vector& edges) { + vector dist(n, INT_MAX); + dist[start] = 0; + + for (int i = 0; i < n - 1; i++) { + for (auto& e : edges) { + if (dist[e.u] != INT_MAX && dist[e.u] + e.w < dist[e.v]) { + dist[e.v] = dist[e.u] + e.w; + } + } + } + + for (auto& e : edges) { + if (dist[e.u] != INT_MAX && dist[e.u] + e.w < dist[e.v]) { + cout << "Negative weight cycle detected!\n"; + return; + } + } + + cout << "Bellman-Ford Shortest Distances:\n"; + for (int i = 0; i < n; i++) + cout << "Node " << i << ": " << dist[i] << endl; +} + +int main() { + int n = 5; + vector edges = { + {0, 1, -1}, {0, 2, 4}, {1, 2, 3}, {1, 3, 2}, + {1, 4, 2}, {3, 2, 5}, {3, 1, 1}, {4, 3, -3} + }; + + bellmanFord(n, 0, edges); + return 0; +} diff --git a/C++ Code/bfs.cpp b/C++ Code/bfs.cpp new file mode 100644 index 00000000..8abea81f --- /dev/null +++ b/C++ Code/bfs.cpp @@ -0,0 +1,36 @@ +#include +using namespace std; + +void BFS(int start, vector>& adj) { + int n = adj.size(); + vector visited(n, false); + queue q; + + visited[start] = true; + q.push(start); + + cout << "BFS Traversal: "; + while (!q.empty()) { + int node = q.front(); + q.pop(); + cout << node << " "; + + for (int neighbor : adj[node]) { + if (!visited[neighbor]) { + visited[neighbor] = true; + q.push(neighbor); + } + } + } + cout << endl; +} + +int main() { + int n = 5; + vector> adj = { + {1, 2}, {0, 3, 4}, {0, 4}, {1}, {1, 2} + }; + + BFS(0, adj); + return 0; +} diff --git a/C++ Code/dfs.cpp b/C++ Code/dfs.cpp new file mode 100644 index 00000000..80818f3e --- /dev/null +++ b/C++ Code/dfs.cpp @@ -0,0 +1,30 @@ +#include +using namespace std; + +void DFSUtil(int node, vector>& adj, vector& visited) { + visited[node] = true; + cout << node << " "; + + for (int neighbor : adj[node]) { + if (!visited[neighbor]) + DFSUtil(neighbor, adj, visited); + } +} + +void DFS(int start, vector>& adj) { + int n = adj.size(); + vector visited(n, false); + cout << "DFS Traversal: "; + DFSUtil(start, adj, visited); + cout << endl; +} + +int main() { + int n = 5; + vector> adj = { + {1, 2}, {0, 3, 4}, {0, 4}, {1}, {1, 2} + }; + + DFS(0, adj); + return 0; +} diff --git a/C++ Code/dijkstra.cpp b/C++ Code/dijkstra.cpp new file mode 100644 index 00000000..b83052b8 --- /dev/null +++ b/C++ Code/dijkstra.cpp @@ -0,0 +1,47 @@ +#include +using namespace std; + +void dijkstra(int start, vector>>& adj) { + int n = adj.size(); + vector dist(n, INT_MAX); + dist[start] = 0; + + priority_queue, vector>, greater<>> pq; + pq.push({0, start}); + + while (!pq.empty()) { + int d = pq.top().first; + int node = pq.top().second; + pq.pop(); + + if (d > dist[node]) continue; + + for (auto& edge : adj[node]) { + int next = edge.first; + int weight = edge.second; + + if (dist[node] + weight < dist[next]) { + dist[next] = dist[node] + weight; + pq.push({dist[next], next}); + } + } + } + + cout << "Dijkstra Shortest Distances:\n"; + for (int i = 0; i < n; i++) + cout << "Node " << i << ": " << dist[i] << endl; +} + +int main() { + int n = 5; + vector>> adj(n); + + adj[0] = {{1, 2}, {2, 4}}; + adj[1] = {{2, 1}, {3, 7}}; + adj[2] = {{4, 3}}; + adj[3] = {{4, 1}}; + adj[4] = {}; + + dijkstra(0, adj); + return 0; +} diff --git a/C++ Code/linkedlist.cpp b/C++ Code/linkedlist.cpp new file mode 100644 index 00000000..7d82c4b6 --- /dev/null +++ b/C++ Code/linkedlist.cpp @@ -0,0 +1,238 @@ +#include +using namespace std; + +class Node { +public: + int data; + Node *next; +}; + +class List { + Node *listptr, *temp; +public: + List() { + listptr = NULL; + temp = NULL; + } + + void create(); + void display(); + void insert_start(); + void insert_end(); + void insert_intermediate(); + void insert_after_element(); + void delete_start(); + void delete_end(); + void delete_intermediate(); + void delete_after_element(); + void reverse(); + void concat(List l2); + void merge(List l2); +}; + +void List::create() { + int x, n; + cout << "Enter how many nodes : "; + cin >> n; + for (int i = 0; i < n; i++) { + cout << "Enter value for node " << i << " : "; + cin >> x; + Node *newNode = new Node; + newNode->data = x; + newNode->next = NULL; + if (listptr == NULL) { + listptr = newNode; + temp = newNode; + } else { + temp->next = newNode; + temp = newNode; + } + } +} + +void List::display() { + temp = listptr; + while (temp != NULL) { + cout << temp->data << " -> "; + temp = temp->next; + } + cout << "NULL" << endl; +} + +void List::insert_start() { + Node *newnode = new Node; + int x; + cout << "Enter the value to insert at start: "; + cin >> x; + newnode->data = x; + newnode->next = listptr; + listptr = newnode; +} + +void List::insert_end() { + int x; + Node *newnode = new Node; + cout << "Enter value: "; + cin >> x; + newnode->data = x; + newnode->next = NULL; + if (listptr == NULL) { + listptr = newnode; + return; + } + temp = listptr; + while (temp->next != NULL) { + temp = temp->next; + } + temp->next = newnode; +} + +void List::insert_intermediate() { + int pos, x; + Node *newnode = new Node; + cout << "Enter position: "; + cin >> pos; + cout << "Enter value: "; + cin >> x; + newnode->data = x; //1 -> 2 -> 3 -> 4 -> NULL + temp = listptr; + for (int i = 1; i < pos - 1; i++) { + temp = temp->next; + } + newnode->next = temp->next; + temp->next = newnode; +} + +void List::insert_after_element() { + int key, x; + cout << "Enter element after which to insert: "; + cin >> key; + cout << "Enter value: "; + cin >> x; + Node *newnode = new Node; + newnode->data = x; + temp = listptr; + while (temp != NULL && temp->data != key) { + temp = temp->next; + } + if (temp != NULL) { + newnode->next = temp->next; + temp->next = newnode; + } +} + +void List::delete_start() { + temp = listptr; + listptr = listptr->next; + delete(temp); +} + +void List::delete_end() { + temp = listptr; + while (temp->next->next != NULL) { + temp = temp->next; + } + delete(temp->next); + temp->next = NULL; +} + +void List::delete_intermediate() { + int pos, i = 0; + Node *q; + temp = listptr; + cout << "Enter position: "; + cin >> pos; + while (i < pos - 1) { + temp = temp->next; + i++; + } + q = temp->next; + temp->next = q->next; + delete(q); +} + +void List::delete_after_element() { + int key; + Node *q; + cout << "Enter element after which to delete: "; + cin >> key; + temp = listptr; + while (temp != NULL && temp->data != key) { + temp = temp->next; + } + if (temp != NULL && temp->next != NULL) { + q = temp->next; + temp->next = q->next; + delete(q); + } +} + +void List::reverse() { + Node *prev = NULL, *curr = listptr, *next = NULL; + while (curr != NULL) { + next = curr->next; + curr->next = prev; + prev = curr; + curr = next; + } + listptr = prev; +} + +void List::concat(List l2) { + if (listptr == NULL) { + listptr = l2.listptr; + return; + } + temp = listptr; + while (temp->next != NULL) { + temp = temp->next; + } + temp->next = l2.listptr; +} + +void List::merge(List l2) { + // You can implement sorted merge if needed +} + +int main() { + int p = 1, ch; + List l1, l2; + while (p == 1) { + cout << "\nEnter Choice:\n"; + cout << "1) Create\n"; + cout << "2) Display\n"; + cout << "3) Insert at Start\n"; + cout << "4) Insert at End\n"; + cout << "5) Insert at Intermediate\n"; + cout << "6) Insert after Element\n"; + cout << "7) Delete Start\n"; + cout << "8) Delete End\n"; + cout << "9) Delete Intermediate\n"; + cout << "10) Delete after Element\n"; + cout << "11) Reverse\n"; + cout << "12) Concat\n"; + cout << "13) Merge\n"; + cout << "Enter your choice: "; + cin >> ch; + + switch (ch) { + case 1: l1.create(); break; + case 2: l1.display(); break; + case 3: l1.insert_start(); l1.display(); break; + case 4: l1.insert_end(); l1.display(); break; + case 5: l1.insert_intermediate(); l1.display(); break; + case 6: l1.insert_after_element(); l1.display(); break; + case 7: l1.delete_start(); l1.display(); break; + case 8: l1.delete_end(); l1.display(); break; + case 9: l1.delete_intermediate(); l1.display(); break; + case 10: l1.delete_after_element(); l1.display(); break; + case 11: l1.reverse(); l1.display(); break; + case 12: l2.create(); l1.concat(l2); l1.display(); break; + case 13: l2.create(); l1.merge(l2); l1.display(); break; + default: cout << "Invalid choice!\n"; + } + cout << "\nPress 1 to continue: "; + cin >> p; + } + return 0; +} diff --git a/C++/BmiCalculator.cpp b/C++/BmiCalculator.cpp new file mode 100644 index 00000000..12aa51b5 --- /dev/null +++ b/C++/BmiCalculator.cpp @@ -0,0 +1,26 @@ +#include +using namespace std; + +int main() { + float height, weight, bmi; + + cout << "Enter your height in meters: "; + cin >> height; + cout << "Enter your weight in kg: "; + cin >> weight; + + bmi = weight / (height * height); + + cout << "Your BMI is: " << bmi << endl; + + if (bmi < 18.5) + cout << "Category: Underweight" << endl; + else if (bmi < 24.9) + cout << "Category: Normal weight" << endl; + else if (bmi < 29.9) + cout << "Category: Overweight" << endl; + else + cout << "Category: Obese" << endl; + + return 0; +} diff --git a/C/Armstrong.c b/C/Armstrong.c new file mode 100644 index 00000000..66cac513 --- /dev/null +++ b/C/Armstrong.c @@ -0,0 +1,34 @@ +#include +#include + +int main() { + int num, originalNum, remainder, result = 0, n = 0; + + printf("Enter an integer: "); + scanf("%d", &num); + + originalNum = num; + + // Count number of digits + while (originalNum != 0) { + originalNum /= 10; + n++; + } + + originalNum = num; + + // Calculate sum of digits raised to the power n + while (originalNum != 0) { + remainder = originalNum % 10; + result += pow(remainder, n); + originalNum /= 10; + } + + // Check if Armstrong + if (result == num) + printf("✅ %d is an Armstrong number.\n", num); + else + printf("❌ %d is not an Armstrong number.\n", num); + + return 0; +} \ No newline at end of file diff --git a/C/Binary.c b/C/Binary.c new file mode 100644 index 00000000..f6489f17 --- /dev/null +++ b/C/Binary.c @@ -0,0 +1,35 @@ +#include + +int main() { + int arr[100], n, i, j, minIndex, temp; + + printf("Enter number of elements: "); + scanf("%d", &n); + + printf("Enter %d integers:\n", n); + for (i = 0; i < n; i++) { + scanf("%d", &arr[i]); + } + + // Selection Sort + for (i = 0; i < n - 1; i++) { + minIndex = i; + for (j = i + 1; j < n; j++) { + if (arr[j] < arr[minIndex]) { + minIndex = j; + } + } + // Swap the found minimum with the first element + temp = arr[i]; + arr[i] = arr[minIndex]; + arr[minIndex] = temp; + } + + printf("Sorted array in ascending order:\n"); + for (i = 0; i < n; i++) { + printf("%d ", arr[i]); + } + printf("\n"); + + return 0; +} \ No newline at end of file diff --git a/C/Bubble_Sort.c b/C/Bubble_Sort.c new file mode 100644 index 00000000..e1943d4d --- /dev/null +++ b/C/Bubble_Sort.c @@ -0,0 +1,33 @@ +#include + +int main() { + int arr[100], n, i, j, temp; + + printf("Enter number of elements: "); + scanf("%d", &n); + + printf("Enter %d integers:\n", n); + for (i = 0; i < n; i++) { + scanf("%d", &arr[i]); + } + + // Bubble Sort + for (i = 0; i < n - 1; i++) { + for (j = 0; j < n - i - 1; j++) { + if (arr[j] > arr[j + 1]) { + // Swap + temp = arr[j]; + arr[j] = arr[j + 1]; + arr[j + 1] = temp; + } + } + } + + printf("Sorted array in ascending order:\n"); + for (i = 0; i < n; i++) { + printf("%d ", arr[i]); + } + printf("\n"); + + return 0; +} \ No newline at end of file diff --git a/C/Calculator_with_Switch.c b/C/Calculator_with_Switch.c new file mode 100644 index 00000000..25f47a19 --- /dev/null +++ b/C/Calculator_with_Switch.c @@ -0,0 +1,40 @@ +#include + +int main() { + char operator; + double num1, num2, result; + + printf("Enter an operator (+, -, *, /): "); + scanf(" %c", &operator); // Note the space before %c to consume any leftover newline + + printf("Enter two numbers: "); + scanf("%lf %lf", &num1, &num2); + + switch (operator) { + case '+': + result = num1 + num2; + printf("Result: %.2lf\n", result); + break; + case '-': + result = num1 - num2; + printf("Result: %.2lf\n", result); + break; + case '*': + result = num1 * num2; + printf("Result: %.2lf\n", result); + break; + case '/': + if (num2 != 0) + result = num1 / num2; + else { + printf("Error: Division by zero!\n"); + return 1; + } + printf("Result: %.2lf\n", result); + break; + default: + printf("Invalid operator!\n"); + } + + return 0; +} \ No newline at end of file diff --git a/C/Insertion_Sort.c b/C/Insertion_Sort.c new file mode 100644 index 00000000..31f49cea --- /dev/null +++ b/C/Insertion_Sort.c @@ -0,0 +1,34 @@ +#include + +int main() { + int arr[100], n, i, j, key; + + printf("Enter number of elements: "); + scanf("%d", &n); + + printf("Enter %d integers:\n", n); + for (i = 0; i < n; i++) { + scanf("%d", &arr[i]); + } + + // Insertion Sort + for (i = 1; i < n; i++) { + key = arr[i]; + j = i - 1; + + // Move elements greater than key one position ahead + while (j >= 0 && arr[j] > key) { + arr[j + 1] = arr[j]; + j--; + } + arr[j + 1] = key; + } + + printf("Sorted array in ascending order:\n"); + for (i = 0; i < n; i++) { + printf("%d ", arr[i]); + } + printf("\n"); + + return 0; +} \ No newline at end of file diff --git a/C/Linear_Search.c b/C/Linear_Search.c new file mode 100644 index 00000000..6bf27b08 --- /dev/null +++ b/C/Linear_Search.c @@ -0,0 +1,30 @@ +#include + +int main() { + int arr[100], n, target, i, found = 0; + + printf("Enter number of elements: "); + scanf("%d", &n); + + printf("Enter %d integers:\n", n); + for (i = 0; i < n; i++) { + scanf("%d", &arr[i]); + } + + printf("Enter the number to search: "); + scanf("%d", &target); + + for (i = 0; i < n; i++) { + if (arr[i] == target) { + found = 1; + printf("✅ %d found at index %d.\n", target, i); + break; + } + } + + if (!found) { + printf("❌ %d not found in the array.\n", target); + } + + return 0; +} \ No newline at end of file diff --git a/C/Merge_Sort.c b/C/Merge_Sort.c new file mode 100644 index 00000000..94694188 --- /dev/null +++ b/C/Merge_Sort.c @@ -0,0 +1,67 @@ +#include + +void merge(int arr[], int left, int mid, int right) { + int i, j, k; + int n1 = mid - left + 1; + int n2 = right - mid; + + // Create temporary arrays + int L[n1], R[n2]; + + // Copy data to temp arrays + for (i = 0; i < n1; i++) + L[i] = arr[left + i]; + for (j = 0; j < n2; j++) + R[j] = arr[mid + 1 + j]; + + // Merge the temp arrays back into arr[left..right] + i = 0; j = 0; k = left; + while (i < n1 && j < n2) { + if (L[i] <= R[j]) { + arr[k++] = L[i++]; + } else { + arr[k++] = R[j++]; + } + } + + // Copy remaining elements + while (i < n1) + arr[k++] = L[i++]; + while (j < n2) + arr[k++] = R[j++]; +} + +void mergeSort(int arr[], int left, int right) { + if (left < right) { + int mid = left + (right - left) / 2; + + // Sort first and second halves + mergeSort(arr, left, mid); + mergeSort(arr, mid + 1, right); + + // Merge the sorted halves + merge(arr, left, mid, right); + } +} + +int main() { + int arr[100], n; + + printf("Enter number of elements: "); + scanf("%d", &n); + + printf("Enter %d integers:\n", n); + for (int i = 0; i < n; i++) { + scanf("%d", &arr[i]); + } + + mergeSort(arr, 0, n - 1); + + printf("Sorted array:\n"); + for (int i = 0; i < n; i++) { + printf("%d ", arr[i]); + } + printf("\n"); + + return 0; +} \ No newline at end of file diff --git a/C/Palindrome.c b/C/Palindrome.c new file mode 100644 index 00000000..c037f423 --- /dev/null +++ b/C/Palindrome.c @@ -0,0 +1,34 @@ +#include +#include + +int main() { + char str[100], reversed[100]; + int length, i, isPalindrome = 1; + + printf("Enter a word: "); + scanf("%s", str); // Reads a single word (no spaces) + + length = strlen(str); + + // Reverse the string + for (i = 0; i < length; i++) { + reversed[i] = str[length - i - 1]; + } + reversed[length] = '\0'; // Null-terminate the reversed string + + // Compare original and reversed + for (i = 0; i < length; i++) { + if (str[i] != reversed[i]) { + isPalindrome = 0; + break; + } + } + + if (isPalindrome) { + printf("✅ It's a palindrome!\n"); + } else { + printf("❌ Not a palindrome.\n"); + } + + return 0; +} \ No newline at end of file diff --git a/C/Prime_Number_Generator.c b/C/Prime_Number_Generator.c new file mode 100644 index 00000000..ac413860 --- /dev/null +++ b/C/Prime_Number_Generator.c @@ -0,0 +1,27 @@ +#include + +int isPrime(int num) { + if (num <= 1) return 0; + for (int i = 2; i * i <= num; i++) { + if (num % i == 0) + return 0; + } + return 1; +} + +int main() { + int limit; + + printf("Enter the upper limit: "); + scanf("%d", &limit); + + printf("Prime numbers up to %d are:\n", limit); + for (int i = 2; i <= limit; i++) { + if (isPrime(i)) { + printf("%d ", i); + } + } + printf("\n"); + + return 0; +} \ No newline at end of file diff --git a/C/Reverse_Number.c b/C/Reverse_Number.c new file mode 100644 index 00000000..b8523e60 --- /dev/null +++ b/C/Reverse_Number.c @@ -0,0 +1,18 @@ +#include + +int main() { + int num, reversed = 0; + + printf("Enter a number: "); + scanf("%d", &num); + + while (num != 0) { + int digit = num % 10; // Get last digit + reversed = reversed * 10 + digit; // Append digit + num /= 10; // Remove last digit + } + + printf("Reversed number: %d\n", reversed); + + return 0; +} \ No newline at end of file diff --git a/C/Selection_Sort.c b/C/Selection_Sort.c new file mode 100644 index 00000000..f6489f17 --- /dev/null +++ b/C/Selection_Sort.c @@ -0,0 +1,35 @@ +#include + +int main() { + int arr[100], n, i, j, minIndex, temp; + + printf("Enter number of elements: "); + scanf("%d", &n); + + printf("Enter %d integers:\n", n); + for (i = 0; i < n; i++) { + scanf("%d", &arr[i]); + } + + // Selection Sort + for (i = 0; i < n - 1; i++) { + minIndex = i; + for (j = i + 1; j < n; j++) { + if (arr[j] < arr[minIndex]) { + minIndex = j; + } + } + // Swap the found minimum with the first element + temp = arr[i]; + arr[i] = arr[minIndex]; + arr[minIndex] = temp; + } + + printf("Sorted array in ascending order:\n"); + for (i = 0; i < n; i++) { + printf("%d ", arr[i]); + } + printf("\n"); + + return 0; +} \ No newline at end of file diff --git a/C/Swap1.c b/C/Swap1.c new file mode 100644 index 00000000..42aaf6f7 --- /dev/null +++ b/C/Swap1.c @@ -0,0 +1,18 @@ +#include + +int main() { + int a, b, temp; + + printf("Enter two numbers:\n"); + scanf("%d %d", &a, &b); + + printf("Before swapping: a = %d, b = %d\n", a, b); + + temp = a; + a = b; + b = temp; + + printf("After swapping (with temp): a = %d, b = %d\n", a, b); + + return 0; +} \ No newline at end of file diff --git a/C/Swap2.c b/C/Swap2.c new file mode 100644 index 00000000..026da6a4 --- /dev/null +++ b/C/Swap2.c @@ -0,0 +1,18 @@ +#include + +int main() { + int a, b; + + printf("Enter two numbers:\n"); + scanf("%d %d", &a, &b); + + printf("Before swapping: a = %d, b = %d\n", a, b); + + a = a + b; + b = a - b; + a = a - b; + + printf("After swapping (without temp): a = %d, b = %d\n", a, b); + + return 0; +} \ No newline at end of file diff --git a/C/Tic-Tac-Toe Game.c b/C/Tic-Tac-Toe Game.c new file mode 100644 index 00000000..cb401954 --- /dev/null +++ b/C/Tic-Tac-Toe Game.c @@ -0,0 +1,83 @@ +#include + +char board[3][3]; +char currentPlayer = 'X'; + +void initializeBoard() { + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + board[i][j] = ' '; +} + +void printBoard() { + printf("\n"); + for (int i = 0; i < 3; i++) { + printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]); + if (i < 2) printf("---|---|---\n"); + } + printf("\n"); +} + +int checkWin() { + // Rows and columns + for (int i = 0; i < 3; i++) { + if ((board[i][0] == currentPlayer && board[i][1] == currentPlayer && board[i][2] == currentPlayer) || + (board[0][i] == currentPlayer && board[1][i] == currentPlayer && board[2][i] == currentPlayer)) + return 1; + } + // Diagonals + if ((board[0][0] == currentPlayer && board[1][1] == currentPlayer && board[2][2] == currentPlayer) || + (board[0][2] == currentPlayer && board[1][1] == currentPlayer && board[2][0] == currentPlayer)) + return 1; + + return 0; +} + +int isDraw() { + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + if (board[i][j] == ' ') + return 0; + return 1; +} + +void switchPlayer() { + currentPlayer = (currentPlayer == 'X') ? 'O' : 'X'; +} + +void playGame() { + int row, col; + initializeBoard(); + + while (1) { + printBoard(); + printf("Player %c, enter row and column (0-2): ", currentPlayer); + scanf("%d %d", &row, &col); + + if (row < 0 || row > 2 || col < 0 || col > 2 || board[row][col] != ' ') { + printf("Invalid move. Try again.\n"); + continue; + } + + board[row][col] = currentPlayer; + + if (checkWin()) { + printBoard(); + printf("🎉 Player %c wins!\n", currentPlayer); + break; + } + + if (isDraw()) { + printBoard(); + printf("🤝 It's a draw!\n"); + break; + } + + switchPlayer(); + } +} + +int main() { + playGame(); + return 0; +} \ No newline at end of file diff --git a/C/diningphilosopher.c b/C/diningphilosopher.c new file mode 100644 index 00000000..937c73a3 --- /dev/null +++ b/C/diningphilosopher.c @@ -0,0 +1,126 @@ +#include +#include +#include +#include +#include +#include + +#define N_PHIL 5 +#define MEALS_PER_PHIL 3 + +pthread_mutex_t forks[N_PHIL]; +sem_t waiter; +int meals_done[N_PHIL]; + +void rand_sleep_ms(int min_ms, int max_ms) { + int ms = min_ms + rand() % (max_ms - min_ms + 1); + usleep(ms * 1000); +} + +void *philosopher(void *arg) { + int id = *(int *)arg; + int left = id; + int right = (id + 1) % N_PHIL; + + for (int meal = 1; meal <= MEALS_PER_PHIL; ++meal) { + + printf("Philosopher %d is THINKING (meal %d/%d).\n", id, meal, MEALS_PER_PHIL); + fflush(stdout); + rand_sleep_ms(100, 600); + + + printf("Philosopher %d is HUNGRY and tries to get permission from waiter.\n", id); + fflush(stdout); + sem_wait(&waiter); // wait until it's safe to try picking forks + + + printf("Philosopher %d is trying to pick LEFT fork %d.\n", id, left); + fflush(stdout); + pthread_mutex_lock(&forks[left]); + printf("Philosopher %d picked LEFT fork %d.\n", id, left); + fflush(stdout); + + printf("Philosopher %d is trying to pick RIGHT fork %d.\n", id, right); + fflush(stdout); + pthread_mutex_lock(&forks[right]); + printf("Philosopher %d picked RIGHT fork %d.\n", id, right); + fflush(stdout); + + + printf("Philosopher %d is EATING (meal %d/%d).\n", id, meal, MEALS_PER_PHIL); + fflush(stdout); + rand_sleep_ms(150, 500); + meals_done[id]++; + + + pthread_mutex_unlock(&forks[right]); + printf("Philosopher %d put DOWN RIGHT fork %d.\n", id, right); + fflush(stdout); + + pthread_mutex_unlock(&forks[left]); + printf("Philosopher %d put DOWN LEFT fork %d.\n", id, left); + fflush(stdout); + + + sem_post(&waiter); + printf("Philosopher %d informed waiter (finished meal %d).\n", id, meal); + fflush(stdout); + + + rand_sleep_ms(50, 200); + } + + printf("Philosopher %d is DONE (ate %d meals).\n", id, MEALS_PER_PHIL); + fflush(stdout); + return NULL; +} + +int main(int argc, char *argv[]) { + srand((unsigned int)time(NULL)); + + + pthread_t threads[N_PHIL]; + int ids[N_PHIL]; + + + for (int i = 0; i < N_PHIL; ++i) { + if (pthread_mutex_init(&forks[i], NULL) != 0) { + perror("pthread_mutex_init"); + exit(EXIT_FAILURE); + } + meals_done[i] = 0; + } + + + if (sem_init(&waiter, 0, N_PHIL - 1) != 0) { + perror("sem_init"); + exit(EXIT_FAILURE); + } + + + for (int i = 0; i < N_PHIL; ++i) { + ids[i] = i; + if (pthread_create(&threads[i], NULL, philosopher, &ids[i]) != 0) { + perror("pthread_create"); + exit(EXIT_FAILURE); + } + } + + + for (int i = 0; i < N_PHIL; ++i) { + pthread_join(threads[i], NULL); + } + + + for (int i = 0; i < N_PHIL; ++i) { + pthread_mutex_destroy(&forks[i]); + } + sem_destroy(&waiter); + + printf("\nAll philosophers finished. Meals eaten by each:\n"); + for (int i = 0; i < N_PHIL; ++i) { + printf("Philosopher %d: %d meals\n", i, meals_done[i]); + } + + return 0; +} diff --git a/C/factorial_recursion.c b/C/factorial_recursion.c new file mode 100644 index 00000000..e69de29b diff --git a/C/leap_year.c b/C/leap_year.c new file mode 100644 index 00000000..e69de29b diff --git a/Python/Detect cycle in an undirected graph.py b/Python/Detect cycle in an undirected graph.py new file mode 100644 index 00000000..881a0a3e --- /dev/null +++ b/Python/Detect cycle in an undirected graph.py @@ -0,0 +1,24 @@ +def isCyclic(n, edges): + adj = [[] for i in range(n)] + for u,v in edges: + adj[u].append(v) + adj[v].append(u) + + visited=[0]*n + + def dfs(node,parent): + visited[node] = 1 + for i in adj[node]: + if not visited[i]: + if dfs(i,node) == True: + return True + + elif i!=parent: + return True + return False + + for i in range(n): + if not visited[i]: + if dfs(i, -1): + return True + return False \ No newline at end of file diff --git "a/Python/Dijkstra\342\200\231s.py" "b/Python/Dijkstra\342\200\231s.py" new file mode 100644 index 00000000..3c251775 --- /dev/null +++ "b/Python/Dijkstra\342\200\231s.py" @@ -0,0 +1,30 @@ +import heapq + +def dijkstra(n, graph, src): + """ + n -> number of vertices + graph -> adjacency list: {u: [(v, weight), (v2, weight2), ...]} + src -> source vertex + """ + # Step 1: Initialize distances to infinity + dist = [float('inf')] * n + dist[src] = 0 + + # Step 2: Min-heap to get vertex with smallest distance + pq = [(0, src)] # (distance, node) + + while pq: + curr_dist, u = heapq.heappop(pq) + + # Skip if we already found a shorter path + if curr_dist > dist[u]: + continue + + # Step 3: Explore neighbors + for v, weight in graph.get(u, []): + new_dist = curr_dist + weight + if new_dist < dist[v]: + dist[v] = new_dist + heapq.heappush(pq, (new_dist, v)) + + return dist diff --git a/Python/Fibonacci.py b/Python/Fibonacci.py new file mode 100644 index 00000000..e89d0f0b --- /dev/null +++ b/Python/Fibonacci.py @@ -0,0 +1,10 @@ +from functools import lru_cache + +@lru_cache(maxsize=None) +def fibonacci(n): + if n <= 1: + return n + return fibonacci(n - 1) + fibonacci(n - 2) + +# Example usage +print(fibonacci(10)) # Output: 55 diff --git a/Python/Gas_station.py b/Python/Gas_station.py new file mode 100644 index 00000000..59e9be79 --- /dev/null +++ b/Python/Gas_station.py @@ -0,0 +1,17 @@ +def canCompleteCircuit(gas, cost): + if sum(gas) < sum(cost): + return -1 + fuel = 0 + start_sta = -1 + for i in range(len(gas)): + fuel = fuel + gas[i] - cost[i] + if fuel < 0: + start_sta = i+1 + fuel = 0 + return start_sta if fuel >= 0 else -1 + +print(canCompleteCircuit([1,2,3,4,5], [3,4,5,1,2])) # Output: 3 +# The function canCompleteCircuit determines the starting gas station index +# from which a vehicle can complete a circular route given the gas available +# at each station and the cost to travel to the next station. If it's not possible +# to complete the circuit, it returns -1. \ No newline at end of file diff --git a/Python/Max_sum_non_adjacent_number.py b/Python/Max_sum_non_adjacent_number.py new file mode 100644 index 00000000..82510fcf --- /dev/null +++ b/Python/Max_sum_non_adjacent_number.py @@ -0,0 +1,16 @@ +def maxSum(n,nums): + dp=[0]*n + dp[0]=nums[0] + for i in range(1,n): + ans=nums[i] + if i>1: + ans+=dp[i-2] + notans=dp[i-1] + dp[i]=max(ans,notans) + return dp[-1] + +n=int(input()) +nums=list(map(int,input().split())) +print(maxSum(n,nums)) +# Function to find the maximum sum of non-adjacent numbers in a list +# using dynamic programming approach \ No newline at end of file diff --git a/Python/Maximum_collection.py b/Python/Maximum_collection.py new file mode 100644 index 00000000..f06a8cd2 --- /dev/null +++ b/Python/Maximum_collection.py @@ -0,0 +1,22 @@ +def max_coins(grid): + dp = {} + m = len(grid) + n = len(grid[0]) + ans = helper(m, n, grid, dp) + return ans + +def helper(m, n, grid, dp): + if m == 1 and n == 1: + return grid[0][0] + if m < 0 or n < 0: + return float('-inf') + if (m, n) in dp: + return dp[(m, n)] + dp[(m, n)] = grid[m - 1][n - 1] + max(helper(m - 1, n, grid, dp), helper(m, n - 1, grid, dp)) + return dp[(m, n)] + + +print(max_coins([[0, 3, 1, 1], [2, 0, 0, 4], [1, 0, 0, 0], [5, 0, 0, 0]])) # Output: 12 +# The function max_coins calculates the maximum number of coins that can be collected +# while moving from the top-left corner to the bottom-right corner of the grid. +# You can only move either down or right at any point in time. diff --git a/Python/Non_overlapping_intervals.py b/Python/Non_overlapping_intervals.py new file mode 100644 index 00000000..a4477d61 --- /dev/null +++ b/Python/Non_overlapping_intervals.py @@ -0,0 +1,20 @@ +def remove_overlapping(intervals): + overlaps = 0 + for i in intervals: + i[0], i[1] = i[1], i[0] + intervals.sort() + for i in intervals: + i[0], i[1] = i[1], i[0] + + prev = intervals[0] + for i in range(1, len(intervals)): + if prev[1] > intervals[i][0]: + overlaps += 1 + else: + prev = intervals[i] + return overlaps + +intervals = [[1,2],[2,3],[3,4],[1,3]] +print(remove_overlapping(intervals)) # Output: 1 +# Function to remove overlapping intervals +# and return the minimum number of intervals to remove \ No newline at end of file diff --git a/Python/Prim_Algorithm.py b/Python/Prim_Algorithm.py new file mode 100644 index 00000000..23c7c49e --- /dev/null +++ b/Python/Prim_Algorithm.py @@ -0,0 +1,34 @@ +import heapq +from collections import defaultdict + +def prim_mst(graph, start): + mst = [] + visited = set() + min_heap = [(0, start, None)] # (weight, current_node, parent) + + while min_heap: + weight, current, parent = heapq.heappop(min_heap) + if current in visited: + continue + visited.add(current) + if parent is not None: + mst.append((parent, current, weight)) + + for neighbor, edge_weight in graph[current]: + if neighbor not in visited: + heapq.heappush(min_heap, (edge_weight, neighbor, current)) + + return mst + +# Example graph as adjacency list +graph = { + 'A': [('B', 2), ('C', 3)], + 'B': [('A', 2), ('C', 1), ('D', 1)], + 'C': [('A', 3), ('B', 1), ('D', 4)], + 'D': [('B', 1), ('C', 4)] +} + +mst = prim_mst(graph, 'A') +print("Minimum Spanning Tree:") +for edge in mst: + print(f"{edge[0]} - {edge[1]} : {edge[2]}") \ No newline at end of file diff --git a/Python/Rock_paper_game.py b/Python/Rock_paper_game.py new file mode 100644 index 00000000..87fc6156 --- /dev/null +++ b/Python/Rock_paper_game.py @@ -0,0 +1,11 @@ +import random +choices = ["rock", "paper", "scissors"] +user = input("Choose rock/paper/scissors: ") +comp = random.choice(choices) +print("Computer chose:", comp) +if user == comp: + print("Draw") +elif (user == "rock" and comp == "scissors") or (user == "paper" and comp == "rock") or (user == "scissors" and comp == "paper"): + print("You win!") +else: + print("You lose!") diff --git a/Python/Rotting_oranges.py b/Python/Rotting_oranges.py new file mode 100644 index 00000000..64fd62e8 --- /dev/null +++ b/Python/Rotting_oranges.py @@ -0,0 +1,47 @@ +import collections + +def orangesRotting(grid): + if not grid or not grid[0]: + return 0 + + rows, cols = len(grid), len(grid[0]) + q = collections.deque() + fresh_oranges_count = 0 + + for r in range(rows): + for c in range(cols): + if grid[r][c] == 2: + q.append((r, c)) + elif grid[r][c] == 1: + fresh_oranges_count += 1 + + if fresh_oranges_count == 0: + return 0 + + minutes_passed = 0 + directions = [(1, 0), (-1, 0), (0, 1), (0, -1)] + + while q: + level_size = len(q) + + for _ in range(level_size): + r, c = q.popleft() + + for dr, dc in directions: + nr, nc = r + dr, c + dc + + if 0 <= nr < rows and 0 <= nc < cols and grid[nr][nc] == 1: + grid[nr][nc] = 2 + fresh_oranges_count -= 1 + q.append((nr, nc)) + if q: + minutes_passed += 1 + + return minutes_passed if fresh_oranges_count == 0 else -1 + +# Example usage: +grid = [[2,1,1],[1,1,0],[0,1,1]] +print(orangesRotting(grid)) # Output: 4 + +# The function orangesRotting takes a grid as input and returns the minimum number of minutes +# that must elapse until no cell has a fresh orange. If this is impossible, it returns -1. \ No newline at end of file diff --git a/Python/Russian_doll_envelopes.py b/Python/Russian_doll_envelopes.py new file mode 100644 index 00000000..1933c3e3 --- /dev/null +++ b/Python/Russian_doll_envelopes.py @@ -0,0 +1,18 @@ +import bisect + +def maxEnvelopes(envelopes): + # Step 1: Sort envelopes by width ASC, and height DESC for same width + envelopes.sort(key=lambda x: (x[0], -x[1])) + + # Step 2: Extract heights + heights = [h for _, h in envelopes] + + # Step 3: Find LIS using binary search (O(n log n)) + lis = [] + for h in heights: + idx = bisect.bisect_left(lis, h) + if idx == len(lis): + lis.append(h) + else: + lis[idx] = h + return len(lis) diff --git a/Python/calculator.py b/Python/calculator.py new file mode 100644 index 00000000..b27304e9 --- /dev/null +++ b/Python/calculator.py @@ -0,0 +1,52 @@ +def add(x, y): + return x + y + +def subtract(x, y): + return x - y + +def multiply(x, y): + return x * y + +def divide(x, y): + try: + return x / y + except ZeroDivisionError: + return "Error: Cannot divide by zero" + +def calculator(): + while True: + print("\nSimple Calculator") + print("1. Add") + print("2. Subtract") + print("3. Multiply") + print("4. Divide") + print("5. Exit") + + choice = input("Choose an operation (1-5): ") + + if choice == '5': + print("Goodbye!") + break + + if choice in ('1', '2', '3', '4'): + try: + num1 = float(input("Enter first number: ")) + num2 = float(input("Enter second number: ")) + except ValueError: + print("Invalid input. Please enter numeric values.") + continue + + if choice == '1': + result = add(num1, num2) + elif choice == '2': + result = subtract(num1, num2) + elif choice == '3': + result = multiply(num1, num2) + elif choice == '4': + result = divide(num1, num2) + + print("Result:", result) + else: + print("Invalid choice. Please select a valid option.") + +calculator() \ No newline at end of file diff --git a/Python/chatbot b/Python/chatbot new file mode 100644 index 00000000..5edfacd5 --- /dev/null +++ b/Python/chatbot @@ -0,0 +1,22 @@ +from chatterbot import ChatBot +import chatterbot + + +from chatterbot.trainers import ChatterBotCorpusTrainer + + + +chatbot=chatterbot('corona bot') + + +trainer = ChatterBotCorpusTrainer(chatbot) + + +trainer.train("chatterbot.corpus.english.greetings", + "chatterbot.corpus.english.conversations" ) + +response = chatbot.get_response('What is your Number') +print(response) + +response = chatbot.get_response('Who are you?') +print(response) diff --git a/Python/check_anagrams.py b/Python/check_anagrams.py new file mode 100644 index 00000000..85c26099 --- /dev/null +++ b/Python/check_anagrams.py @@ -0,0 +1,10 @@ +""" +Problem: +Two strings are anagrams if one is a rearrangement of the other. + +Example: +Input: "listen", "silent" → Output: True +""" + +def are_anagrams(s1, s2): + return sorted(s1) == sorted(s2) \ No newline at end of file diff --git a/Python/filetext_handling.py b/Python/filetext_handling.py new file mode 100644 index 00000000..41c35947 --- /dev/null +++ b/Python/filetext_handling.py @@ -0,0 +1,3 @@ +text = input("Enter text: ") +words = text.split() +print("Word count:", len(words)) diff --git a/Python/kahn's.py b/Python/kahn's.py new file mode 100644 index 00000000..4e950cc5 --- /dev/null +++ b/Python/kahn's.py @@ -0,0 +1,37 @@ +from collections import defaultdict, deque + +def kahn_topological_sort(n, edges): + """ + n -> number of vertices (0 to n-1) + edges -> list of directed edges (u -> v) + """ + + # Step 1: Build graph and compute in-degree + graph = defaultdict(list) + indegree = [0] * n + + for u, v in edges: + graph[u].append(v) + indegree[v] += 1 + + # Step 2: Initialize queue with all nodes having in-degree 0 + queue = deque([i for i in range(n) if indegree[i] == 0]) + topo_order = [] + + # Step 3: Process nodes in queue + while queue: + node = queue.popleft() + topo_order.append(node) + + # Decrease in-degree of neighbors + for neighbor in graph[node]: + indegree[neighbor] -= 1 + if indegree[neighbor] == 0: + queue.append(neighbor) + + # Step 4: Check for cycles + if len(topo_order) != n: + print("Graph contains a cycle, topological sort not possible.") + return [] + + return topo_order diff --git a/Python/knight_walk.py b/Python/knight_walk.py new file mode 100644 index 00000000..ac50eabb --- /dev/null +++ b/Python/knight_walk.py @@ -0,0 +1,27 @@ +from collections import deque + +def knightWalk(rows, cols, start_row, start_col, dest_row, dest_col): + moves = [ + (2, 1), (2, -1), (-2, 1), (-2, -1), + (1, 2), (1, -2), (-1, 2), (-1, -2) + ] + + visited = [[False] * cols for _ in range(rows)] + queue = deque([(start_row, start_col, 0)]) + visited[start_row][start_col] = True + + while queue: + current_row, current_col, distance = queue.popleft() + + if current_row == dest_row and current_col == dest_col: + return distance + + for dr, dc in moves: + new_row = current_row + dr + new_col = current_col + dc + + if 0 <= new_row < rows and 0 <= new_col < cols and not visited[new_row][new_col]: + visited[new_row][new_col] = True + queue.append((new_row, new_col, distance + 1)) + + return -1 \ No newline at end of file diff --git a/Python/leap_year.py b/Python/leap_year.py new file mode 100644 index 00000000..70233273 --- /dev/null +++ b/Python/leap_year.py @@ -0,0 +1,14 @@ +def is_leap_year(year): + # Leap year if divisible by 4 and not divisible by 100, + # unless also divisible by 400 + if (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0): + return True + else: + return False + +# Example usage +year = int(input("Enter a year: ")) +if is_leap_year(year): + print(f"{year} is a leap year.") +else: + print(f"{year} is not a leap year.") \ No newline at end of file diff --git a/Python/longest_biotonic_subsequences.py b/Python/longest_biotonic_subsequences.py new file mode 100644 index 00000000..0471b13b --- /dev/null +++ b/Python/longest_biotonic_subsequences.py @@ -0,0 +1,26 @@ +def lbs(nums): + n = len(nums) + if n < 3: + return 0 # A bitonic sequence needs at least 3 elements + + # Step 1: LIS from left to right + lis = [1] * n + for i in range(1, n): + for j in range(i): + if nums[i] > nums[j] and lis[i] < lis[j] + 1: + lis[i] = lis[j] + 1 + + # Step 2: LDS from right to left + lds = [1] * n + for i in range(n - 2, -1, -1): + for j in range(n - 1, i, -1): + if nums[i] > nums[j] and lds[i] < lds[j] + 1: + lds[i] = lds[j] + 1 + + # Step 3: Combine LIS + LDS - 1 + max_len = 0 + for i in range(n): + if lis[i] > 1 and lds[i] > 1: # must increase and decrease + max_len = max(max_len, lis[i] + lds[i] - 1) + + return max_len \ No newline at end of file diff --git a/Python/lowest_common_ancestor.py b/Python/lowest_common_ancestor.py new file mode 100644 index 00000000..e4038316 --- /dev/null +++ b/Python/lowest_common_ancestor.py @@ -0,0 +1,25 @@ +class Node: + def __init__(self, val, left=None, right=None): + self.val = val + self.left = left + self.right = right + +def LCA(root, n1, n2): + def exists(node, val): + if node is None: + return False + if node.val == val: + return True + return exists(node.left, val) if val < node.val else exists(node.right, val) + + if not exists(root, n1) or not exists(root, n2): + return Node(-1) + + current = root + while current: + if n1 < current.val and n2 < current.val: + current = current.left + elif n1 > current.val and n2 > current.val: + current = current.right + else: + return current \ No newline at end of file diff --git a/Python/missing_number.py b/Python/missing_number.py new file mode 100644 index 00000000..5963bcd4 --- /dev/null +++ b/Python/missing_number.py @@ -0,0 +1,11 @@ +""" +Problem: +Given an array containing n distinct numbers from 0 to n, find the missing number. + +Example: +Input: [3, 0, 1] → Output: 2 +""" +def missing_number(nums): + n = len(nums) + total = n * (n + 1) // 2 + return total - sum(nums) \ No newline at end of file diff --git a/Python/n-queens.py b/Python/n-queens.py new file mode 100644 index 00000000..af850a26 --- /dev/null +++ b/Python/n-queens.py @@ -0,0 +1,33 @@ +def solveNQueens(board_size): + chessboard = [["."] * board_size for _ in range(board_size)] + all_solutions = [] + occupied_columns = set() + occupied_major_diagonals = set() + occupied_minor_diagonals = set() + + def place_queens(current_row): + if current_row == board_size: + formatted_solution = ["".join(row) for row in chessboard] + all_solutions.append(formatted_solution) + return + + for current_column in range(board_size): + if (current_column in occupied_columns or + (current_row - current_column) in occupied_major_diagonals or + (current_row + current_column) in occupied_minor_diagonals): + continue + + chessboard[current_row][current_column] = "Q" + occupied_columns.add(current_column) + occupied_major_diagonals.add(current_row - current_column) + occupied_minor_diagonals.add(current_row + current_column) + + place_queens(current_row + 1) + + chessboard[current_row][current_column] = "." + occupied_columns.remove(current_column) + occupied_major_diagonals.remove(current_row - current_column) + occupied_minor_diagonals.remove(current_row + current_column) + + place_queens(0) + return all_solutions diff --git a/Python/no_game.py b/Python/no_game.py new file mode 100644 index 00000000..ea7f759a --- /dev/null +++ b/Python/no_game.py @@ -0,0 +1,25 @@ +import random + +def number_guessing_game(): + print("🎯 Welcome to the Number Guessing Game!") + print("I'm thinking of a number between 1 and 100.") + + number_to_guess = random.randint(1, 100) + attempts = 0 + + while True: + try: + guess = int(input("Enter your guess: ")) + attempts += 1 + + if guess < number_to_guess: + print("Too low! Try again.") + elif guess > number_to_guess: + print("Too high! Try again.") + else: + print(f"🎉 Congratulations! You guessed it in {attempts} attempts.") + break + except ValueError: + print("Please enter a valid number.") + +number_guessing_game() \ No newline at end of file diff --git a/Python/number_of_enclaves.py b/Python/number_of_enclaves.py new file mode 100644 index 00000000..443fd028 --- /dev/null +++ b/Python/number_of_enclaves.py @@ -0,0 +1,55 @@ +""" +You are given an n x m binary matrix grid, where 0 represents a sea cell and 1 represents a land cell. + +A move consists of walking from one land cell to another adjacent (4- directionally) land cell or walking off the boundary of the grid. + +Return the number of land cells in grid for which we cannot walk off the boundary of the grid in any number of moves. + +Example +Input: +4 4 +0 0 0 0 +1 0 1 0 +0 1 1 0 +0 0 0 0 +Output: +3 +""" + + +def numEnclaves(grid): + assert grid and grid[0], "Grid must not be empty" + rows, cols = len(grid), len(grid[0]) + assert 1 <= rows <= 10**4 and 1 <= cols <= 10**4 and rows * cols <= 10**4, "Grid dimensions out of bounds" + for row in grid: + assert len(row) == cols, "Grid must be rectangular" + for cell in row: + assert cell in (0, 1), "Grid values must be 0 or 1" + + directions = [(0, 1), (1, 0), (0, -1), (-1, 0)] + + def dfs(x, y): + if x < 0 or x >= rows or y < 0 or y >= cols or grid[x][y] == 0: + return + grid[x][y] = 0 + for dx, dy in directions: + dfs(x + dx, y + dy) + + for i in range(rows): + if grid[i][0] == 1: + dfs(i, 0) + if grid[i][cols - 1] == 1: + dfs(i, cols - 1) + + for j in range(cols): + if grid[0][j] == 1: + dfs(0, j) + if grid[rows - 1][j] == 1: + dfs(rows - 1, j) + + count = 0 + for i in range(rows): + for j in range(cols): + if grid[i][j] == 1: + count += 1 + return count diff --git a/Python/palindorme.py b/Python/palindorme.py new file mode 100644 index 00000000..fe7066e8 --- /dev/null +++ b/Python/palindorme.py @@ -0,0 +1,5 @@ +num = int(input("Enter a number: ")) +if str(num) == str(num)[::-1]: + print("Palindrome") +else: + print("Not Palindrome") diff --git a/Python/palindrome_tools.py b/Python/palindrome_tools.py new file mode 100644 index 00000000..b8adbeb1 --- /dev/null +++ b/Python/palindrome_tools.py @@ -0,0 +1,103 @@ +""" +Palindrome utilities with a simple CLI. + +Functions: +- is_palindrome(text: str, ignore_case: bool = True, ignore_non_alnum: bool = True) -> bool +- longest_palindromic_substring(text: str) -> str + +Run this file directly to access a small CLI for quick checks. +""" + +from typing import Tuple + + +def _normalize(text: str, ignore_case: bool, ignore_non_alnum: bool) -> str: + if ignore_case: + text = text.lower() + if ignore_non_alnum: + text = "".join(ch for ch in text if ch.isalnum()) + return text + + +def is_palindrome(text: str, ignore_case: bool = True, ignore_non_alnum: bool = True) -> bool: + """Return True if text is a palindrome under the chosen normalization options.""" + if not isinstance(text, str): + raise ValueError("text must be a string") + normalized = _normalize(text, ignore_case=ignore_case, ignore_non_alnum=ignore_non_alnum) + return normalized == normalized[::-1] + + +def longest_palindromic_substring(text: str) -> str: + """Return the longest palindromic substring using expand-around-center. + + For ties, the first occurring longest substring is returned. + """ + if not isinstance(text, str): + raise ValueError("text must be a string") + if not text: + return "" + + def expand(left: int, right: int) -> Tuple[int, int]: + while left >= 0 and right < len(text) and text[left] == text[right]: + left -= 1 + right += 1 + return left + 1, right # inclusive start, exclusive end + + best_start, best_end = 0, 1 + for center in range(len(text)): + # Odd-length palindrome + s1, e1 = expand(center, center) + if e1 - s1 > best_end - best_start: + best_start, best_end = s1, e1 + # Even-length palindrome + if center + 1 < len(text): + s2, e2 = expand(center, center + 1) + if e2 - s2 > best_end - best_start: + best_start, best_end = s2, e2 + + return text[best_start:best_end] + + +def _print_examples() -> None: + cases = [ + "racecar", + "A man, a plan, a canal: Panama!", + "hello", + "forgeeksskeegfor", + "abba", + "", + ] + print("Examples:") + for c in cases: + print(f" '{c}' -> is_palindrome: {is_palindrome(c)}; LPS: '{longest_palindromic_substring(c)}'") + + +if __name__ == "__main__": + import argparse + + parser = argparse.ArgumentParser(description="Palindrome utilities: check or find longest palindromic substring.") + sub = parser.add_subparsers(dest="command", required=True) + + p_check = sub.add_parser("check", help="Check if a string is a palindrome") + p_check.add_argument("text", type=str, help="Input text") + p_check.add_argument("--case-sensitive", action="store_true", help="Make check case-sensitive") + p_check.add_argument("--keep-non-alnum", action="store_true", help="Do not strip non-alphanumeric characters") + + p_lps = sub.add_parser("lps", help="Find the longest palindromic substring") + p_lps.add_argument("text", type=str, help="Input text") + + parser.add_argument("--examples", action="store_true", help="Show example outputs") + + args = parser.parse_args() + + if args.examples: + _print_examples() + + if args.command == "check": + ignore_case = not args.case_sensitive + ignore_non_alnum = not args.keep_non_alnum + print(is_palindrome(args.text, ignore_case=ignore_case, ignore_non_alnum=ignore_non_alnum)) + elif args.command == "lps": + print(longest_palindromic_substring(args.text)) + + diff --git a/Python/password_generator.py b/Python/password_generator.py new file mode 100644 index 00000000..b0755e50 --- /dev/null +++ b/Python/password_generator.py @@ -0,0 +1,20 @@ +import random +import string + +def generate_password(length=12, use_digits=True, use_symbols=True): + # Define character sets + letters = string.ascii_letters + digits = string.digits if use_digits else '' + symbols = string.punctuation if use_symbols else '' + + # Combine all selected characters + all_chars = letters + digits + symbols + if not all_chars: + raise ValueError("No character sets selected for password generation.") + + # Generate password + password = ''.join(random.choice(all_chars) for _ in range(length)) + return password + +# Example usage +print("Generated password:", generate_password(length=16)) \ No newline at end of file diff --git a/Python/rat_in_maze.py b/Python/rat_in_maze.py new file mode 100644 index 00000000..6fa6ecaf --- /dev/null +++ b/Python/rat_in_maze.py @@ -0,0 +1,46 @@ +dir = "DLRU" +dr = [1, 0, 0, -1] +dc = [0, -1, 1, 0] + +def isValid(r, c, n, maze): + return 0 <= r < n and 0 <= c < n and maze[r][c] == 1 + +def findPath(r, c, maze, path, res): + n = len(maze) + if r == n - 1 and c == n - 1: + res.append("".join(path)) + return + + maze[r][c] = 0 + + for i in range(4): + nr, nc = r + dr[i], c + dc[i] + if isValid(nr, nc, n, maze): + path.append(dir[i]) + findPath(nr, nc, maze, path, res) + path.pop() + + maze[r][c] = 1 + +def ratInMaze(maze): + n = len(maze) + result = [] + path = [] + + if maze[0][0] == 1 and maze[n - 1][n - 1] == 1: + findPath(0, 0, maze, path, result) + + result.sort() + return result + +if __name__ == "__main__": + maze = [ + [1, 0, 0, 0], + [1, 1, 0, 1], + [1, 1, 0, 0], + [0, 1, 1, 1] + ] + + result = ratInMaze(maze) + for p in result: + print(p, end=" ") \ No newline at end of file diff --git a/Python/reverse_linked_list.py b/Python/reverse_linked_list.py new file mode 100644 index 00000000..9b276086 --- /dev/null +++ b/Python/reverse_linked_list.py @@ -0,0 +1,34 @@ +class Node: + def __init__(self, data): + self.data = data + self.next = None + +def reverse_linked_list(head): + prev = None + current = head + while current: + next_node = current.next # Save next node + current.next = prev # Reverse pointer + prev = current # Move prev forward + current = next_node # Move current forward + return prev # New head of reversed list + +# Helper to print the list +def print_list(head): + while head: + print(head.data, end=" -> ") + head = head.next + print("None") + +# Example usage +head = Node(1) +head.next = Node(2) +head.next.next = Node(3) +head.next.next.next = Node(4) + +print("Original List:") +print_list(head) + +reversed_head = reverse_linked_list(head) +print("Reversed List:") +print_list(reversed_head) \ No newline at end of file diff --git a/Python/roman_numerals.py b/Python/roman_numerals.py new file mode 100644 index 00000000..34d29a12 --- /dev/null +++ b/Python/roman_numerals.py @@ -0,0 +1,151 @@ +""" +Roman numeral utilities + +This module provides two high-level functions: +- int_to_roman(number: int) -> str +- roman_to_int(numeral: str) -> int + +Both functions validate inputs and raise ValueError for invalid cases. + +Run this file directly to use a simple CLI for conversions. +""" + +from typing import Dict + + +_INT_TO_ROMAN_PAIRS: tuple[tuple[int, str], ...] = ( + (1000, "M"), + (900, "CM"), + (500, "D"), + (400, "CD"), + (100, "C"), + (90, "XC"), + (50, "L"), + (40, "XL"), + (10, "X"), + (9, "IX"), + (5, "V"), + (4, "IV"), + (1, "I"), +) + +_ROMAN_TO_INT_MAP: Dict[str, int] = { + "I": 1, + "V": 5, + "X": 10, + "L": 50, + "C": 100, + "D": 500, + "M": 1000, +} + + +def int_to_roman(number: int) -> str: + """Convert an integer to a Roman numeral. + + Supports values from 1 to 3999 inclusive. + Raises ValueError for out-of-range or non-integer inputs. + """ + if not isinstance(number, int): + raise ValueError("number must be an integer") + if number <= 0 or number >= 4000: + raise ValueError("number must be between 1 and 3999 inclusive") + + result_parts: list[str] = [] + remaining = number + for value, symbol in _INT_TO_ROMAN_PAIRS: + if remaining == 0: + break + count, remaining = divmod(remaining, value) + if count: + result_parts.append(symbol * count) + return "".join(result_parts) + + +def roman_to_int(numeral: str) -> int: + """Convert a Roman numeral to an integer. + + Validates standard subtractive notation and character set. Case-insensitive. + Raises ValueError for invalid strings. + """ + if not isinstance(numeral, str) or not numeral.strip(): + raise ValueError("numeral must be a non-empty string") + + s = numeral.strip().upper() + total = 0 + i = 0 + + while i < len(s): + current_char = s[i] + if current_char not in _ROMAN_TO_INT_MAP: + raise ValueError(f"invalid Roman numeral character: {current_char}") + + current_value = _ROMAN_TO_INT_MAP[current_char] + + if i + 1 < len(s): + next_char = s[i + 1] + if next_char not in _ROMAN_TO_INT_MAP: + raise ValueError(f"invalid Roman numeral character: {next_char}") + next_value = _ROMAN_TO_INT_MAP[next_char] + + if current_value < next_value: + # Validate allowed subtractive pairs + if current_char == "I" and next_char not in ("V", "X"): + raise ValueError("invalid subtractive pair: I can precede V or X only") + if current_char == "X" and next_char not in ("L", "C"): + raise ValueError("invalid subtractive pair: X can precede L or C only") + if current_char == "C" and next_char not in ("D", "M"): + raise ValueError("invalid subtractive pair: C can precede D or M only") + + total += next_value - current_value + i += 2 + continue + + total += current_value + i += 1 + + # Convert back to Roman to ensure canonical form matches input when normalized + # This guards against sequences like "IM" which might numerically process but are invalid + try: + canonical = int_to_roman(total) + except ValueError: + raise ValueError("resulting value is out of supported range") + + if canonical != s: + # Accept non-canonical but equivalent forms only if they strictly match canonical when uppercased + # e.g., "xvii" is allowed because upper() makes it canonical; "iiiii" is rejected + # since canonical for 5 is "V" + raise ValueError("invalid or non-canonical Roman numeral sequence") + + return total + + +def _print_examples() -> None: + examples = [1, 4, 9, 29, 44, 58, 94, 145, 3999] + print("Examples (int -> roman -> int):") + for n in examples: + r = int_to_roman(n) + back = roman_to_int(r) + print(f" {n} -> {r} -> {back}") + + +if __name__ == "__main__": + import argparse + + parser = argparse.ArgumentParser(description="Convert between Roman numerals and integers.") + group = parser.add_mutually_exclusive_group(required=True) + group.add_argument("--to-roman", type=int, dest="to_roman", help="Convert integer to Roman numeral") + group.add_argument("--to-int", type=str, dest="to_int", help="Convert Roman numeral to integer") + parser.add_argument("--examples", action="store_true", help="Show example conversions") + + args = parser.parse_args() + + if args.examples: + _print_examples() + + if args.to_roman is not None: + print(int_to_roman(args.to_roman)) + elif args.to_int is not None: + print(roman_to_int(args.to_int)) + + diff --git a/Python/set_bits_count.py b/Python/set_bits_count.py new file mode 100644 index 00000000..5b9461d9 --- /dev/null +++ b/Python/set_bits_count.py @@ -0,0 +1,14 @@ +""" +Problem: +Given an integer, count how many 1s are present in its binary representation. + +Example: +Input: 13 (1101) → Output: 3 +""" + +def count_set_bits(n): + count = 0 + while n: + count += n & 1 + n >>= 1 + return count \ No newline at end of file diff --git a/Python/subset_with_sum_k.py b/Python/subset_with_sum_k.py new file mode 100644 index 00000000..df469d95 --- /dev/null +++ b/Python/subset_with_sum_k.py @@ -0,0 +1,27 @@ +MOD = 10**9 + 7 + +def count_subsets_with_sum(nums, target_sum): + n = len(nums) + if target_sum == 0: + return 1 + + memo = [[-1] * (target_sum + 1) for _ in range(n)] + + def helper(index, remaining_sum): + if remaining_sum == 0: + return 1 + if index == 0: + return 1 if nums[0] == remaining_sum else 0 + + if memo[index][remaining_sum] != -1: + return memo[index][remaining_sum] + + count_excluding = helper(index - 1, remaining_sum) + count_including = 0 + if nums[index] <= remaining_sum: + count_including = helper(index - 1, remaining_sum - nums[index]) + + memo[index][remaining_sum] = (count_excluding + count_including) % MOD + return memo[index][remaining_sum] + + return helper(n - 1, target_sum) \ No newline at end of file diff --git a/Python/sum_till_single_digit.py b/Python/sum_till_single_digit.py new file mode 100644 index 00000000..86d42e8f --- /dev/null +++ b/Python/sum_till_single_digit.py @@ -0,0 +1,16 @@ +""" +Problem: +Keep summing digits of a number until you get a single digit. + +Example: +Input: 9875 +9+8+7+5=29 +2+9=11 +1+1=2 +Output: 2 +""" + +def digital_root(n): + while n >= 10: + n = sum(int(d) for d in str(n)) + return n \ No newline at end of file diff --git a/Python/tribonacci_series.py b/Python/tribonacci_series.py new file mode 100644 index 00000000..06867b81 --- /dev/null +++ b/Python/tribonacci_series.py @@ -0,0 +1,13 @@ +def tri(n): + if n == 0: + return 0 + elif n == 1 or n == 2: + return 1 + + trib = [0] * (n + 1) + trib[0], trib[1], trib[2] = 0, 1, 1 + + for i in range(3, n + 1): + trib[i] = trib[i - 1] + trib[i - 2] + trib[i - 3] + + return trib[n] \ No newline at end of file diff --git a/Python/unique_paths.py b/Python/unique_paths.py new file mode 100644 index 00000000..161a88fc --- /dev/null +++ b/Python/unique_paths.py @@ -0,0 +1,15 @@ +dp = {} +def uniquePaths(m , n): + if m == 1 and n == 1: + return 1 + if m < 1 or n < 1: + return 0 + if (m, n) in dp: + return dp[(m, n)] + dp[(m, n)] = uniquePaths(m - 1, n) + uniquePaths(m, n - 1) + return dp[(m, n)] + +print(uniquePaths(3, 7)) # Output: 28 +# The function uniquePaths calculates the number of unique paths +# from the top-left corner to the bottom-right corner of an m x n grid. +# You can only move either down or right at any point in time. \ No newline at end of file diff --git a/Square_SubMat_With_Ones.py b/Square_SubMat_With_Ones.py new file mode 100644 index 00000000..2e5185de --- /dev/null +++ b/Square_SubMat_With_Ones.py @@ -0,0 +1,47 @@ +from typing import List + +class Solution: + def countSquares(self, matrix: List[List[int]]) -> int: + # Get number of rows and columns + r = len(matrix) + c = len(matrix[0]) + + # dp[i][j] will store the size of the largest square + # whose bottom-right corner is at cell (i, j) + dp = [[0] * c for _ in range(r)] + + count = 0 # To store total number of square submatrices + + # Initialize first row + # Each 1 in the first row forms a 1x1 square + for j in range(c): + if matrix[0][j] == 1: + dp[0][j] = 1 + count += 1 + + # Initialize first column + # Each 1 in the first column forms a 1x1 square + for i in range(1, r): + if matrix[i][0] == 1: + dp[i][0] = 1 + count += 1 + + # Fill the dp table for the rest of the matrix + for i in range(1, r): + for j in range(1, c): + # If the cell is 0, no square can end here + if matrix[i][j] == 0: + continue + # If the cell is 1, find the smallest neighboring square + # and extend it by 1 to form a bigger square + elif dp[i-1][j] == 0 or dp[i-1][j-1] == 0 or dp[i][j-1] == 0: + dp[i][j] = 1 # Only a 1x1 square possible + else: + # Minimum of top, left, and top-left + 1 + dp[i][j] = min(dp[i-1][j], dp[i-1][j-1], dp[i][j-1]) + 1 + + # Add the number of squares ending at (i, j) + count += dp[i][j] + + # Return total count of all square submatrices with all 1s + return count diff --git a/Tic-Tac-To-Game/Game.html b/Tic-Tac-To-Game/Game.html new file mode 100644 index 00000000..6037601d --- /dev/null +++ b/Tic-Tac-To-Game/Game.html @@ -0,0 +1,332 @@ + + + + + + Tic-Tac-Toe Game + + + +
+

Tic-Tac-Toe

+ +
+
+
X
+
0
+
+
+
Draw
+
0
+
+
+
O
+
0
+
+
+ +
Next: X
+ +
+ + + + + + + + + +
+ +
+ + +
+
+ + + + \ No newline at end of file diff --git a/pandas/Employees Whose Manager Left the Company.py b/pandas/Employees Whose Manager Left the Company.py new file mode 100644 index 00000000..b2b46854 --- /dev/null +++ b/pandas/Employees Whose Manager Left the Company.py @@ -0,0 +1,6 @@ +import pandas as pd + +def find_employees(employees: pd.DataFrame) -> pd.DataFrame: + valid_ids = set(employees['employee_id']) + df = employees[~employees['manager_id'].isin(valid_ids) & employees['manager_id'].notna()] + return df[['employee_id']] diff --git a/pandas/Employees With Missing Information.py b/pandas/Employees With Missing Information.py new file mode 100644 index 00000000..dfa2d050 --- /dev/null +++ b/pandas/Employees With Missing Information.py @@ -0,0 +1,7 @@ +import pandas as pd + +def find_employees(employee: pd.DataFrame, salary: pd.DataFrame) -> pd.DataFrame: + df = pd.merge(employee, salary, on='employee_id', how='outer') + missing = df[df.isna().any(axis=1)][['employee_id']] + missing = missing.sort_values('employee_id') + return missing diff --git a/pandas/Not Boring Movies.py b/pandas/Not Boring Movies.py new file mode 100644 index 00000000..95de709b --- /dev/null +++ b/pandas/Not Boring Movies.py @@ -0,0 +1,5 @@ +import pandas as pd + +def not_boring_movies(cinema: pd.DataFrame) -> pd.DataFrame: + df = cinema[(cinema['id'] % 2 == 1) & (cinema['description'] != 'boring')] + return df.sort_values('rating', ascending=False) diff --git a/pandas/Order Two Columns Independently.py b/pandas/Order Two Columns Independently.py new file mode 100644 index 00000000..2faa67f2 --- /dev/null +++ b/pandas/Order Two Columns Independently.py @@ -0,0 +1,6 @@ +import pandas as pd + +def order_columns_independently(df: pd.DataFrame) -> pd.DataFrame: + df['col1'] = sorted(df['col1']) + df['col2'] = sorted(df['col2']) + return df diff --git a/pandas/The Change in Global Rankings.py b/pandas/The Change in Global Rankings.py new file mode 100644 index 00000000..84eb80b0 --- /dev/null +++ b/pandas/The Change in Global Rankings.py @@ -0,0 +1,9 @@ +import pandas as pd + +def rank_change(comp1: pd.DataFrame, comp2: pd.DataFrame) -> pd.DataFrame: + comp1['rank1'] = comp1['score'].rank(ascending=False, method='dense') + comp2['rank2'] = comp2['score'].rank(ascending=False, method='dense') + + merged = pd.merge(comp1[['player_id', 'rank1']], comp2[['player_id', 'rank2']], on='player_id') + merged['rank_diff'] = merged['rank1'] - merged['rank2'] + return merged[['player_id', 'rank_diff']] diff --git a/swim_in_rising_water b/swim_in_rising_water new file mode 100644 index 00000000..dfd756d8 --- /dev/null +++ b/swim_in_rising_water @@ -0,0 +1,28 @@ +class Solution: + def swimInWater(self, grid: List[List[int]]) -> int: + m,n=len(grid),len(grid[0]) + edges=[] + for i in range(m): + for j in range(n): + if i>0: + edges.append((max(grid[i][j],grid[i-1][j]),i*n+j,(i-1)*n+j)) + if j>0: + edges.append((max(grid[i][j],grid[i][j-1]),i*n+j,i*n+j-1)) + + edges.sort() + parent = list(range(m * n)) + + def find(x): + if parent[x]!=x: + parent[x]=find(parent[x]) + return parent[x] + + def union(x, y): + parent[find(x)]=find(y) + + for cost,u,v in edges: + union(u,v) + if find(0)==find(m*n-1): + return cost + + return grid[0][0]