Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --- .\make-one.py
- import os
- from typing import List, Tuple
- from dotenv import load_dotenv
- load_dotenv()
- delimiter = os.environ.get('DELIMITER')
- def get_files(path=".", excludes=['.exe', '.txt', '.env']) -> List[str]:
- # Items in the current folder
- folder_items = os.listdir(path)
- # Filter out the folders
- folders = list(
- filter(lambda x: '.' not in x, folder_items)
- )
- # Filter out the files
- files = list(
- map(
- lambda file_name: os.path.join(path, file_name),
- filter(lambda x: ('.' in x) and all(
- [exclude not in x for exclude in excludes]), folder_items)
- )
- )
- # It means we're at the deepest level
- if len(folders) == 0:
- return files
- # Iterate over all the folders to the files
- for folder in folders:
- files += get_files(path=os.path.join(path, folder))
- # Return the files we got
- return files
- def dump_into_one(files: list[str], output: str = "out.txt"):
- """
- Dumps all the files into big text file,
- delimiter=''
- """
- with open(output, encoding='utf-8', mode='w+') as outFile:
- # Read and write from every single file
- content = ""
- content_string = "{0} {1}\n{2}\n{0}\n"
- for file in files:
- with open(file, encoding='utf-8', mode='r') as inFile:
- content += content_string.format(delimiter,
- file, inFile.read())
- # Write the read content
- outFile.write(content)
- return
- def extract_from_dump(out_file: str = "out.txt") -> List[Tuple[str, str]]:
- # Output filenames with their content
- output: List[Tuple[str, str]] = []
- # Read the file and split on the delimiter
- content = ""
- with open(out_file, encoding='utf-8', mode='r+') as readFile:
- content = readFile.read().split(delimiter)
- # Filters for the content
- content = list(
- filter(lambda x: x != '\n' and x != delimiter and x != '', content)
- )
- # Iterate over the content
- for i, file_content in enumerate(content):
- filename = file_content.split('\n')[0].strip()
- content = file_content.replace(filename, '')
- # Record this
- output.append((filename, content))
- return output
- if __name__ == '__main__':
- def bundle_files():
- # To compress the files
- files = get_files()
- for file in files:
- print(file)
- dump_into_one(files)
- def debundle_files():
- # To debundle the files
- files = extract_from_dump(out_file="out.txt")
- # Make the directories exist
- for (filename, file_content) in files:
- # Split the path of the file
- head, tail = os.path.split(filename)
- try:
- os.mkdir(head)
- except FileExistsError:
- pass
- # Write the file
- with open(filename, encoding='utf-8', mode='w+') as writeFile:
- writeFile.write(file_content)
- # end-with
- # end-for
- bundle_files()
- # structure = extract_from_dump()
- # for (filename, _) in structure:
- # print(filename)
- # debundle_files()
- ---
- --- .\graphs\bipartite.cpp
- #include <iostream>
- #include <vector>
- #include <queue>
- using namespace std;
- class Solution
- {
- // colors a component
- private:
- bool check(int start, int V, vector<int> adj[], int color[])
- {
- queue<int> q;
- q.push(start);
- color[start] = 0;
- while (!q.empty())
- {
- int node = q.front();
- q.pop();
- for (auto it : adj[node])
- {
- // if the adjacent node is yet not colored
- // you will give the opposite color of the node
- if (color[it] == -1)
- {
- color[it] = !color[node];
- q.push(it);
- }
- // is the adjacent guy having the same color
- // someone did color it on some other path
- else if (color[it] == color[node])
- {
- return false;
- }
- }
- }
- return true;
- }
- public:
- bool isBipartite(int V, vector<int> adj[])
- {
- int *color = new int[V];
- for (int i = 0; i < V; i++)
- color[i] = -1;
- for (int i = 0; i < V; i++)
- {
- // if not coloured
- if (color[i] == -1)
- {
- if (check(i, V, adj, color) == false)
- {
- delete[] color;
- return false;
- }
- }
- }
- delete[] color;
- return true;
- }
- };
- void addEdge(vector<int> adj[], int u, int v)
- {
- adj[u].push_back(v);
- adj[v].push_back(u);
- }
- int main()
- {
- // V = 4, E = 4
- vector<int> adj[4];
- addEdge(adj, 0, 2);
- addEdge(adj, 0, 3);
- addEdge(adj, 2, 3);
- addEdge(adj, 3, 1);
- Solution obj;
- bool ans = obj.isBipartite(4, adj);
- if (ans)
- cout << "1\n";
- else
- cout << "0\n";
- return 0;
- }
- ---
- --- .\graphs\cycles.cpp
- // A C++ Program to detect cycle in a graph
- #include <iostream>
- #include <list>
- using namespace std;
- class Graph
- {
- // No. of vertices
- int V;
- // Pointer to an array containing adjacency lists
- list<int> *adj;
- // Used by isCyclic()
- bool isCyclicUtil(int v, bool visited[], bool *rs);
- public:
- Graph(int V);
- void addEdge(int v, int w);
- bool isCyclic();
- };
- Graph::Graph(int V)
- {
- this->V = V;
- adj = new list<int>[V];
- }
- void Graph::addEdge(int v, int w)
- {
- // Add w to v’s list.
- adj[v].push_back(w);
- }
- // DFS function to find if a cycle exists
- bool Graph::isCyclicUtil(int v, bool visited[],
- bool *recStack)
- {
- if (visited[v] == false)
- {
- // Mark the current node as visited
- // and part of recursion stack
- visited[v] = true;
- recStack[v] = true;
- // Recur for all the vertices adjacent to this
- // vertex
- list<int>::iterator i;
- for (i = adj[v].begin(); i != adj[v].end(); ++i)
- {
- if (!visited[*i] && isCyclicUtil(*i, visited, recStack))
- return true;
- else if (recStack[*i])
- return true;
- }
- }
- // Remove the vertex from recursion stack
- recStack[v] = false;
- return false;
- }
- // Returns true if the graph contains a cycle, else false
- bool Graph::isCyclic()
- {
- // Mark all the vertices as not visited
- // and not part of recursion stack
- bool *visited = new bool[V];
- bool *recStack = new bool[V];
- for (int i = 0; i < V; i++)
- {
- visited[i] = false;
- recStack[i] = false;
- }
- // Call the recursive helper function
- // to detect cycle in different DFS trees
- for (int i = 0; i < V; i++)
- if (!visited[i] && isCyclicUtil(i, visited, recStack))
- return true;
- return false;
- }
- // Driver code
- int main()
- {
- // Create a graph
- Graph g(4);
- g.addEdge(0, 1);
- g.addEdge(0, 2);
- g.addEdge(1, 2);
- g.addEdge(2, 0);
- g.addEdge(2, 3);
- g.addEdge(3, 3);
- // Function call
- if (g.isCyclic())
- cout << "Graph contains cycle";
- else
- cout << "Graph doesn't contain cycle";
- return 0;
- }
- ---
- --- .\graphs\main.cpp
- #include <iostream>
- #include "paths.hpp"
- #include "prims.hpp"
- int main()
- {
- /*
- Graph *g = new Graph(13);
- g->addNeighbors(0, {7, 9, 11});
- g->addNeighbors(1, {8, 10});
- g->addNeighbors(2, {3, 12});
- g->addNeighbors(3, {2, 4, 7});
- g->addNeighbors(4, {3});
- g->addNeighbors(5, {6});
- g->addNeighbors(6, {5});
- g->addNeighbors(7, {3, 6, 11});
- g->addNeighbors(8, {1, 12});
- g->addNeighbors(9, {8, 10});
- g->addNeighbors(10, {1});
- g->addNeighbors(11, {0});
- g->addNeighbors(12, {2, 8});
- int src = 4, dest = 1;
- std::cout << "Breadth First ";
- int level = g->breadthFirstSearch(src, dest);
- std::cout << std::endl;
- if (level == -1)
- {
- std::cout << "Couldn't find a path from " << src << " to " << dest << "\n";
- }
- std::cout << "Depth First ";
- int dfsLevel = g->depthFirstSearch(src, dest);
- std::cout << std::endl;
- if (dfsLevel == -1)
- {
- std::cout << "Couldn't find a path from " << src << " to " << dest << "\n";
- }
- // Free the taken memory
- delete g;
- */
- vector<vector<pair<int, int>>> adjList{
- {{1, 1}, {2, 6}, {3, 5}}, // 0
- {{0, 1}, {2, 6}}, // 1
- {{0, 6}, {1, 6}, {4, 7}, {5, 3}}, // 2
- {{0, 5}, {5, 2}, {6, 10}}, // 3
- {{2, 7}, {7, 12}}, // 4
- {{2, 3}, {3, 2}, {7, 8}}, // 5
- {{3, 10}, {7, 7}, {8, 3}}, // 6
- {{4, 12}, {5, 8}, {6, 7}, {8, 8}}, // 7
- {{6, 3}, {7, 8}}, // 8
- };
- int start = 1;
- int cost = primsMinimumCostSpanningTree(start, adjList);
- std::cout << "The cost of the minimum spanning tree is: " << cost << "\n";
- return 0;
- }
- ---
- --- .\graphs\paths.hpp
- #ifndef PATHS
- #define PATHS
- #include <vector>
- #include <queue>
- #include <stack>
- template <class T>
- using vector = std::vector<T>;
- template <class T>
- using queue = std::queue<T>;
- template <class T>
- using stack = std::stack<T>;
- template <class T1, class T2>
- using pair = std::pair<T1, T2>;
- /**
- * Class to represent graphs
- */
- class Graph
- {
- private:
- vector<vector<int>> adjList;
- int vertexCount;
- /**
- * Prints the shortest path found in the graph
- * @param parent The list containing parent for each vertex
- * @param src The starting vertex of the journey
- * @param dest The ending vertex of the journey
- */
- int printShortestPath(vector<int> const &parent, const int src, const int dest)
- {
- static int level = 0;
- // If we've reached the root of the shortest path tree
- if (parent[src] == -1)
- {
- std::cout << "Shortest path between " << src << " and " << dest << " is " << src << " ";
- return level;
- }
- // Recursively find the path
- printShortestPath(parent, parent[src], dest);
- level++;
- if (src < vertexCount)
- {
- std::cout << src << " ";
- }
- return level;
- }
- public:
- /**
- * The vertex numbers start from '0'
- */
- Graph(int vertices)
- {
- // Add empty list for the adjacency
- for (int i = 0; i < vertices; i++)
- adjList.push_back({});
- // Store the number of the vertices
- vertexCount = vertices;
- }
- /**
- * Adds an edge to the graph from u -> v
- * @param u The first vertex of the dge
- * @param v The second vertex of the edge
- */
- void addEdge(int u, int v)
- {
- // Check if the vertex is within the bounds
- if (0 > u || vertexCount <= u)
- return;
- if (0 > v || vertexCount <= v)
- return;
- // Add the vertex to the list
- adjList[u].push_back(v);
- }
- /**
- * Adds a whole list for the adjacency list
- * @param vertex The vertex to add neighbors to
- * @param neighbors The neighbor list for the vertex
- */
- void addNeighbors(const int &vertex, const vector<int> &neighbors)
- {
- adjList[vertex] = neighbors;
- }
- /**
- * To perform a breadth first search on the graph
- * @param start The starting vertex of the graph
- * @param end The destination for the search
- */
- int breadthFirstSearch(int const start, int const end)
- {
- // Create a queue frontier for the search
- queue<int> q;
- // Add the start to the queue
- q.push(start);
- // Make a list to keep track of parents
- vector<int> parent(vertexCount, -1);
- // Make a visited list
- vector<bool> visited(vertexCount, false);
- // Mark the current node as visited
- visited[start] = true;
- while (!q.empty())
- {
- // Get the current element to explore, pop it from the queue
- int current = q.front();
- q.pop();
- // Check if we've reached our goal
- if (current == end)
- {
- return printShortestPath(parent, current, end);
- }
- // Iterate over all the neighbors to the find the
- for (int const &neighbor : adjList[current])
- {
- if (!visited[neighbor])
- {
- q.push(neighbor);
- visited[neighbor] = true;
- parent[neighbor] = current;
- }
- }
- }
- // Return -1, if we don't find any path
- return -1;
- }
- /**
- * To perform a depth-first search on the graph
- * @param start The starting vertex of the graph
- * @param end The destination for the search
- */
- int depthFirstSearch(int const start, int const end)
- {
- // Create a stack frontier
- stack<int> stack;
- // Keep track of the visited nodes
- vector<bool> visited(vertexCount, false);
- // Make a list of parents to create a path later
- vector<int> parent(vertexCount, -1);
- // Add the current node to frontier, and mark it visited
- stack.push(start);
- visited[start] = true;
- // Repeat till the stack is empty
- while (!stack.empty())
- {
- // Get the element at top of the stack
- int current = stack.top();
- stack.pop();
- // Check if we've reached our destination
- if (current == end)
- {
- return printShortestPath(parent, current, end);
- }
- // Mark this node as visited
- visited[current] = true;
- // Explore all the neighbors
- for (int const &neighbor : adjList[current])
- {
- if (!visited[neighbor])
- {
- // Add this node to the frontier to explore later
- stack.push(neighbor);
- // Mark the current element as parent of the neighbor (in dfs tree)
- parent[neighbor] = current;
- // Mark this node as visited
- visited[neighbor] = true;
- }
- }
- }
- // Return -1, if we didn't find any path
- return -1;
- }
- };
- #endif
- ---
- --- .\graphs\prims.cpp
- #include <stdio.h>
- #include <limits.h>
- #define vertices 5 /*Define the number of vertices in the graph*/
- /* create minimum_key() method for finding the vertex that has minimum key-value and that is not added in MST yet */
- int minimum_key(int k[], int mst[])
- {
- int minimum = INT_MAX, min, i;
- /*iterate over all vertices to find the vertex with minimum key-value*/
- for (i = 0; i < vertices; i++)
- if (mst[i] == 0 && k[i] < minimum)
- minimum = k[i], min = i;
- return min;
- }
- /* create prim() method for constructing and printing the MST.
- The g[vertices][vertices] is an adjacency matrix that defines the graph for MST.*/
- void prim(int g[vertices][vertices])
- {
- /* create array of size equal to total number of vertices for storing the MST*/
- int parent[vertices];
- /* create k[vertices] array for selecting an edge having minimum weight*/
- int k[vertices];
- int mst[vertices];
- int i, count, edge, v; /*Here 'v' is the vertex*/
- for (i = 0; i < vertices; i++)
- {
- k[i] = INT_MAX;
- mst[i] = 0;
- }
- k[0] = 0; /*It select as first vertex*/
- parent[0] = -1; /* set first value of parent[] array to -1 to make it root of MST*/
- for (count = 0; count < vertices - 1; count++)
- {
- /*select the vertex having minimum key and that is not added in the MST yet from the set of vertices*/
- edge = minimum_key(k, mst);
- mst[edge] = 1;
- for (v = 0; v < vertices; v++)
- {
- if (g[edge][v] && mst[v] == 0 && g[edge][v] < k[v])
- {
- parent[v] = edge, k[v] = g[edge][v];
- }
- }
- }
- /*Print the constructed Minimum spanning tree*/
- printf("\n Edge \t Weight\n");
- for (i = 1; i < vertices; i++)
- printf(" %d <-> %d %d \n", parent[i], i, g[i][parent[i]]);
- }
- int main()
- {
- int g[vertices][vertices] = {
- {0, 0, 3, 0, 0},
- {0, 0, 10, 4, 0},
- {3, 10, 0, 2, 6},
- {0, 4, 2, 0, 1},
- {0, 0, 6, 1, 0},
- };
- prim(g);
- return 0;
- }
- ---
- --- .\graphs\strongly.cpp
- // Program to check if the given directed graph
- // is strongly connected or not.
- #include <iostream>
- #include <list>
- #include <queue>
- using namespace std;
- class Graph
- {
- int vertices; // To store no. of vertices
- list<int> *adjList;
- // Function to print DFS starting from v
- void BFSUtil(int v, bool visited[]);
- public:
- Graph(int V)
- {
- this->vertices = V;
- adjList = new list<int>[V];
- }
- ~Graph() { delete[] adjList; }
- // Function to add an edge
- void addEdge(int v, int w);
- // Function that returns if the
- // graph is strongly connected or not.
- bool isStronglyConnected();
- // Function that returns reverse (or transpose)
- // of this graph
- Graph getTranspose();
- };
- // A recursive function to print DFS starting from v
- void Graph::BFSUtil(int v, bool visited[])
- {
- // Creating a queue for BFS traversal
- list<int> queue;
- visited[v] = true;
- queue.push_back(v);
- list<int>::iterator i;
- while (!queue.empty())
- {
- // Dequeue a vertex from queue
- v = queue.front();
- queue.pop_front();
- for (i = adjList[v].begin(); i != adjList[v].end(); ++i)
- {
- if (!visited[*i])
- {
- visited[*i] = true;
- queue.push_back(*i);
- }
- }
- }
- }
- Graph Graph::getTranspose()
- {
- Graph g(vertices);
- for (int v = 0; v < vertices; v++)
- {
- list<int>::iterator i;
- for (i = adjList[v].begin(); i != adjList[v].end(); ++i)
- g.adjList[*i].push_back(v);
- }
- return g;
- }
- void Graph::addEdge(int v, int w)
- {
- adjList[v].push_back(w);
- }
- // Function that returns true if graph
- // is strongly connected
- bool Graph::isStronglyConnected()
- {
- // Step 1: Mark all the vertices as not
- // visited (For first BFS)
- bool *visited = new bool[vertices];
- for (int i = 0; i < vertices; i++)
- visited[i] = false;
- // Do BFS traversal starting from the first vertex.
- BFSUtil(0, visited);
- // If BFS traversal doesn’t visit all vertices
- // return false.
- for (int i = 0; i < vertices; i++)
- if (visited[i] == false)
- {
- delete[] visited;
- return false;
- }
- // Create a reversed graph
- Graph gr = getTranspose();
- // Step 4: Mark all the vertices as not
- // visited (For second BFS)
- for (int i = 0; i < vertices; i++)
- visited[i] = false;
- gr.BFSUtil(0, visited);
- // If all vertices are not visited in the second DFS
- // return false
- for (int i = 0; i < vertices; i++)
- if (visited[i] == false)
- {
- delete[] visited;
- return false;
- }
- delete[] visited;
- return true;
- }
- // Driver program to test the above functions
- int main()
- {
- Graph g1(7);
- g1.addEdge(0, 1);
- g1.addEdge(1, 2);
- g1.addEdge(2, 3);
- g1.addEdge(3, 0);
- g1.addEdge(2, 4);
- g1.addEdge(4, 2);
- g1.addEdge(4, 5);
- g1.addEdge(5, 6);
- g1.addEdge(6, 4);
- g1.isStronglyConnected() ? cout << "Yes" : cout << "No";
- return 0;
- }
- ---
- --- .\graphs\topologicalSorting.cpp
- #include <iostream>
- #include <vector>
- #include <stack>
- using namespace std;
- // Function to perform DFS and topological sorting
- void topologicalSortUtil(int v, vector<vector<int>> &adj,
- vector<bool> &visited,
- stack<int> &Stack)
- {
- // Mark the current node as visited
- visited[v] = true;
- // Recur for all adjacent vertices
- for (int i : adj[v])
- {
- if (!visited[i])
- topologicalSortUtil(i, adj, visited, Stack);
- }
- // Push current vertex to stack which stores the result
- Stack.push(v);
- }
- // Function to perform Topological Sort
- void topologicalSort(vector<vector<int>> &adj, int V)
- {
- stack<int> Stack; // Stack to store the result
- vector<bool> visited(V, false);
- // Call the recursive helper function to store
- // Topological Sort starting from all vertices one by
- // one
- for (int i = 0; i < V; i++)
- {
- if (!visited[i])
- topologicalSortUtil(i, adj, visited, Stack);
- }
- // Print contents of stack
- while (!Stack.empty())
- {
- cout << Stack.top() << " ";
- Stack.pop();
- }
- }
- int main()
- {
- // Number of nodes
- int V = 4;
- // Edges
- vector<vector<int>> edges = {{0, 1}, {1, 2}, {3, 1}, {3, 2}};
- // Graph represented as an adjacency list
- vector<vector<int>> adj(V);
- for (auto i : edges)
- {
- adj[i[0]].push_back(i[1]);
- }
- cout << "Topological sorting of the graph: ";
- topologicalSort(adj, V);
- return 0;
- }
- ---
- --- .\knapsack\knapsack.cpp
- #include <iostream>
- #include <vector>
- using namespace std;
- /**
- * @param itemCount The number of items to pick from
- * @param sackWeight The weight of the knapsack
- * @param weights The weights to pick from
- * @param profits The profits relating to the weights
- * @param pickSeq The picking sequence of the items (0 or 1)
- */
- int knapsackForItem(int itemCount, int sackWeight, vector<int> const &weights, vector<int> const &profits, vector<bool> &pickSeq, vector<vector<int>> memTable = {})
- {
- // If the item is non-existent or the sack weight
- // is non-existent, then return
- if (itemCount <= 0 || sackWeight <= 0)
- return 0;
- // Check if we have memoized answer
- if (memTable.size() != 0 && memTable[itemCount - 1][sackWeight - 1] != -1)
- {
- return memTable[itemCount - 1][sackWeight - 1];
- }
- // If the weight of the current item is more than
- // the sack weight, then return
- if (weights[itemCount - 1] > sackWeight)
- {
- // We cannot fit this item in the sack
- pickSeq[itemCount - 1] = false;
- // Get the result from the table if possible
- if (memTable.size() != 0 && memTable[itemCount - 1][sackWeight - 1] != -1)
- return memTable[itemCount - 1][sackWeight - 1];
- // Memoize the result
- int result = knapsackForItem(itemCount - 1, sackWeight, weights, profits, pickSeq);
- if (memTable.size() != 0)
- {
- memTable[itemCount - 1][sackWeight - 1] = result;
- return memTable[itemCount - 1][sackWeight - 1];
- }
- // We're not given a memTable
- return result;
- }
- /* Else, we need to get the result where the profit is maximum */
- // Not picking the item
- int notPicking = knapsackForItem(itemCount - 1, sackWeight, weights, profits, pickSeq);
- // Picking the item
- int picking = knapsackForItem(itemCount - 1, sackWeight - weights[itemCount - 1], weights, profits, pickSeq) + profits[itemCount - 1];
- // If we're given a memTable
- if (memTable.size() != 0)
- {
- memTable[itemCount - 1][sackWeight - 1] = max(notPicking, picking);
- }
- if (notPicking > picking)
- {
- pickSeq[itemCount - 1] = false;
- std::cout << "Not picking the item with weight: " << weights[itemCount - 1] << "\n";
- return notPicking;
- }
- else
- {
- pickSeq[itemCount - 1] = true;
- std::cout << "Picking the item with weight: " << weights[itemCount - 1] << "\n";
- return picking;
- }
- }
- /**
- * Returns the answer using memoized
- */
- int optimalKnapsack(int itemCount, int sackWeight, vector<int> const &weights, vector<int> const &profits, vector<bool> &pickSeq)
- {
- // Make a memoized table
- vector<vector<int>> memTable(itemCount, vector<int>(sackWeight, -1));
- // Return the memoized version
- return knapsackForItem(itemCount, sackWeight, weights, profits, pickSeq, memTable);
- }
- int main()
- {
- /*
- Consider the problem where
- weights = {3, 4, 6, 5}
- profits = {2, 3, 1, 4}
- The max weight is: 8 Kgs
- */
- // The weights for the item to pick
- vector<int> weights{3, 4, 6, 5};
- // The profits corresponding to those items
- vector<int> profits{2, 3, 1, 4};
- // Number of items to pick from
- const int itemCount = 4;
- // The maximum carry weight for the sack
- const int maxWeight = 8;
- // The picking sequence
- vector<bool> pickSeq(itemCount, false);
- int maxProfit = optimalKnapsack(itemCount, maxWeight, weights, profits, pickSeq);
- std::cout << "Max profit from the knapsack is: " << maxProfit << std::endl;
- // Picking sequence
- std::cout << "Answer to 0-1 Knapsack: [ ";
- for (bool const &didPick : pickSeq)
- {
- std::cout << didPick << " ";
- }
- std::cout << "]" << std::endl;
- return 0;
- }
- ---
- --- .\multilpication\strassen.cpp
- #include <iostream>
- #include <vector>
- using namespace std;
- // Function to add two matrices
- vector<vector<int>> matrixAdd(const vector<vector<int>> &A, const vector<vector<int>> &B)
- {
- int n = A.size();
- vector<vector<int>> C(n, vector<int>(n));
- for (int i = 0; i < n; i++)
- {
- for (int j = 0; j < n; j++)
- {
- C[i][j] = A[i][j] + B[i][j];
- }
- }
- return C;
- }
- // Function to subtract two matrices
- vector<vector<int>> matrixSubtract(const vector<vector<int>> &A, const vector<vector<int>> &B)
- {
- int n = A.size();
- vector<vector<int>> C(n, vector<int>(n));
- for (int i = 0; i < n; i++)
- {
- for (int j = 0; j < n; j++)
- {
- C[i][j] = A[i][j] - B[i][j];
- }
- }
- return C;
- }
- // Function to multiply two matrices using Strassen's algorithm
- vector<vector<int>> strassenMultiply(const vector<vector<int>> &A, const vector<vector<int>> &B)
- {
- int n = A.size();
- // Base case: If the matrix size is 1x1
- if (n == 1)
- {
- vector<vector<int>> C(1, vector<int>(1));
- C[0][0] = A[0][0] * B[0][0];
- return C;
- }
- // Splitting matrices into quadrants
- int mid = n / 2;
- vector<vector<int>> A11(mid, vector<int>(mid)), A12(mid, vector<int>(mid)), A21(mid, vector<int>(mid)), A22(mid, vector<int>(mid));
- vector<vector<int>> B11(mid, vector<int>(mid)), B12(mid, vector<int>(mid)), B21(mid, vector<int>(mid)), B22(mid, vector<int>(mid));
- for (int i = 0; i < mid; i++)
- {
- for (int j = 0; j < mid; j++)
- {
- A11[i][j] = A[i][j];
- A12[i][j] = A[i][j + mid];
- A21[i][j] = A[i + mid][j];
- A22[i][j] = A[i + mid][j + mid];
- B11[i][j] = B[i][j];
- B12[i][j] = B[i][j + mid];
- B21[i][j] = B[i + mid][j];
- B22[i][j] = B[i + mid][j + mid];
- }
- }
- // Calculating intermediate matrices
- vector<vector<int>> M1 = strassenMultiply(matrixAdd(A11, A22), matrixAdd(B11, B22));
- vector<vector<int>> M2 = strassenMultiply(matrixAdd(A21, A22), B11);
- vector<vector<int>> M3 = strassenMultiply(A11, matrixSubtract(B12, B22));
- vector<vector<int>> M4 = strassenMultiply(A22, matrixSubtract(B21, B11));
- vector<vector<int>> M5 = strassenMultiply(matrixAdd(A11, A12), B22);
- vector<vector<int>> M6 = strassenMultiply(matrixSubtract(A21, A11), matrixAdd(B11, B12));
- vector<vector<int>> M7 = strassenMultiply(matrixSubtract(A12, A22), matrixAdd(B21, B22));
- // Calculating result matrix
- vector<vector<int>> C(n, vector<int>(n));
- vector<vector<int>> C11 = matrixAdd(matrixSubtract(matrixAdd(M1, M4), M5), M7);
- vector<vector<int>> C12 = matrixAdd(M3, M5);
- vector<vector<int>> C21 = matrixAdd(M2, M4);
- vector<vector<int>> C22 = matrixAdd(matrixSubtract(matrixAdd(M1, M3), M2), M6);
- // Combining result quadrants into the result matrix
- for (int i = 0; i < mid; i++)
- {
- for (int j = 0; j < mid; j++)
- {
- C[i][j] = C11[i][j];
- C[i][j + mid] = C12[i][j];
- C[i + mid][j] = C21[i][j];
- C[i + mid][j + mid] = C22[i][j];
- }
- }
- return C;
- }
- // Function to print a matrix
- void printMatrix(const vector<vector<int>> &matrix)
- {
- int n = matrix.size();
- for (int i = 0; i < n; i++)
- {
- for (int j = 0; j < n; j++)
- {
- cout << matrix[i][j] << " ";
- }
- cout << endl;
- }
- }
- int main()
- {
- vector<vector<int>> A = {{1, 2}, {3, 4}};
- vector<vector<int>> B = {{5, 6}, {7, 8}};
- cout << "Matrix A:" << endl;
- printMatrix(A);
- cout << endl;
- cout << "Matrix B:" << endl;
- printMatrix(B);
- cout << endl;
- cout << "Result of matrix multiplication (Strassen's algorithm):" << endl;
- vector<vector<int>> C = strassenMultiply(A, B);
- printMatrix(C);
- return 0;
- }
- ---
- --- .\sorting\countSort.hpp
- #ifndef COUNT_SORT
- #define COUNT_SORT
- /**
- * Sorts the array using count-sort
- * @param array The array to sort
- * @param size The length of the array to sort
- */
- void countSort(int array[], int size)
- {
- int maxElement = array[0];
- for (int i = 1; i < size; i++)
- {
- if (array[i] > maxElement)
- maxElement = array[i];
- }
- // Initialize count array with all elements as 0
- int *count = new int[maxElement + 1];
- // Initialize it with zeros
- for (size_t j = 0; j < maxElement + 1; j++)
- count[j] = 0;
- // Count the occurrences of each element
- for (int i = 0; i < size; i++)
- {
- count[array[i]]++;
- }
- // Fill the original array with sorted elements
- int index = 0;
- for (int i = 0; i <= maxElement; i++)
- {
- while (count[i] > 0)
- {
- array[index++] = i;
- count[i]--;
- }
- }
- delete[] count;
- }
- #endif
- ---
- --- .\sorting\heapSort.hpp
- #ifndef HEAP_SORT
- #define HEAP_SORT
- /**
- * Swaps two values
- * @param a The first value to swap
- * @param b The second value to swap with
- */
- template <class T>
- void swap(T &a, T &b)
- {
- T temp = a;
- a = b;
- b = temp;
- }
- /**
- * Builds a max heap from the given array
- * @param array The array to perform max-heapify on
- * @param size The length of the array
- * @param i The index to start heapify with '0' for root
- */
- void maxHeapify(int array[], int size, int i)
- {
- int largest = i; // Initialize largest as the root
- int left = 2 * i + 1; // Left child of the root
- int right = 2 * i + 2; // Right child of the root
- // Find the new largest element
- if (left < size && array[left] > array[largest])
- largest = left;
- if (right < size && array[right] > array[largest])
- largest = right;
- // If the largest is not the root, then swap
- if (largest != i)
- {
- swap(array[i], array[largest]);
- // Recursively heapify the affected sub-tree
- maxHeapify(array, size, largest);
- }
- }
- /**
- * Sorts the array using heap sort
- * @param array The array to sort
- * @param size The length of the array
- */
- void heapSort(int array[], int size)
- {
- // Build a max-heap (rearrange array)
- for (int i = (size / 2) - 1; i >= 0; i--)
- {
- maxHeapify(array, size, i);
- }
- // One-by-one extract an element from the heap
- for (int i = size - 1; i >= 0; i--)
- {
- // Move the current root to the end
- swap(array[0], array[i]);
- // Call the max heapify on the reduced heap
- maxHeapify(array, i, 0);
- }
- }
- #endif
- ---
- --- .\sorting\insertionSort.hpp
- #ifndef INSERTION_SORT
- #define INSERTION_SORT
- /**
- * Insertion Sort (in-place)
- * @param array The array to sort
- * @param size The size of the array
- */
- void insertionSort(int array[], int size)
- {
- for (int i = 1; i < size; i++)
- {
- int key = array[i];
- int j = i - 1;
- while (j >= 0 && array[j] > key)
- {
- // Shift the elements to the right
- array[j + 1] = array[j];
- j = j - 1;
- }
- array[j + 1] = key;
- }
- }
- #endif
- ---
- --- .\sorting\main.cpp
- #include <iostream>
- // Internal Dependencies
- #include "insertionSort.hpp"
- #include "mergeSort.hpp"
- // #include "heapSort.hpp"
- #include "quickSort.hpp"
- /**
- * @param array The array to print
- * @param size The size of the array
- * @param endline The character at the end of the line
- */
- template <class T>
- void printArray(T array[], int size, char endline = '\0')
- {
- std::cout << "[ ";
- for (int i = 0; i < size; i++)
- std::cout << array[i] << " ";
- std::cout << "]" << endline;
- }
- #include "countSort.hpp"
- /**
- * The driver function of the code
- */
- int main()
- {
- int a[] = {1, 4, 7, 4, 2, 8, 1, 9, 0, 3};
- // Get the size of the array
- int size = sizeof(a) / sizeof(a[0]);
- // Before sorting
- printArray(a, size, '\n');
- // quickSort(a, 0, size - 1);
- countSort(a, size);
- // After sorting
- printArray(a, size, '\n');
- return 0;
- }
- ---
- --- .\sorting\mergeSort.hpp
- #ifndef MERGE_SORT
- #define MERGE_SORT
- /**
- * Merges the sub-arrays
- */
- void merge(int array[], int const left, int const mid, int const right)
- {
- int const subArrayLeft = mid - left + 1;
- int const subArrayRight = right - mid;
- // Create new temporary arrays
- int *leftArray = new int[subArrayLeft];
- int *rightArray = new int[subArrayRight];
- // Copy the data of sub-arrays to this new array
- for (size_t i = 0; i < subArrayLeft; i++)
- {
- leftArray[i] = array[left + i];
- }
- for (size_t i = 0; i < subArrayRight; i++)
- {
- rightArray[i] = array[mid + 1 + i];
- }
- int i = 0; // Iterator for the left sub-array
- int j = 0; // Iterator for the right sub-array
- int k = left; // Iterator for the merged array
- while (i < subArrayLeft && j < subArrayRight)
- {
- if (leftArray[i] <= rightArray[j])
- {
- // Choose the element from the left sub-array
- array[k] = leftArray[i];
- i++;
- }
- else
- {
- // Choose the element from the right sub-array
- array[k] = rightArray[j];
- j++;
- }
- // Increment the sub-array iterator
- k++;
- }
- // Add the remaining left array elements
- while (i < subArrayLeft)
- {
- array[k] = leftArray[i];
- i++;
- k++;
- }
- // Add the remaining right array elements
- while (j < subArrayRight)
- {
- array[k] = rightArray[j];
- j++;
- k++;
- }
- delete[] leftArray;
- delete[] rightArray;
- }
- /**
- * Sorts the array using merge sort, (in-place)
- * @param array The array to sort
- * @param begin The beginning of the index in the array
- * @param end The end index of the array (should be 'length-1')
- */
- void mergeSort(int array[], int const begin, int const end)
- {
- if (begin >= end)
- return;
- // Get the middle of the array and divide it there
- int mid = (begin + end) / 2;
- // Sort the left half of the array
- mergeSort(array, begin, mid);
- // Sort the right half of the array
- mergeSort(array, mid + 1, end);
- // Merge the two halves
- merge(array, begin, mid, end);
- }
- #endif
- ---
- --- .\sorting\quickSort.hpp
- #ifndef QUICK_SORT
- #define QUICK_SORT
- /**
- * Swaps two values
- * @param a The first value to swap
- * @param b The second value to swap with
- */
- template <class T>
- void swap(T &a, T &b)
- {
- T temp = a;
- a = b;
- b = temp;
- }
- /**
- * Function to partition the array and return the pivot index
- */
- int partition(int array[], int low, int high)
- {
- // Choosing the last element as pivot
- int pivot = array[high];
- // Index of the smaller element
- int i = low - 1;
- for (int j = low; j <= high - 1; j++)
- {
- // If the current element is smaller than or equal to pivot
- if (array[j] <= pivot)
- {
- i++; // Increment the index of smaller element
- swap(array[i], array[j]);
- }
- }
- swap(array[i + 1], array[high]);
- return (i + 1);
- }
- void quickSort(int array[], int low, int high)
- {
- if (low >= high)
- return;
- // Partitioning index
- int pi = partition(array, low, high);
- // Separately sort elements before and after partition
- quickSort(array, low, pi - 1);
- quickSort(array, pi + 1, high);
- }
- #endif
- ---
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement