├── .gitattributes ├── .vs └── Fun Practice 3 │ └── v14 │ └── .suo ├── 10_CityTraffic.cpp ├── 11_WeightedPath.cpp ├── 12_FarthestNode.cpp ├── 13_VertexCovering.cpp ├── 14_HamiltonianPath.cpp ├── 15_KaprekarsConstant.cpp ├── 16_TransitivityRelations.cpp ├── 17_OptimalAssignment.cpp ├── 18_IntersectingLines.cpp ├── 19_ChessboardTraveling.cpp ├── 1_SudokuQuadrantChecker.cpp ├── 20_KnightJumps.cpp ├── 21_BlackjackHighest.cpp ├── 22_QueenCheck.cpp ├── 23_QuickKnight.cpp ├── 24_StepWalking.cpp ├── 25_PentagonalNumber.cpp ├── 26_MaximalSquare.cpp ├── 27_WildcardCharacters.cpp ├── 28_BracketCombinations.cpp ├── 29_ArrayRotation.cpp ├── 2_Calculator.cpp ├── 30_ArrayCouples.cpp ├── 31_SimpleSAT.cpp ├── 32_MatrixDeterminant.cpp ├── 33_CountingAnagrams.cpp ├── 34_BipartiteMatching.cpp ├── 35_NoughtsDeterminer.cpp ├── 36_SquareFigures.cpp ├── 37_AlphabetRunEncryption.cpp ├── 38_SymmetricMatrix.cpp ├── 39_SwitchSort.cpp ├── 3_PatternChaser.cpp ├── 40_MatrixBorder.cpp ├── 41_ArrayJumping.cpp ├── 42_PolynomialExpansion.cpp ├── 43_MatchingCouples.cpp ├── 4_GasStation.cpp ├── 5_ReversePolishNotation.cpp ├── 6_MaximalRectangle.cpp ├── 7_LCS.cpp ├── 8_ParallelSums.cpp ├── 9_ShortestPath.cpp ├── Debug ├── 32_MatrixDeterminant.obj ├── Fun Practice 3.Build.CppClean.log ├── Fun Practice 3.exe ├── Fun Practice 3.log ├── Fun Practice 3.tlog │ ├── CL.read.1.tlog │ ├── CL.write.1.tlog │ ├── Fun Practice 3.lastbuildstate │ ├── cl.command.1.tlog │ ├── link.command.1.tlog │ ├── link.read.1.tlog │ └── link.write.1.tlog └── vc120.idb ├── Fun Practice 3.VC.db ├── Fun Practice 3.sln ├── Fun Practice 3.vcxproj ├── Fun Practice 3.vcxproj.filters ├── Fun Practice 3.vcxproj.user ├── README.md ├── code2.cpp └── extra_FoldersAndCows.cpp /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.vs/Fun Practice 3/v14/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gutty333/Hard-Programming-Challenges/f63f6d97fab7fe48b41bbe1671035d82d3f953ba/.vs/Fun Practice 3/v14/.suo -------------------------------------------------------------------------------- /10_CityTraffic.cpp: -------------------------------------------------------------------------------- 1 | // For this challenge you will be finding the maximum traffic that will enter a node. 2 | /* 3 | have the function CityTraffic(strArr) read strArr which will be a representation of an undirected graph in a form similar to an adjacency list. Each element in the input will contain an integer which will represent the population for that city, and then that will be followed by a comma separated list of its neighboring cities and their populations (these will be separated by a colon). For example: strArr may be 4 | ["1:[5]", "4:[5]", "3:[5]", "5:[1,4,3,2]", "2:[5,15,7]", "7:[2,8]", "8:[7,38]", "15:[2]", "38:[8]"]. This graph then looks like the following picture: 5 | 6 | Each node represents the population of that city and each edge represents a road to that city. Your goal is to determine the maximum traffic that would occur via a single road if everyone decided to go to that city. For example: if every single person in all the cities decided to go to city 7, then via the upper road the number of people coming in would be (8 + 38) = 46. If all the cities beneath city 7 decided to go to it via the lower road, the number of people coming in would be (2 + 15 + 1 + 3 + 4 + 5) = 30. So the maximum traffic coming into the city 7 would be 46 because the maximum value of (30, 46) = 46. 7 | 8 | Your program should determine the maximum traffic for every single city and return the answers in a comma separated string in the format: city:max_traffic,city:max_traffic,... The cities should be outputted in sorted order by the city number. For the above example, the output would therefore be: 1:82,2:53,3:80,4:79,5:70,7:46,8:38,15:68,38:45. The cities will all be unique positive integers and there will not be any cycles in the graph. There will always be at least 2 cities in the graph. 9 | 10 | */ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | using namespace std; 21 | 22 | /* 23 | Our first steps will be to set up the graph 24 | 25 | One approach we can use is to check every city 26 | Once we arrive at a current city we now check its neighbors, the number of neighbors determine the possible numbers of incoming traffic. Example if a city has 2 neighbors, than is there will be 2 incoming traffics into that city. 27 | 28 | We can perform a BFS from each neighbor start point and get a total of the population. 29 | We store the population of each incoming traffic and record only the maximum possible traffic for that city. 30 | */ 31 | 32 | // hash map to quickly index the vertices 33 | map nodeIndex; 34 | 35 | // a structure representing each vertex 36 | struct node 37 | { 38 | int cost; 39 | bool visited; 40 | }; 41 | 42 | // method to create a connection between 2 nodes 43 | void makePairs(vector >& graph, int source, int partner) 44 | { 45 | // making the edge connection 46 | graph[nodeIndex[source]].push_back(graph[nodeIndex[partner]][0]); 47 | } 48 | 49 | // method to create our graph 50 | void createGraph(vector >& graph, string arr[], int size) 51 | { 52 | // traverse the string array to first extract the cost of each node 53 | for (int x = 0; x < size; x++) 54 | { 55 | // variable to collect the string number 56 | string num; 57 | 58 | for (int y = 0; y < arr[x].length(); y++) 59 | { 60 | // condition to get the cost of the current node 61 | if (arr[x][y] >= '0' && arr[x][y] <= '9') 62 | { 63 | num.push_back(arr[x][y]); 64 | } 65 | else 66 | { 67 | break; 68 | } 69 | } 70 | 71 | // converting from string to int 72 | int costValue; 73 | istringstream value(num); 74 | value >> costValue; 75 | 76 | // adding the key value pair to our table 77 | nodeIndex.insert(make_pair(costValue, x)); 78 | 79 | // creating the node for our graph 80 | graph[x].push_back(new node); 81 | 82 | // setting its default values 83 | graph[x][0]->cost = costValue; 84 | graph[x][0]->visited = false; 85 | } 86 | } 87 | 88 | // method to set up the connections 89 | void addConnections(vector >& graph, string arr[], int size) 90 | { 91 | for (int x = 0; x < size; x++) 92 | { 93 | string num; 94 | 95 | // loop to check nodes that connect to the current node 96 | int start = arr[x].find("["); 97 | for (int y = start+1; y < arr[x].length(); y++) 98 | { 99 | if (arr[x][y] >= '0' && arr[x][y] <= '9') 100 | { 101 | num.push_back(arr[x][y]); 102 | } 103 | else 104 | { 105 | // if current character does not represent a number than convert the string value we collected 106 | int valueCost; 107 | istringstream convert(num); 108 | convert >> valueCost; 109 | 110 | // here we call our make pair function to create the connection 111 | // we are connecting the current node to the current cost extracted 112 | makePairs(graph, graph[x][0]->cost, valueCost); 113 | 114 | // reset the string number variable 115 | num.clear(); 116 | } 117 | } 118 | } 119 | } 120 | 121 | // each time we call this method it will reset the visit signal of each node back to false 122 | void graphReset(vector >& graph) 123 | { 124 | for (int x = 0; x < graph.size(); x++) 125 | { 126 | graph[x][0]->visited = false; 127 | } 128 | } 129 | 130 | // applying BFS from the current source, as we traverse we add up the population 131 | int bfsSum(vector < vector > graph, vector source) 132 | { 133 | queue < vector > list; 134 | 135 | list.push(source); 136 | 137 | int total = 0; // keep track of the total cost from traversing from this source node 138 | 139 | while (!list.empty()) 140 | { 141 | vector currentNode = list.front(); 142 | currentNode[0]->visited = true; 143 | total += currentNode[0]->cost; 144 | list.pop(); 145 | 146 | // checking the neighbors 147 | for (int x = 1; x < currentNode.size(); x++) 148 | { 149 | if (!currentNode[x]->visited) 150 | { 151 | // adding valid neighbors to our queue 152 | list.push(graph[nodeIndex[currentNode[x]->cost]]); 153 | } 154 | } 155 | } 156 | 157 | return total; 158 | } 159 | 160 | // sorts our 2d vector which stores the city and max traffic 161 | // using a quick bubble sort to sort our list 162 | void sortResult(vector< vector >& list) 163 | { 164 | bool swap; 165 | 166 | do 167 | { 168 | swap = false; 169 | 170 | for (int row = 0; row < list.size()-1; row++) 171 | { 172 | if (list[row][0] > list[row + 1][0]) 173 | { 174 | int temp1 = list[row][0]; 175 | int temp2 = list[row][1]; 176 | 177 | list[row][0] = list[row + 1][0]; 178 | list[row][1] = list[row + 1][1]; 179 | 180 | list[row + 1][0] = temp1; 181 | list[row + 1][1] = temp2; 182 | 183 | swap = true; 184 | } 185 | } 186 | 187 | } while (swap); 188 | } 189 | 190 | string CityTraffic(string strArr[], int size) 191 | { 192 | nodeIndex.clear(); // clearing our hash table 193 | 194 | // creating our graph and making the connection 195 | vector > graph(size); 196 | createGraph(graph, strArr, size); 197 | addConnections(graph, strArr, size); 198 | 199 | string result = ""; // output the final result 200 | vector < vector > resultOrder(size); // will store the integer values of city:max traffic 201 | 202 | /* 203 | we analyze each city here and check for all possible routes of incoming traffic 204 | we collect the total population of people coming in from each route 205 | in each calculation we are only keeping track of the highest incoming population 206 | */ 207 | for (int x = 0; x < graph.size(); x++) 208 | { 209 | // reseting our graph each time 210 | // this step is mandatory so that BFS checks all the valid neighbors 211 | graphReset(graph); 212 | 213 | int high = 0; // we store the highest possible incoming traffic 214 | 215 | // we set the current city as visited 216 | graph[x][0]->visited = true; 217 | 218 | // we take the neighbors 219 | for (int y = 1; y < graph[x].size(); y++) 220 | { 221 | // calling our BFS sum it will return the total cost for this route 222 | int incomingTraffic = bfsSum(graph, graph[nodeIndex[graph[x][y]->cost]]); 223 | 224 | // updating our highest incoming traffic 225 | if ( incomingTraffic > high) 226 | { 227 | high = incomingTraffic; 228 | } 229 | } 230 | 231 | // storing our values in a list for sorting later 232 | resultOrder[x].push_back(graph[x][0]->cost); 233 | resultOrder[x].push_back(high); 234 | } 235 | 236 | // sorting our list 237 | sortResult(resultOrder); 238 | 239 | // loop to extract the integer values and convert back to a final string result 240 | for (int x = 0; x < resultOrder.size(); x++) 241 | { 242 | stringstream convert; 243 | convert << resultOrder[x][0]; 244 | result += convert.str(); 245 | 246 | result += ':'; 247 | 248 | convert.str(""); 249 | convert << resultOrder[x][1]; 250 | result += convert.str(); 251 | result += ','; 252 | } 253 | 254 | result.pop_back(); // removing the last character 255 | return result; 256 | } 257 | 258 | int main() 259 | { 260 | string A[] = { "1:[5]", "4:[5]", "3:[5]", "5:[1,4,3,2]", "2:[5,15,7]", "7:[2,8]", "8:[7,38]", "15:[2]", "38:[8]" }; 261 | string B[] = { "1:[5]", "2:[5]", "3:[5]", "4:[5]", "5:[1,2,3,4]" }; 262 | string C[] = { "1:[5]", "2:[5,18]", "3:[5,12]", "4:[5]", "5:[1,2,3,4]", "18:[2]", "12:[3]" }; 263 | 264 | cout << CityTraffic(A, sizeof(A)/sizeof(A[0])) << endl; // 1:82,2:53,3:80,4:79,5:70,7:46,8:38,15:68,38:45 265 | cout << CityTraffic(B, sizeof(B) / sizeof(B[0])) << endl; // 1:14,2:13,3:12,4:11,5:4 266 | cout << CityTraffic(C, sizeof(C) / sizeof(C[0])) << endl; // 1:44,2:25,3:30,4:41,5:20,12:33,18:27 267 | 268 | return 0; 269 | } -------------------------------------------------------------------------------- /11_WeightedPath.cpp: -------------------------------------------------------------------------------- 1 | // For this challenge you will have to determine the shortest weighted path from one node to an end node. 2 | /* 3 | have the function WeightedPath(strArr) take strArr which will be an array of strings which models a non-looping weighted Graph. The structure of the array will be as follows: The first element in the array will be the number of nodes N (points) in the array as a string. The next N elements will be the nodes which can be anything (A, B, C .. Brick Street, Main Street .. etc.). Then after the Nth element, the rest of the elements in the array will be the connections between all of the nodes along with their weights (integers) separated by the pipe symbol (|). They will look like this: (A|B|3, B|C|12 .. Brick Street|Main Street|14 .. etc.). Although, there may exist no connections at all. 4 | 5 | An example of strArr may be: ["4","A","B","C","D","A|B|1","B|D|9","B|C|3","C|D|4"]. Your program should return the shortest path when the weights are added up from node to node from the first Node to the last Node in the array separated by dashes. So in the example above the output should be A-B-C-D. Here is another example with strArr being ["7","A","B","C","D","E","F","G","A|B|1","A|E|9","B|C|2","C|D|1","D|F|2","E|D|6","F|G|2"]. The output for this array should be A-B-C-D-F-G. There will only ever be one shortest path for the array. If no path between the first and last node exists, return -1. The array will at minimum have two nodes. Also, the connection A-B for example, means that A can get to B and B can get to A. A path may not go through any Node more than once. 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | using namespace std; 16 | 17 | /* 18 | For this problem we can utilize the concept of single source shortest path by implementing Dijkstra's algorithm 19 | Reusing BFS as a base, we now need to perform an edge relaxation on the most optimal path for each node 20 | When an optimal path is found we have to update its cost and its parent 21 | 22 | Before starting each node will have a cost of infinity and for each iteration of BFS we are checking if the current path is a better choice than the previous path found for this node. 23 | */ 24 | 25 | // global variables 26 | const string defaultParent = "unknown"; 27 | const int defaultCost = 1000 * 100; 28 | 29 | map hashTable; // hash table to quickly reference the nodes 30 | 31 | // structure representing a weighted connection in our graph 32 | struct edgeConnection 33 | { 34 | string neighbor; 35 | int edgeWeight; 36 | }; 37 | 38 | // structure representing a node in our graph 39 | struct node 40 | { 41 | string name; 42 | int cost; 43 | string parent; 44 | vector connections; 45 | }; 46 | 47 | 48 | // method to create our nodes for our graph 49 | void createGraph(vector & graph, string nodeValues[], int size) 50 | { 51 | for (int x = 1; x <= size; x++) 52 | { 53 | // creating the nodes 54 | graph.push_back(new node); 55 | graph[x - 1]->name = nodeValues[x]; 56 | graph[x - 1]->cost = defaultCost; 57 | graph[x - 1]->parent = defaultParent; 58 | 59 | // adding to our hash table 60 | hashTable[nodeValues[x]] = x - 1; 61 | } 62 | } 63 | 64 | // method to make the connections 65 | void makeConnections(vector & graph, string neighbors[], int index, int size) 66 | { 67 | for (int x = index; x < size; x++) 68 | { 69 | // extracting the contents from the string 70 | // we take the 2 nodes that are connecting and the edge weight value 71 | int breakpoint = neighbors[x].find('|'); 72 | string node1 = neighbors[x].substr(0, breakpoint); 73 | int breakpoint2 = neighbors[x].find('|', breakpoint + 1); 74 | string node2 = neighbors[x].substr(breakpoint + 1, breakpoint2 - (breakpoint + 1)); 75 | 76 | // getting the edge value 77 | string value = neighbors[x].substr(breakpoint2 + 1); 78 | stringstream convert(value); 79 | int edge; 80 | convert >> edge; 81 | 82 | // adding the neighbors to the corresponding nodes 83 | int pair1 = hashTable[node1]; 84 | int pair2 = hashTable[node2]; 85 | 86 | edgeConnection temp1; 87 | temp1.neighbor = node2; 88 | temp1.edgeWeight = edge; 89 | 90 | edgeConnection temp2; 91 | temp2.neighbor = node1; 92 | temp2.edgeWeight = edge; 93 | 94 | graph[pair1]->connections.push_back(temp1); 95 | graph[pair2]->connections.push_back(temp2); 96 | } 97 | } 98 | 99 | 100 | string WeightedPath(string strArr[], int size) 101 | { 102 | // getting the total number of nodes for our graph 103 | int nodeSize; 104 | istringstream value(strArr[0]); 105 | value >> nodeSize; 106 | 107 | // creating our graph with default values 108 | vector graph; 109 | createGraph(graph, strArr, nodeSize); 110 | 111 | // making the edge connections 112 | makeConnections(graph, strArr, nodeSize + 1, size); 113 | 114 | 115 | string source = graph[0]->name; 116 | string destination = graph[graph.size() - 1]->name; 117 | 118 | // doing our operations for the single source shortest path 119 | // first we set up a queue and insert the source node 120 | // note the cost of our source is set to zero 121 | queue list; 122 | graph[0]->cost = 0; 123 | list.push(graph[0]); 124 | 125 | while (!list.empty()) 126 | { 127 | // get current node from our queue to analyze 128 | node* current = list.front(); 129 | list.pop(); 130 | 131 | // loop to check the neighbors of the current node 132 | if (current->name != destination) 133 | { 134 | for (int x = 0; x < current->connections.size(); x++) 135 | { 136 | int index = hashTable[current->connections[x].neighbor]; 137 | int edgecost = current->connections[x].edgeWeight; 138 | 139 | if (graph[index]->name != current->parent) 140 | { 141 | // condition to check if the current path is more optimal than the last 142 | // if true we perform edge relaxation and update its parent 143 | if (current->cost + edgecost < graph[index]->cost) 144 | { 145 | // here we update its cost and parent 146 | graph[index]->cost = current->cost + edgecost; 147 | graph[index]->parent = current->name; 148 | 149 | 150 | // adding to our queue 151 | list.push(graph[index]); 152 | } 153 | } 154 | } 155 | } 156 | } 157 | 158 | // condition to check if we were able to reach the destination 159 | if (graph[hashTable[destination]]->parent == defaultParent) 160 | { 161 | return "-1"; 162 | } 163 | else 164 | { 165 | // collecting our shortest path 166 | string result; 167 | 168 | node* current = graph[hashTable[destination]]; 169 | 170 | // we start at the destination and collect the parents in each iteration 171 | while (current) 172 | { 173 | result += current->name; 174 | result += '-'; 175 | 176 | if (current->parent == defaultParent) 177 | { 178 | result.pop_back(); 179 | reverse(result.begin(), result.end()); 180 | return result; 181 | } 182 | else 183 | { 184 | current = graph[hashTable[current->parent]]; 185 | } 186 | } 187 | } 188 | } 189 | 190 | int main() 191 | { 192 | string A[] = { "4", "A", "B", "C", "D", "A|B|1", "B|D|9", "B|C|3", "C|D|4" }; 193 | string B[] = { "7", "A", "B", "C", "D", "E", "F", "G", "A|B|1", "A|E|9", "B|C|2", "C|D|1", "D|F|2", "E|D|6", "F|G|2" }; 194 | string C[] = { "4", "A", "B", "C", "D", "A|B|2", "C|B|11", "C|D|3", "B|D|2" }; 195 | string D[] = { "4", "x", "y", "z", "w", "x|y|2", "y|z|14", "z|y|31" }; 196 | 197 | cout << WeightedPath(A, sizeof(A) / sizeof(A[0])) << endl; // A-B-C-D 198 | cout << WeightedPath(B, sizeof(B) / sizeof(B[0])) << endl; // A-B-C-D-F-G 199 | cout << WeightedPath(C, sizeof(C) / sizeof(C[0])) << endl; // A-B-D 200 | cout << WeightedPath(D, sizeof(D) / sizeof(D[0])) << endl; // -1 201 | return 0; 202 | } -------------------------------------------------------------------------------- /12_FarthestNode.cpp: -------------------------------------------------------------------------------- 1 | // For this challenge you will determine what nodes are farthest apart. 2 | /* 3 | have the function FarthestNodes(strArr) read strArr which will be an array of hyphenated letters representing paths between those two nodes. For example: ["a-b","b-c","b-d"] means that there is a path from node a to b (and b to a), b to c, and b to d. Your program should determine the longest path that exists in the graph and return the length of that path. So for the example above, your program should return 2 because of the paths a-b-c and d-b-c. The path a-b-c also means that there is a path c-b-a. No cycles will exist in the graph and every node will be connected to some other node in the graph. 4 | */ 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | /* 13 | one approach is to treat each node as a possible starting point from where we can expand and perform BFS 14 | at each step of our BFS we update the cost of each node 15 | this cost determines the length from the current starting node 16 | we repeat this process for all the nodes in our graph and keep track of the highest length 17 | */ 18 | 19 | map hashTable; 20 | 21 | // structure to represent each node in the graph 22 | struct node 23 | { 24 | int cost; 25 | char name; 26 | bool visited; 27 | vector neighbors; 28 | }; 29 | 30 | // method to create the nodes in our graph 31 | void createGraph(vector & graph, string values[], int size) 32 | { 33 | int index = 0; 34 | 35 | for (int x = 0; x < size; x++) 36 | { 37 | char node1 = values[x][0]; 38 | char node2 = values[x][2]; 39 | 40 | // check if the current node is already in our hash table 41 | // this determines if we need to add it to our graph 42 | // for the first iteration we add the first 2 letters analyzed 43 | if (x == 0) 44 | { 45 | hashTable[node1] = index; 46 | 47 | // making the node 48 | graph.push_back(new node); 49 | graph[index]->cost = 0; 50 | graph[index]->visited = false; 51 | graph[index]->name = node1; 52 | index++; 53 | 54 | hashTable[node2] = index; 55 | graph.push_back(new node); 56 | graph[index]->cost = 0; 57 | graph[index]->visited = false; 58 | graph[index]->name = node2; 59 | index++; 60 | } 61 | else 62 | { 63 | if (hashTable.count(node1) <= 0) 64 | { 65 | hashTable[node1] = index; 66 | graph.push_back(new node); 67 | graph[index]->cost = 0; 68 | graph[index]->visited = false; 69 | graph[index]->name = node1; 70 | index++; 71 | } 72 | 73 | if (hashTable.count(node2) <= 0) 74 | { 75 | hashTable[node2] = index; 76 | graph.push_back(new node); 77 | graph[index]->cost = 0; 78 | graph[index]->visited = false; 79 | graph[index]->name = node2; 80 | index++; 81 | } 82 | } 83 | } 84 | } 85 | 86 | // method to create the pair connections 87 | void makeConnections(vector graph, string values[], int size) 88 | { 89 | for (int x = 0; x < size; x++) 90 | { 91 | char node1 = values[x][0]; 92 | char node2 = values[x][2]; 93 | 94 | // making the bidirectional edge connection between the 2 nodes 95 | graph[hashTable[node1]]->neighbors.push_back(node2); 96 | graph[hashTable[node2]]->neighbors.push_back(node1); 97 | } 98 | } 99 | 100 | // method to reset our graph to default values 101 | void resetGraph(vector graph) 102 | { 103 | for (int x = 0; x < graph.size(); x++) 104 | { 105 | graph[x]->cost = 0; 106 | graph[x]->visited = false; 107 | } 108 | } 109 | 110 | // method that return the farthest node from the specified source node 111 | int getFarthest(node* source, vector graph) 112 | { 113 | // in this method we are applying a simple BFS from the source 114 | queue list; 115 | list.push(source); 116 | 117 | // keep track of farthest length 118 | int length = 0; 119 | 120 | while (!list.empty()) 121 | { 122 | node* current = list.front(); 123 | list.pop(); 124 | 125 | current->visited = true; 126 | 127 | // check the neighbors of current node 128 | for (int x = 0; x < current->neighbors.size(); x++) 129 | { 130 | int index = hashTable[current->neighbors[x]]; 131 | 132 | // only analyze unvisited neighbors 133 | if (graph[index]->visited == false) 134 | { 135 | // update its cost and compare it to the length 136 | int newLength = current->cost + 1; 137 | graph[index]->cost = newLength; 138 | 139 | if (newLength > length) 140 | { 141 | length = newLength; 142 | } 143 | 144 | // adding to our queue 145 | list.push(graph[index]); 146 | } 147 | } 148 | } 149 | 150 | return length; 151 | } 152 | 153 | int FarthestNodes(string strArr[], int size) 154 | { 155 | int length = 0; 156 | 157 | // setting up our graph 158 | vector graph; 159 | createGraph(graph, strArr, size); 160 | 161 | // making the connections 162 | makeConnections(graph, strArr, size); 163 | 164 | // in this operation we perform a BFS from every node in our graph 165 | for (int x = 0; x < graph.size(); x++) 166 | { 167 | int currentLength = getFarthest(graph[x], graph); 168 | 169 | if (currentLength > length) 170 | { 171 | length = currentLength; 172 | } 173 | 174 | // resetting our graph; 175 | resetGraph(graph); 176 | } 177 | 178 | hashTable.clear(); 179 | 180 | return length; 181 | } 182 | 183 | int main() 184 | { 185 | string A[] = { "a-b","b-c","b-d" }; 186 | string B[] = { "b-e","b-c","c-d","a-b","e-f" }; 187 | string C[] = { "b-a","c-e","b-c","d-c" }; 188 | 189 | cout << FarthestNodes(A, sizeof(A)/sizeof(A[0])) << endl; // 2 190 | cout << FarthestNodes(B, sizeof(B) / sizeof(B[0])) << endl; // 4 191 | cout << FarthestNodes(C, sizeof(C) / sizeof(C[0])) << endl; // 3 192 | 193 | return 0; 194 | } -------------------------------------------------------------------------------- /13_VertexCovering.cpp: -------------------------------------------------------------------------------- 1 | // For this challenge you will determine whether a given set of vertices can cover all the edges in the graph. 2 | /* 3 | have the function VertexCovering(strArr) take strArr which will be an array of length three. The first part of the array will be a list of vertices in a graph in the form (A,B,C,...), the second part of the array will be the edges connecting the vertices in the form (A-B,C-D,...) where each edge is bidirectional. The last part of the array will be a set of vertices in the form (X,Y,Z,...) and your program will have to determine whether or not the set of vertices given covers every edge in the graph such that every edge is incident to at least one vertex in the set. 4 | 5 | For example: if strArr is ["(A,B,C,D)","(A-B,A-D,B-D,A-C)","(A,B)"] then the vertices (A,B) are in fact one of the endpoints of every edge in the graph, so every edge has been accounted for. Therefore your program should return the string yes. But, if for example the last part of the array was (C,B) then these vertices don't cover all the edges because the edge connecting A-D is left out. If this is the case your program should return the edges given in the second part of the array that are left out in the same order they were listed, so for this example your program should return (A-D). 6 | 7 | The graph will have at least 2 vertices and all the vertices in the graph will be connected. The third part of the array listing the vertices may be empty, where it would only contain the parenthesis with no values within it: "()" 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | using namespace std; 17 | 18 | /* 19 | one approach is to check if each of the connections are possible based on the nodes provided in the 3rd element 20 | if the connection does not check, we would add it to our list of left out connection 21 | */ 22 | 23 | // method to check if the current pair of nodes check based on the specified nodes 24 | bool checkConnections(char node1, char node2, string nodes) 25 | { 26 | // loop to check if any of the provided nodes covers this specified connection 27 | for (int x = 0; x < nodes.length(); x++) 28 | { 29 | if (nodes[x] == node1 || nodes[x] == node2) 30 | { 31 | return true; 32 | } 33 | } 34 | 35 | return false; 36 | } 37 | 38 | string VertexCovering(string strArr[]) 39 | { 40 | string result; 41 | 42 | // getting the connections from the second element, we also remove any unnecessary characters 43 | string connections = strArr[1]; 44 | connections.erase(remove(connections.begin(), connections.end(), ','), connections.end()); 45 | connections.erase(remove(connections.begin(), connections.end(), ')'), connections.end()); 46 | connections.erase(remove(connections.begin(), connections.end(), '('), connections.end()); 47 | connections.erase(remove(connections.begin(), connections.end(), '-'), connections.end()); 48 | 49 | // getting the nodes from the third element 50 | string nodes = strArr[2]; 51 | nodes.erase(remove(nodes.begin(), nodes.end(), ','), nodes.end()); 52 | nodes.erase(remove(nodes.begin(), nodes.end(), ')'), nodes.end()); 53 | nodes.erase(remove(nodes.begin(), nodes.end(), '('), nodes.end()); 54 | 55 | // loop to analyze each of the connections 56 | for (int x = 0; x < connections.length(); x += 2) 57 | { 58 | // if the current connection does not check than add it to our result of left out connections 59 | if (!checkConnections(connections[x], connections[x + 1], nodes)) 60 | { 61 | if (result.empty()) 62 | { 63 | result.push_back('('); 64 | } 65 | 66 | // adding our missing connection to our result 67 | result.push_back(connections[x]); 68 | result.push_back('-'); 69 | result.push_back(connections[x + 1]); 70 | result.push_back(','); 71 | } 72 | } 73 | 74 | if (result.size() > 0) 75 | { 76 | result.pop_back(); // removing the extra comma 77 | result.push_back(')'); // adding closing tag 78 | 79 | return result; 80 | } 81 | else 82 | { 83 | return "yes"; 84 | } 85 | } 86 | 87 | int main() 88 | { 89 | string A[] = { "(A,B,C,D)", "(A-B,A-D,B-D,A-C)", "(A,B)" }; 90 | string B[] = { "(A,B,C,D)", "(A-B,A-D,B-D,A-C)", "(C)" }; 91 | string C[] = { "(X,Y,Z,Q)", "(X-Y,Y-Q,Y-Z)", "(Z,Y,Q)" }; 92 | 93 | cout << VertexCovering(A) << endl; // yes 94 | cout << VertexCovering(B) << endl; // (A-B,A-D,B-D) 95 | cout << VertexCovering(C) << endl; // yes 96 | 97 | return 0; 98 | } -------------------------------------------------------------------------------- /14_HamiltonianPath.cpp: -------------------------------------------------------------------------------- 1 | // For this challenge you will determine whether a given set of vertices form a Hamiltonian path on the graph. 2 | /* 3 | have the function HamiltonianPath(strArr) take strArr which will be an array of length three. The first part of the array will be a list of vertices in a graph in the form (A,B,C,...), the second part of the array will be the edges connecting the vertices in the form (A-B,C-D,...) where each edge is bidirectional. The last part of the array will be a set of vertices in the form (X,Y,Z,...) and your program will have to determine whether or not the set of vertices given forms a Hamiltonian path on the graph which means that every vertex in the graph is visited only once in the order given. 4 | 5 | For example: if strArr is ["(A,B,C,D)","(A-B,A-D,B-D,A-C)","(C,A,D,B)"] then the vertices (C,A,D,B) in this order do in fact form a Hamiltonian path on the graph so your program should return the string yes. If for example the last part of the array was (D,A,B,C) then this doesn't form a Hamiltonian path because once you get to B you can't get to C in the graph without passing through the visited vertices again. Here your program should return the vertex where the path had to terminate, in this case your program should return B. 6 | 7 | The graph will have at least 2 vertices and all the vertices in the graph will be connected. 8 | */ 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | using namespace std; 15 | 16 | /* 17 | we first we create a graph representation for the nodes and their respective connections 18 | to solve the problem we can use element 3 as our foundation 19 | the first value will represent our source node 20 | from their we can check if the next value is part of its neighbor 21 | if true we update our current node and update it's visit flag 22 | we repeat this until all nodes from element 3 have been analyzed 23 | if a current node does not have a neighbor that matches the target we can signal the node where we terminate 24 | */ 25 | 26 | map hashTable; 27 | 28 | // structure representing a node in our graph 29 | struct node 30 | { 31 | char name; 32 | bool visit; 33 | vector neighbors; 34 | }; 35 | 36 | // method to create our graph 37 | void createGraph(vector & graph, string values[]) 38 | { 39 | // removing unneeded characters from the first element to extract the node values 40 | values[0].erase(remove(values[0].begin(), values[0].end(), ','), values[0].end()); 41 | values[0].erase(remove(values[0].begin(), values[0].end(), ')'), values[0].end()); 42 | values[0].erase(remove(values[0].begin(), values[0].end(), '('), values[0].end()); 43 | 44 | for (int x = 0; x < values[0].length(); x++) 45 | { 46 | graph.push_back(new node); 47 | graph[x]->name = values[0][x]; 48 | graph[x]->visit = false; 49 | 50 | hashTable[values[0][x]] = x; 51 | } 52 | } 53 | 54 | // method for making the connections 55 | void makeConnections(vector graph, string values[]) 56 | { 57 | // removing unneeded characters from the second element 58 | values[1].erase(remove(values[1].begin(), values[1].end(), ','), values[1].end()); 59 | values[1].erase(remove(values[1].begin(), values[1].end(), ')'), values[1].end()); 60 | values[1].erase(remove(values[1].begin(), values[1].end(), '('), values[1].end()); 61 | values[1].erase(remove(values[1].begin(), values[1].end(), '-'), values[1].end()); 62 | 63 | for (int x = 0; x < values[1].length(); x+=2) 64 | { 65 | char node1 = values[1][x]; 66 | char node2 = values[1][x + 1]; 67 | 68 | // making the bidirectional connections 69 | graph[hashTable[node1]]->neighbors.push_back(node2); 70 | graph[hashTable[node2]]->neighbors.push_back(node1); 71 | } 72 | } 73 | 74 | // method to check if the path is valid, we take 2 nodes and check if based on our graph a connection is possible 75 | bool checkPath(char node1, char node2, vector& graph) 76 | { 77 | node* current = graph[hashTable[node1]]; 78 | 79 | // loop to check if any of the unvisited neighbors are the target node (node2) 80 | for (int x = 0; x < current->neighbors.size(); x++) 81 | { 82 | node* temp = graph[hashTable[current->neighbors[x]]]; 83 | 84 | if (temp->visit == false && temp->name == node2) 85 | { 86 | temp->visit = true; 87 | return true; 88 | } 89 | } 90 | return false; 91 | } 92 | 93 | string HamiltonianPath(string strArr[]) 94 | { 95 | // setting up our graph 96 | vector graph; 97 | createGraph(graph, strArr); 98 | makeConnections(graph, strArr); 99 | 100 | // getting the 3rd element which determines the order of our path 101 | string path = strArr[2]; 102 | path.erase(remove(path.begin(), path.end(), ','), path.end()); 103 | path.erase(remove(path.begin(), path.end(), ')'), path.end()); 104 | path.erase(remove(path.begin(), path.end(), '('), path.end()); 105 | 106 | for (int x = 0; x < path.length() - 1; x++) 107 | { 108 | // condition that checks if the path is valid 109 | // recall we take 2 nodes and check if there is a connection between them 110 | if (!checkPath(path[x], path[x + 1], graph)) 111 | { 112 | // when not valid we return the node at which it terminates 113 | string result; 114 | result.push_back(path[x]); 115 | hashTable.clear(); 116 | return result; 117 | } 118 | } 119 | 120 | hashTable.clear(); 121 | return "yes"; 122 | } 123 | 124 | int main() 125 | { 126 | string A[] = { "(A,B,C,D)", "(A-B,A-D,B-D,A-C)", "(C,A,D,B)" }; 127 | string B[] = { "(A,B,C)", "(B-A,C-B)", "(C,B,A)" }; 128 | string C[] = { "(X,Y,Z,Q)", "(X-Y,Y-Q,Y-Z)", "(Z,Y,Q,X)" }; 129 | 130 | cout << HamiltonianPath(A) << endl; // yes 131 | cout << HamiltonianPath(B) << endl; // yes 132 | cout << HamiltonianPath(C) << endl; // Q 133 | return 0; 134 | } -------------------------------------------------------------------------------- /15_KaprekarsConstant.cpp: -------------------------------------------------------------------------------- 1 | // For this challenge you will determine when a specific sequence terminates. 2 | /* 3 | have the function KaprekarsConstant(num) take the num parameter being passed which will be a 4-digit number with at least two distinct digits. Your program should perform the following routine on the number: Arrange the digits in descending order and in ascending order (adding zeroes to fit it to a 4-digit number), and subtract the smaller number from the bigger number. Then repeat the previous step. Performing this routine will always cause you to reach a fixed number: 6174. Then performing the routine on 6174 will always give you 6174 (7641 - 1467 = 6174). Your program should return the number of times this routine must be performed until 6174 is reached. For example: if num is 3524 your program should return 3 because of the following steps: (1) 5432 - 2345 = 3087, (2) 8730 - 0378 = 8352, (3) 8532 - 2358 = 6174. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | int vectorToInt(vector ); 13 | 14 | /* 15 | First we extract the digits from the current number 16 | we store those numbers in a vector to sort them in both ascending and descending order 17 | set a condition to check that both result in a 4 digit number 18 | perform the subtraction and recursive back to the initial step until the base case is reached 19 | */ 20 | int KaprekarsConstant(int num) 21 | { 22 | int count = 0; 23 | 24 | while (num != 6174) 25 | { 26 | vector largeNum; 27 | 28 | // extracting the digits 29 | while (num > 0) 30 | { 31 | int temp = num % 10; 32 | num /= 10; 33 | largeNum.push_back(temp); 34 | } 35 | 36 | // make a copy since we need both a list sorted in descending order and one in ascending order 37 | vector smallerNum = largeNum; 38 | 39 | // sorting the values from both list 40 | sort(smallerNum.begin(), smallerNum.end()); 41 | sort(largeNum.begin(), largeNum.end()); 42 | reverse(largeNum.begin(), largeNum.end()); 43 | 44 | // taking the sorted elements and converting back to an int 45 | int biggerValue = vectorToInt(largeNum); 46 | int smallerValue = vectorToInt(smallerNum); 47 | 48 | // condition in the case the number is not 4 digits for the larger value 49 | if (largeNum.size() < 4) 50 | { 51 | biggerValue *= 10; 52 | } 53 | 54 | // subtracting the numbers 55 | num = biggerValue - smallerValue; 56 | 57 | // updating the count 58 | count++; 59 | } 60 | 61 | return count; 62 | } 63 | 64 | // method to convert the vector to an integer 65 | int vectorToInt(vector list) 66 | { 67 | int result= 0; 68 | int position; 69 | 70 | // conditions to determine the position place 71 | if (list.size() == 4) 72 | { 73 | position = 1000; 74 | } 75 | else if (list.size() == 3) 76 | { 77 | position = 100; 78 | } 79 | else if (list.size() == 2) 80 | { 81 | position = 10; 82 | } 83 | else 84 | { 85 | position = 1; 86 | } 87 | 88 | // loop to add each individual element into the correct place of the number 89 | for (int x = 0; x < list.size(); x++) 90 | { 91 | result += (position*list[x]); 92 | position /= 10; 93 | } 94 | 95 | return result; 96 | } 97 | 98 | int main() 99 | { 100 | cout << KaprekarsConstant(3524) << endl; // 3 101 | cout << KaprekarsConstant(2111) << endl; // 5 102 | cout << KaprekarsConstant(9831) << endl; // 7 103 | 104 | 105 | 106 | return 0; 107 | } -------------------------------------------------------------------------------- /16_TransitivityRelations.cpp: -------------------------------------------------------------------------------- 1 | // For this challenge you will determine whether or not a matrix is transitive. 2 | /*have the function TransitivityRelations(strArr) read the strArr parameter being passed which will make up an NxN matrix where the rows are separated by each pair of parentheses (the matrix will range from 2x2 to 5x5). The matrix represents connections between nodes in a graph where each node corresponds to the Nth element in the matrix (with 0 being the first node). If a connection exists from one node to another, it will be represented by a 1, if not it will be represented by a 0. For example: suppose strArr were a 3x3 matrix with input 3 | ["(1,1,1)", "(1,0,0)", "(0,1,0)"], this means that there is a connection from node 0->0, 0->1, and 0->2. For node 1 the connections are 1->0, and for node 2 the connections are 2->1. This can be interpreted as a connection existing from node X to node Y if there is a 1 in the Xth row and Yth column.Note: a connection from X->Y does not imply a connection from Y->X. 4 | 5 | What your program should determine is whether or not the matrix, which represents connections among the nodes, is transitive.A transitive relation means that if the connections 0->1 and 1->2 exist for example, then there must exist the connection 0->2. More generally, if there is a relation xRy and yRz, then xRz should exist within the matrix.If a matrix is completely transitive, return the string transitive.If it isn't, your program should return the connections needed, in the following format, in order for the matrix to be transitive: (N1,N2)-(N3,N4)-(...). So for the example above, your program should return (1,2)-(2,0). You can ignore the reflexive property of nodes in your answers. Return the connections needed in lexicographical order [e.g. (0,1)-(0,4)-(1,4)-(2,3)-(4,1)]. 6 | */ 7 | 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | // NOT FINISHED 13 | 14 | string TransitivityRelations(string strArr[], int size) 15 | { 16 | 17 | } 18 | 19 | int main() 20 | { 21 | string A[] = { "(1,1,1)", "(0,1,1)", "(0,1,1)" }; 22 | string B[] = { "(0,1,0,0)", "(0,0,1,0)", "(0,0,1,1)", "(0,0,0,1)" }; 23 | string C[] = { "(1,1,1)", "(1,0,0)", "(0,1,0)" }; 24 | cout << TransitivityRelations(A, sizeof(A) / sizeof(A[0])) << endl; // "transitive" 25 | cout << TransitivityRelations(B, sizeof(B) / sizeof(B[0])) << endl; // (0,2)-(0,3)-(1,3) 26 | cout << TransitivityRelations(C,sizeof(C)/sizeof(C[0])) << endl; // (1,2)-(2,0) 27 | return 0; 28 | } -------------------------------------------------------------------------------- /17_OptimalAssignment.cpp: -------------------------------------------------------------------------------- 1 | // For this challenge you will be optimally assigning tasks to a number of machines. 2 | /* 3 | have the function OptimalAssignments(strArr) read strArr which will represent an NxN matrix and it will be in the following format: ["(n,n,n...)","(...)",...] where the n's represent integers. This matrix represents a machine at row i performing task at column j. The cost for this is matrix[i][j]. Your program should determine what machine should perform what task so as to minimize the whole cost and it should return the pairings of machines to tasks in the following format: (i-j)(...)... Only one machine can perform one task. For example: if strArr is ["(5,4,2)","(12,4,3)","(3,4,13)"] then your program should return (1-3)(2-2)(3-1) because assigning the machines to these tasks gives the least cost. The matrix will range from 2x2 to 6x6, there will be no negative costs in the matrix, and there will always be a unique answer. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | // NOT FINISHED 13 | 14 | 15 | bool linearSearch(vector , int); 16 | 17 | /* 18 | Here we can apply a greedy approach 19 | first is to convert the string input into integers 20 | we well set a selection criteria that selects the current available task with lowest cost 21 | once a task is selected for that particular machine it cannot be available for the next machines 22 | */ 23 | string OptimalAssignments(string strArr[], int size) { 24 | vector > newList(size); // 2D vector 25 | vector taskTaken; // keeps track of the task we have used 26 | 27 | // Make the string argument into a list of integers for ease of handling down the line 28 | string num; 29 | int temp; 30 | for (int x = 0; x < size; x++) 31 | { 32 | for (int y = 0; y < strArr[x].length(); y++) 33 | { 34 | if ((strArr[x][y] == '(' || strArr[x][y] == ')' || strArr[x][y] == ',') && !num.empty()) 35 | { 36 | istringstream(num) >> temp; 37 | newList[x].push_back(temp); 38 | num.clear(); 39 | } 40 | else if (isdigit(strArr[x][y])) 41 | { 42 | num += strArr[x][y]; 43 | } 44 | } 45 | } 46 | 47 | string result; 48 | 49 | for (int row = 0; row < newList.size(); row++) 50 | { 51 | // update our output 52 | // following the output format rules 53 | result += '(' + (row + 1) + '-'; 54 | 55 | int col = 0; 56 | int currentLow = col; // keeps track of the current lowest available task 57 | 58 | // loop to perform our greedy choice for the current machine 59 | for (col; col < newList[row].size(); col++) 60 | { 61 | // condition only selects the lowest available task 62 | if (newList[row][col] < newList[row][currentLow] && !linearSearch(taskTaken, currentLow)) 63 | { 64 | currentLow = col; 65 | } 66 | } 67 | cout << endl; 68 | } 69 | 70 | return "test"; 71 | } 72 | 73 | 74 | // linear search method 75 | bool linearSearch(vector list, int target) 76 | { 77 | for (int x = 0; x < list.size(); x++) 78 | { 79 | if (list[x] == target) 80 | { 81 | return true; 82 | } 83 | } 84 | return false; 85 | } 86 | 87 | int main() 88 | { 89 | string A[] = { "(1,2,1)", "(4,1,5)", "(5,2,1)" }; 90 | string B[] = { "(13,4,7,6)", "(1,11,5,4)", "(6,7,2,8)", "(1,3,5,9)" }; 91 | string C[] = { "(5,4,2)", "(12,4,3)", "(3,4,13)" }; 92 | string D[] = { "(90,75,75,80)", "(35,85,55,65)", "(125,95,90,105)", "(45,110,95,115)" }; 93 | 94 | // (3,2) , (1,5) 95 | cout << OptimalAssignments(A, sizeof(A) / sizeof(A[0])) << endl; // (1-1)(2-2)(3-3) 96 | cout << OptimalAssignments(B, sizeof(B) / sizeof(B[0])) << endl; // (1-2)(2-4)(3-3)(4-1) 97 | cout << OptimalAssignments(C, sizeof(C) / sizeof(C[0])) << endl; // (1-3)(2-2)(3-1) 98 | cout << OptimalAssignments(D, sizeof(D) / sizeof(D[0])) << endl; // (1-4)(2-3)(3-2)(4-1) or (1-2)(2-4)(3-3)(4-1) 99 | return 0; 100 | } -------------------------------------------------------------------------------- /18_IntersectingLines.cpp: -------------------------------------------------------------------------------- 1 | // For this challenge you will be determining where two lines intersect in terms of Cartesian coordinates. 2 | /* 3 | have the function IntersectingLines(strArr) take strArr which will be an array of 4 coordinates in the form: (x,y). Your program should take these points where the first 2 form a line and the last 2 form a line, and determine whether the lines intersect, and if they do, at what point. For example: if strArr is ["(3,0)","(1,4)","(0,-3)","(2,3)"], then the line created by (3,0) and (1,4) and the line created by (0,-3) (2,3) intersect at (9/5,12/5). Your output should therefore be the 2 points in fraction form in the following format: (9/5,12/5). If there is no denominator for the resulting points, then the output should just be the integers like so: (12,3). If any of the resulting points is negative, add the negative sign to the numerator like so: (-491/63,-491/67). If there is no intersection, your output should return the string "no intersection". The input points and the resulting points can be positive or negative integers. 4 | */ 5 | 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | // NOT FINISHED 11 | 12 | string IntersectingLines(string strArr[]) 13 | { 14 | 15 | } 16 | 17 | int main() 18 | { 19 | string A[] = {}; 20 | cout << IntersectingLines(A); 21 | return 0; 22 | } -------------------------------------------------------------------------------- /19_ChessboardTraveling.cpp: -------------------------------------------------------------------------------- 1 | // This challenge will require knowledge of basic mathematical combinations. 2 | /* 3 | have the function ChessboardTraveling(str) read str which will be a string consisting of the location of a space on a standard 8x8 chess board with no pieces on the board along with another space on the chess board. The structure of str will be the following: "(x y)(a b)" where (x y) represents the position you are currently on with x and y ranging from 1 to 8 and (a b) represents some other space on the chess board with a and b also ranging from 1 to 8 where a > x and b > y. Your program should determine how many ways there are of traveling from (x y) on the board to (a b) moving only up and to the right. For example: if str is (1 1)(2 2) then your program should output 2 because there are only two possible ways to travel from space (1 1) on a chessboard to space (2 2) while making only moves up and to the right. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | using namespace std; 12 | 13 | /* 14 | first step involves extracting the string values 15 | 16 | we can apply a DFS from current location to destination 17 | for example starting at current location 18 | we take any valid paths possible if we move only up or right 19 | 20 | if the path is valid we add it to our stack 21 | we repeat the process by analyzing those current points 22 | if the current points match our destination points we update our count on the many ways we can reach the destination 23 | */ 24 | string ChessboardTraveling(string str) 25 | { 26 | // extracting point locations from string input 27 | char destinationX = str[6]; 28 | char destinationY = str[8]; 29 | 30 | char currentX = str[1]; 31 | char currentY = str[3]; 32 | 33 | 34 | // setting up our stack which will store a pair of points 35 | vector temp; 36 | temp.push_back(currentX); 37 | temp.push_back(currentY); 38 | 39 | stack < vector > list; 40 | list.push(temp); 41 | 42 | 43 | // value to keep track of the total possible paths we can take to reach destination; 44 | int result = 0; 45 | 46 | // loop to perform our DFS 47 | while (!list.empty()) 48 | { 49 | // get current spot to analyze its points 50 | vector currentLocation = list.top(); 51 | list.pop(); 52 | 53 | 54 | // check if current point reached the destination 55 | if (currentLocation[0] == destinationX && currentLocation[1] == destinationY) 56 | { 57 | result++; 58 | } 59 | 60 | // conditions to check if we can add any other point pairs 61 | // possible path by moving up 62 | if (char(currentLocation[0] + 1) <= destinationX) 63 | { 64 | vector possiblePoints; 65 | char possibleX = char(currentLocation[0] + 1); 66 | char possibleY = currentLocation[1]; 67 | 68 | possiblePoints.push_back(possibleX); 69 | possiblePoints.push_back(possibleY); 70 | 71 | // add the possible pair to our list 72 | list.push(possiblePoints); 73 | } 74 | 75 | // possible path by moving to the right 76 | if (char(currentLocation[1] + 1) <= destinationY) 77 | { 78 | vector possiblePoints; 79 | char possibleX = currentLocation[0]; 80 | char possibleY = char(currentLocation[1] + 1); 81 | 82 | possiblePoints.push_back(possibleX); 83 | possiblePoints.push_back(possibleY); 84 | 85 | // add the possible pair to our list 86 | list.push(possiblePoints); 87 | } 88 | } 89 | 90 | // output result 91 | ostringstream convert; 92 | convert << result; 93 | return convert.str(); 94 | } 95 | 96 | int main() 97 | { 98 | cout << ChessboardTraveling("(1 1)(2 2)") << endl; // 2 99 | cout << ChessboardTraveling("(1 1)(3 3)") << endl; // 6 100 | cout << ChessboardTraveling("(2 2)(4 3)") << endl; // 3 101 | return 0; 102 | } -------------------------------------------------------------------------------- /1_SudokuQuadrantChecker.cpp: -------------------------------------------------------------------------------- 1 | // For this challenge you will be checking if a Sudoku board is legal. 2 | /* 3 | have the function SudokuQuadrantChecker(strArr) read the strArr parameter being passed which will represent a 9x9 Sudoku board of integers ranging from 1 to 9. The rules of Sudoku are to place each of the 9 integers integer in every row and column and not have any integers repeat in the respective row, column, or 3x3 sub-grid. The input strArr will represent a Sudoku board and it will be structured in the following format: ["(N,N,N,N,N,x,x,x,x)","(...)","(...)",...)] where N stands for an integer between 1 and 9 and x will stand for an empty cell. Your program will determine if the board is legal; the board also does not necessarily have to be finished. If the board is legal, your program should return the string legal but if it isn't legal, it should return the 3x3 quadrants (separated by commas) where the errors exist. The 3x3 quadrants are numbered from 1 to 9 starting from top-left going to bottom-right. 4 | 5 | For example, if strArr is: ["(1,2,3,4,5,6,7,8,1)","(x,x,x,x,x,x,x,x,x)","(x,x,x,x,x,x,x,x,x)","(1,x,x,x,x,x,x,x,x)","(x,x,x,x,x,x,x,x,x)","(x,x,x,x,x,x,x,x,x)","(x,x,x,x,x,x,x,x,x)","(x,x,x,x,x,x,x,x,x)","(x,x,x,x,x,x,x,x,x)"] then your program should return 1,3,4 since the errors are in quadrants 1, 3 and 4 because of the repeating integer 1. 6 | 7 | Another example, if strArr is: ["(1,2,3,4,5,6,7,8,9)","(x,x,x,x,x,x,x,x,x)","(6,x,5,x,3,x,x,4,x)","(2,x,1,1,x,x,x,x,x)","(x,x,x,x,x,x,x,x,x)","(x,x,x,x,x,x,x,x,x)","(x,x,x,x,x,x,x,x,x)","(x,x,x,x,x,x,x,x,x)","(x,x,x,x,x,x,x,x,9)"] then your program should return 3,4,5,9. 8 | */ 9 | 10 | #include 11 | #include 12 | using namespace std; 13 | 14 | // Helper function to help determine in which quadrant the error is located 15 | void quadrantLocation(string& result, int x, int y) 16 | { 17 | if (x < 3) 18 | { 19 | if (y < 3) 20 | { 21 | result += ",1"; 22 | } 23 | else if (y >= 3 && y < 6) 24 | { 25 | result += ",2"; 26 | } 27 | else if (y >= 6 && y < 9) 28 | { 29 | result += ",3"; 30 | } 31 | } 32 | else if (x >= 3 && x < 6) 33 | { 34 | if (y < 3) 35 | { 36 | result += ",4"; 37 | } 38 | else if (y >= 3 && y < 6) 39 | { 40 | result += ",5"; 41 | } 42 | else if (y >= 6 && y < 9) 43 | { 44 | result += ",6"; 45 | } 46 | } 47 | else if (x >= 6 && x < 9) 48 | { 49 | if (y < 3) 50 | { 51 | result += ",7"; 52 | } 53 | else if (y >= 3 && y < 6) 54 | { 55 | result += ",8"; 56 | } 57 | else if (y >= 6 && y < 9) 58 | { 59 | result += ",9"; 60 | } 61 | } 62 | } 63 | // Overload function but this time we want to find the range of the quadrant 64 | // This will aid for when searching the current quadrant to check if the number repeats 65 | void quadrantLocation(int x, int y, int& rowSize, int& columnSize) 66 | { 67 | if (x < 3) 68 | { 69 | rowSize = 3; 70 | if (y < 3) 71 | { 72 | columnSize = 3; 73 | } 74 | else if (y >= 3 && y < 6) 75 | { 76 | columnSize = 6; 77 | } 78 | else if (y >= 6 && y < 9) 79 | { 80 | columnSize = 9; 81 | } 82 | } 83 | else if (x >= 3 && x < 6) 84 | { 85 | rowSize = 6; 86 | if (y < 3) 87 | { 88 | columnSize = 3; 89 | } 90 | else if (y >= 3 && y < 6) 91 | { 92 | columnSize = 6; 93 | } 94 | else if (y >= 6 && y < 9) 95 | { 96 | columnSize = 9; 97 | } 98 | } 99 | else if (x >= 6 && x < 9) 100 | { 101 | rowSize = 9; 102 | if (y < 3) 103 | { 104 | columnSize = 3; 105 | } 106 | else if (y >= 3 && y < 6) 107 | { 108 | columnSize = 6; 109 | } 110 | else if (y >= 6 && y < 9) 111 | { 112 | columnSize = 9; 113 | } 114 | } 115 | } 116 | 117 | string SudokuQuadrantChecker(string strArr[], int size) { 118 | // Removing unnecessary characters such as commas and parentheses 119 | for (int row = 0; row < size; row++) 120 | { 121 | for (int col = 0; col < strArr[row].length(); col++) 122 | { 123 | if (strArr[row][col] == '(' || strArr[row][col] == ')' || strArr[row][col] == ',') 124 | { 125 | strArr[row].erase(strArr[row].begin() + col); 126 | } 127 | } 128 | } 129 | 130 | // Analyzing the rules 131 | string quadrant =""; 132 | int rowIndex, colIndex; 133 | for (int x = 0; x < size; x++) 134 | { 135 | for (int current = 0; current < size; current++) 136 | { 137 | for (int y = 0; y < size; y++) 138 | { 139 | // Checking for repetition in rows and columns 140 | if (strArr[x][current] == strArr[x][y] && y != current && strArr[x][current] != 'x') // Rows 141 | { 142 | quadrantLocation(quadrant, x, current); // Function call to provide the error location 143 | break; 144 | } 145 | else if (strArr[x][current] == strArr[y][current] && y != x && strArr[x][current] != 'x') // Columns 146 | { 147 | quadrantLocation(quadrant, x, current); // Function call to provide the error location 148 | break; 149 | } 150 | else if (strArr[x][current] != 'x') 151 | { 152 | quadrantLocation(x, current, rowIndex, colIndex); // Function call to provide the current quadrant we need to analyze 153 | int i, z; 154 | // Switch statements to find the starting index for the current quadrant 155 | switch (rowIndex) 156 | { 157 | case 3: 158 | i = 0; 159 | break; 160 | case 6: 161 | i = 3; 162 | break; 163 | case 9: 164 | i = 6; 165 | break; 166 | } 167 | switch (colIndex) 168 | { 169 | case 3: 170 | z = 0; 171 | break; 172 | case 6: 173 | z = 3; 174 | break; 175 | case 9: 176 | z = 6; 177 | break; 178 | } 179 | // Loop to check if numbers repeat in the current quadrant 180 | for (i; i < rowIndex; i++) 181 | { 182 | for (z; z < colIndex; z++) 183 | { 184 | if (x == i && z == current) 185 | { 186 | continue; 187 | } 188 | else if (strArr[x][current] == strArr[i][z]) // Check if the numbers repeat 189 | { 190 | // Function call to find error location when the quadrant contains repeating numbers 191 | quadrantLocation(quadrant, i, z); 192 | break; 193 | } 194 | } 195 | } 196 | } 197 | } 198 | } 199 | } 200 | 201 | if (quadrant.length() > 0) 202 | { 203 | quadrant.erase(quadrant.begin() + 0); 204 | for (int r = 0; r < quadrant.length(); r++) // Safeguard in the case we have the same quadrant listed multiple times 205 | { 206 | if (isdigit(quadrant[r])) 207 | { 208 | for (int t = 0; t < quadrant.length(); t++) 209 | { 210 | if (t == r) 211 | { 212 | continue; 213 | } 214 | else if (isdigit(quadrant[t]) && quadrant[r] == quadrant[t]) 215 | { 216 | quadrant.erase(quadrant.begin() + t); 217 | quadrant.erase(quadrant.begin() +(t- 1)); 218 | } 219 | } 220 | } 221 | } 222 | return quadrant; 223 | } 224 | else 225 | { 226 | return "legal"; 227 | } 228 | } 229 | 230 | int main() { 231 | 232 | // keep this function call here 233 | /* Note: In C++ you first have to initialize an array and set 234 | it equal to the stdin to test your code with arrays. */ 235 | 236 | string A[] = { "(1,2,3,4,5,6,7,8,1)", "(x,x,x,x,x,x,x,x,x)", "(x,x,x,x,x,x,x,x,x)", "(1,x,x,x,x,x,x,x,x)", "(x,x,x,x,x,x,x,x,x)", "(x,x,x,x,x,x,x,x,x)", "(x,x,x,x,x,x,x,x,x)", "(x,x,x,x,x,x,x,x,x)", "(x,x,x,x,x,x,x,x,x)" }; 237 | string B[] = { "(1,2,3,4,5,6,7,8,9)", "(x,x,x,x,x,x,x,x,x)", "(6,x,5,x,3,x,x,4,x)", "(2,x,1,1,x,x,x,x,x)", "(x,x,x,x,x,x,x,x,x)", "(x,x,x,x,x,x,x,x,x)", "(x,x,x,x,x,x,x,x,x)", "(x,x,x,x,x,x,x,x,x)", "(x,x,x,x,x,x,x,x,9)" }; 238 | string C[] = { "(1,2,3,4,5,6,7,8,9)", "(4,5,6,1,2,3,x,x,x)", "(7,8,9,x,x,6,x,x,x)", "(2,3,4,x,x,x,x,x,x)", "(5,6,7,x,x,x,x,x,x)", "(8,9,1,x,x,x,x,x,x)", "(x,x,x,x,x,x,x,x,x)", "(x,x,x,x,x,x,x,x,x)", "(x,x,x,x,x,x,x,x,1)" }; 239 | cout << SudokuQuadrantChecker(A, sizeof(A) / sizeof(A[0])) << endl; // 1,3,4 240 | cout << SudokuQuadrantChecker(B, sizeof(B) / sizeof(B[0])) << endl; // 3,4,5,9 241 | cout << SudokuQuadrantChecker(C, sizeof(C) / sizeof(C[0])) << endl; // 2 242 | return 0; 243 | } -------------------------------------------------------------------------------- /20_KnightJumps.cpp: -------------------------------------------------------------------------------- 1 | // This challenge will require knowledge of chess pieces and their movements. 2 | /* 3 | have the function KnightJumps(str) read str which will be a string consisting of the location of a knight on a standard 8x8 chess board with no other pieces on the board. The structure of str will be the following: "(x y)" which represents the position of the knight with x and y ranging from 1 to 8. Your program should determine the number of spaces the knight can move to from a given location. For example: if str is "(4 5)" then your program should output 8 because the knight can move to 8 different spaces from position x=4 and y=5. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | using namespace std; 10 | 11 | void analyzeUp(char, char, int&); 12 | void analyzeDown(char, char, int&); 13 | void analyzeLeft(char, char, int&); 14 | void analyzeRight(char, char, int&); 15 | 16 | /* 17 | we first extract the points for the knight location 18 | 19 | one approach is to use helpers that analyze the possible moves 20 | 4 methods used to extends in the 4 directions 21 | 22 | we than check for the final possible move 23 | for example one method is used for top path 24 | if knight can move 2 steps to the top 25 | check the possible paths of moving 1 step to both left or right 26 | 27 | for any valid possible complete movements we update our total 28 | */ 29 | int KnightJumps(string str) 30 | { 31 | // get knight location 32 | char currentX = str[1]; 33 | char currentY = str[3]; 34 | 35 | // keep track of total 36 | int result = 0; 37 | 38 | // find possible moves for the knight 39 | analyzeUp(currentX, currentY, result); 40 | analyzeDown(currentX, currentY, result); 41 | analyzeLeft(currentX, currentY, result); 42 | analyzeRight(currentX, currentY, result); 43 | 44 | return result; 45 | } 46 | 47 | 48 | void analyzeUp(char x, char y, int& total) 49 | { 50 | // moving Up 51 | char moveUp = char(x + 2); 52 | 53 | // condition to check for out of bounds 54 | if (moveUp > '8') 55 | { 56 | return; 57 | } 58 | 59 | // condition to check if we can move left or right 60 | if (char(y + 1) <= '8') 61 | { 62 | total++; 63 | } 64 | if (char(y - 1) >= '1') 65 | { 66 | total++; 67 | } 68 | } 69 | void analyzeDown(char x, char y, int& total) 70 | { 71 | char moveDown = char(x - 2); 72 | 73 | if (moveDown < '1') 74 | { 75 | return; 76 | } 77 | 78 | if (char(y + 1) <= '8') 79 | { 80 | total++; 81 | } 82 | if (char(y - 1) >= '1') 83 | { 84 | total++; 85 | } 86 | } 87 | void analyzeLeft(char x, char y, int& total) 88 | { 89 | char moveLeft = char(y + 2); 90 | 91 | // condition to check for out of bounds 92 | if (moveLeft > '8') 93 | { 94 | return; 95 | } 96 | 97 | // condition to check if we can move up or down 98 | if (char(x + 1) <= '8') 99 | { 100 | total++; 101 | } 102 | if (char(x - 1) >= '1') 103 | { 104 | total++; 105 | } 106 | } 107 | void analyzeRight(char x, char y, int& total) 108 | { 109 | char moveRight = char(y - 2); 110 | 111 | if (moveRight < '1') 112 | { 113 | return; 114 | } 115 | 116 | if (char(x + 1) <= '8') 117 | { 118 | total++; 119 | } 120 | if (char(x - 1) >= '1') 121 | { 122 | total++; 123 | } 124 | } 125 | 126 | int main() 127 | { 128 | cout << KnightJumps("(4 5)") << endl; // 8 129 | cout << KnightJumps("(1 1)") << endl; // 2 130 | cout << KnightJumps("(2 8)") << endl; // 3 131 | return 0; 132 | } 133 | -------------------------------------------------------------------------------- /21_BlackjackHighest.cpp: -------------------------------------------------------------------------------- 1 | // For this challenge you will be determining the highest cards within a hand in Blackjack. 2 | /* 3 | have the function BlackjackHighest(strArr) take the strArr parameter being passed which will be an array of numbers and letters representing blackjack cards. Numbers in the array will be written out. So for example strArr may be ["two","three","ace","king"]. The full list of possibilities for strArr is: two, three, four, five, six, seven, eight, nine, ten, jack, queen, king, ace. Your program should output below, above, or blackjack signifying if you have blackjack (numbers add up to 21) or not and the highest card in your hand in relation to whether or not you have blackjack. If the array contains an ace but your hand will go above 21, you must count the ace as a 1. You must always try and stay below the 21 mark. So using the array mentioned above, the output should be below king. The ace is counted as a 1 in this example because if it wasn't you would be above the 21 mark. Another example would be if strArr was ["four","ten","king"], the output here should be above king. If you have a tie between a ten and a face card in your hand, return the face card as the "highest card". If you have multiple face cards, the order of importance is jack, queen, then king. 4 | 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | 13 | string BlackjackHighest(string strArr[]) 14 | { 15 | 16 | } 17 | 18 | int main() 19 | { 20 | string A[] = {}; 21 | 22 | cout << BlackjackHighest(A); 23 | return 0; 24 | 25 | } -------------------------------------------------------------------------------- /22_QueenCheck.cpp: -------------------------------------------------------------------------------- 1 | // This challenge will require knowledge of chess pieces and their movements. 2 | /* 3 | have the function QueenCheck(strArr) read strArr which will be an array consisting of the locations of a Queen and King on a standard 8x8 chess board with no other pieces on the board. The structure of strArr will be the following: ["(x1,y1)","(x2,y2)"] with (x1,y1) representing the position of the queen and (x2,y2) representing the location of the king with x and y ranging from 1 to 8. Your program should determine if the king is in check based on the current positions of the pieces, and if so, return the number of spaces it can move to in order to get out of check. If the king is not in check, return -1. For example: if strArr is ["(4,4)","(6,6)"] then your program should output 6. Remember, because only the queen and king are on the board, if the queen is checking the king by being directly adjacent to it, technically the king can capture the queen. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | using namespace std; 10 | 11 | bool analyzeCheck(char, char, char, char); 12 | 13 | /* 14 | first extract the points from the string array 15 | 16 | an approach is to use a helper function that checks queen location to current king location 17 | if checks all possible attacks from the queen 18 | 19 | if king is not in check return -1 20 | 21 | else we iterate through all valid paths the king can take 22 | if new king location is not outbounds and is not in check we update our total 23 | for each check we can use the helper function with different king location points 24 | */ 25 | int QueenCheck(string strArr[]) 26 | { 27 | // getting points for queen and king location 28 | char queenX = strArr[0][1]; 29 | char queenY = strArr[0][3]; 30 | char kingX = strArr[1][1]; 31 | char kingY = strArr[1][3]; 32 | 33 | // check if the king is safe 34 | if (!analyzeCheck(queenX, queenY, kingX, kingY)) 35 | { 36 | return -1; 37 | } 38 | 39 | // value to store our result to total possible safe moves from the king 40 | int result = 0; 41 | 42 | // iterate through all 8 possible moves a king can make 43 | // up 44 | if (!analyzeCheck(queenX, queenY, char(kingX + 1), kingY)) 45 | { 46 | result++; 47 | } 48 | 49 | // down 50 | if (!analyzeCheck(queenX, queenY, char(kingX - 1), kingY)) 51 | { 52 | result++; 53 | } 54 | 55 | // left 56 | if (!analyzeCheck(queenX, queenY, kingX, char(kingY + 1))) 57 | { 58 | result++; 59 | } 60 | 61 | // right 62 | if (!analyzeCheck(queenX, queenY, kingX, char(kingY - 1))) 63 | { 64 | result++; 65 | } 66 | 67 | // top left 68 | if (!analyzeCheck(queenX, queenY, char(kingX+1), char(kingY + 1))) 69 | { 70 | result++; 71 | } 72 | 73 | // top right 74 | if (!analyzeCheck(queenX, queenY, char(kingX + 1), char(kingY - 1))) 75 | { 76 | result++; 77 | } 78 | 79 | // bottom left 80 | if (!analyzeCheck(queenX, queenY, char(kingX - 1), char(kingY + 1))) 81 | { 82 | result++; 83 | } 84 | 85 | // bottom right 86 | if (!analyzeCheck(queenX, queenY, char(kingX - 1), char(kingY - 1))) 87 | { 88 | result++; 89 | } 90 | 91 | 92 | // check if king can take the queen 93 | if ((char(abs(int(queenX - kingX)) + 48) == '1' || char(abs(int(queenX - kingX)) + 48) == '0') 94 | && (char(abs(int(queenY - kingY)) + 48) == '1' || char(abs(int(queenY - kingY)) + 48) == '0')) 95 | { 96 | result++; 97 | } 98 | 99 | return result; 100 | } 101 | 102 | bool analyzeCheck(char queenX, char queenY, char kingX, char kingY) 103 | { 104 | // first check king is inside the chessboard 105 | if (kingX > '8' || kingX < '1' || kingY > '8' || kingY < '1') 106 | { 107 | return true; 108 | } 109 | 110 | // check if there is horizontal or vertical check 111 | if (kingX == queenX || kingY == queenY) 112 | { 113 | return true; 114 | } 115 | 116 | // check if there is any diagonal check 117 | // top left 118 | for (char x = queenX, y = queenY; x <= '8' && y <= '8'; x = char(x + 1), y = char(y + 1)) 119 | { 120 | if (x == kingX && y == kingY) 121 | { 122 | return true; 123 | } 124 | } 125 | // bottom left 126 | for (char x = queenX, y = queenY; x >= '1' && y <= '8'; x = char(x - 1), y = char(y + 1)) 127 | { 128 | if (x == kingX && y == kingY) 129 | { 130 | return true; 131 | } 132 | } 133 | // top right 134 | for (char x = queenX, y = queenY; x <= '8' && y >= '1'; x = char(x + 1), y = char(y - 1)) 135 | { 136 | if (x == kingX && y == kingY) 137 | { 138 | return true; 139 | } 140 | } 141 | // bottom right 142 | for (char x = queenX, y = queenY; x >= '1' && y >= '1'; x = char(x - 1), y = char(y - 1)) 143 | { 144 | if (x == kingX && y == kingY) 145 | { 146 | return true; 147 | } 148 | } 149 | 150 | return false; 151 | } 152 | 153 | int main() 154 | { 155 | string A[] = { "(4,4)", "(6,6)" }; 156 | string B[] = { "(1,1)", "(1,4)" }; 157 | string C[] = { "(3,1)", "(4,4)" }; 158 | string D[] = { "(2,2)", "(2,3)" }; 159 | string E[] = { "(1,8)", "(2,7)" }; 160 | string F[] = { "(1,1)", "(8,1)" }; 161 | string G[] = { "(8,2)", "(7,1)" }; 162 | 163 | 164 | cout << QueenCheck(A) << endl; // 6 165 | cout << QueenCheck(B) << endl; // 3 166 | cout << QueenCheck(C) << endl; // -1 167 | cout << QueenCheck(D) << endl; // 3 168 | cout << QueenCheck(E) << endl; // 3 169 | cout << QueenCheck(F) << endl; // 2 170 | cout << QueenCheck(G) << endl; // 2 171 | 172 | return 0; 173 | } 174 | -------------------------------------------------------------------------------- /23_QuickKnight.cpp: -------------------------------------------------------------------------------- 1 | // This challenge will require knowledge of chess pieces and their movements. 2 | /* 3 | have the function QuickKnight(str) read str which will be a string consisting of the location of a knight on a standard 8x8 chess board with no other pieces on the board and another space on the chess board. The structure of str will be the following: "(x y)(a b)" where (x y) represents the position of the knight with x and y ranging from 1 to 8 and (a b) represents some other space on the chess board with a and b also ranging from 1 to 8. Your program should determine the least amount of moves it would take the knight to go from its position to position (a b). For example if str is "(2 3)(7 5)" then your program should output 3 because that is the least amount of moves it would take for the knight to get from (2 3) to (7 5) on the chess board. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | 13 | int analyzeUp(int, int); 14 | int analyzeDown(int, int); 15 | int analyzeLeft(int, int); 16 | int analyzeRight(int, int); 17 | vector newLocation(int, int, int); 18 | 19 | /* 20 | first step is to extract the points for our knight and the destination 21 | 22 | can be solved using a BFS approach 23 | we take current location 24 | check all possible valid moves the knight can make 25 | we store the movement and its cost in a queue 26 | 27 | we repeat the same steps now with a different current location 28 | if path is valid we add 1 to the current cost to get a new movement cost 29 | when we reach destination we return the total cost 30 | */ 31 | int QuickKnight(string str) 32 | { 33 | // get location for knight and destination 34 | int knightX = str[1] - 48; 35 | int knightY = str[3] -48; 36 | int destinationX = str[6] - 48; 37 | int destinationY = str[8] - 48; 38 | 39 | // result 40 | int cost = 0; 41 | 42 | // making the point pair, alongside its cost to add to the queue 43 | vector source; 44 | source.push_back(knightX); 45 | source.push_back(knightY); 46 | source.push_back(0); 47 | 48 | // adding source 49 | queue < vector > list; 50 | list.push(source); 51 | 52 | while (!list.empty()) 53 | { 54 | vector currentLocation = list.front(); 55 | list.pop(); 56 | 57 | // for ease of access 58 | int x = currentLocation[0]; 59 | int y = currentLocation[1]; 60 | int cost = currentLocation[2]; 61 | 62 | // check if we reached the destination 63 | if (x == destinationX && y == destinationY) 64 | { 65 | return cost; 66 | } 67 | 68 | /* 69 | check for valid knight movements 70 | 71 | rules set: if helper method returns 3 it can move the desired direction and both end directions 72 | example: knight can go up and move left and right 73 | example: knight can go left and move up and down 74 | 75 | returns 2 = left or up 76 | returns 1 = right or down 77 | returns 0 = no valid movement 78 | */ 79 | // up 80 | if (analyzeUp(x, y) == 3) 81 | { 82 | list.push(newLocation(x + 2, y + 1, cost + 1)); 83 | list.push(newLocation(x + 2, y - 1, cost + 1)); 84 | } 85 | else if (analyzeUp(x, y) == 2) 86 | { 87 | list.push(newLocation(x + 2, y + 1, cost + 1)); 88 | } 89 | else if (analyzeUp(x, y) == 1) 90 | { 91 | list.push(newLocation(x + 2, y - 1, cost + 1)); 92 | } 93 | // down 94 | if (analyzeDown(x, y) == 3) 95 | { 96 | list.push(newLocation(x - 2, y + 1, cost + 1)); 97 | list.push(newLocation(x - 2, y - 1, cost + 1)); 98 | } 99 | else if (analyzeDown(x, y) == 2) 100 | { 101 | list.push(newLocation(x - 2, y + 1, cost + 1)); 102 | } 103 | else if (analyzeDown(x, y) == 1) 104 | { 105 | list.push(newLocation(x - 2, y - 1, cost + 1)); 106 | } 107 | // left 108 | if (analyzeLeft(x, y) == 3) 109 | { 110 | list.push(newLocation(x + 1, y + 2, cost + 1)); 111 | list.push(newLocation(x - 1, y + 2, cost + 1)); 112 | } 113 | else if (analyzeLeft(x, y) == 2) 114 | { 115 | list.push(newLocation(x + 1, y + 2, cost + 1)); 116 | } 117 | else if (analyzeLeft(x, y) == 1) 118 | { 119 | list.push(newLocation(x - 1, y + 2, cost + 1)); 120 | } 121 | // right 122 | if (analyzeRight(x, y) == 3) 123 | { 124 | list.push(newLocation(x + 1, y - 2, cost + 1)); 125 | list.push(newLocation(x - 1, y - 2, cost + 1)); 126 | } 127 | else if (analyzeRight(x, y) == 2) 128 | { 129 | list.push(newLocation(x + 1, y - 2, cost + 1)); 130 | } 131 | else if (analyzeRight(x, y) == 1) 132 | { 133 | list.push(newLocation(x - 1, y - 2, cost + 1)); 134 | } 135 | } 136 | 137 | return cost; 138 | } 139 | 140 | 141 | int analyzeUp(int x, int y) 142 | { 143 | // moving Up 144 | int moveUp = x + 2; 145 | 146 | // making sure we are still inbound when moving up 2 steps 147 | if (moveUp <= 8) 148 | { 149 | // condition to check if we can move left or right 150 | if (y + 1 <= 8 && y-1 >= 1) 151 | { 152 | return 3; 153 | } 154 | else if (y + 1 <= 8) 155 | { 156 | return 2; 157 | } 158 | else if (y - 1 >= 1) 159 | { 160 | return 1; 161 | } 162 | } 163 | 164 | return 0; 165 | } 166 | int analyzeDown(int x, int y) 167 | { 168 | int moveDown = x - 2; 169 | 170 | if (moveDown >= 1) 171 | { 172 | if (y + 1 <= 8 && y - 1 >= 1) 173 | { 174 | return 3; 175 | } 176 | else if (y + 1 <= 8) 177 | { 178 | return 2; 179 | } 180 | else if (char(y - 1) >= 1) 181 | { 182 | return 1; 183 | } 184 | } 185 | 186 | return 0; 187 | } 188 | int analyzeLeft(int x, int y) 189 | { 190 | int moveLeft = y + 2; 191 | 192 | // condition we are inbounds when moving left 2 steps 193 | if (moveLeft <= 8) 194 | { 195 | // condition to check if we can move up or down 196 | if (x + 1 <= 8 && x - 1 >= 1) 197 | { 198 | return 3; 199 | } 200 | else if (x + 1 <= 8) 201 | { 202 | return 2; 203 | } 204 | else if (x - 1 >= 1) 205 | { 206 | return 1; 207 | } 208 | } 209 | 210 | return 0; 211 | } 212 | int analyzeRight(int x, int y) 213 | { 214 | int moveRight = y - 2; 215 | 216 | if (moveRight >= 1) 217 | { 218 | if (x + 1 <= 8 && x - 1 >= 1) 219 | { 220 | return 3; 221 | } 222 | else if (x + 1 <= 8) 223 | { 224 | return 2; 225 | } 226 | else if (x - 1 >= 1) 227 | { 228 | return 1; 229 | } 230 | } 231 | 232 | return 0; 233 | } 234 | 235 | vector newLocation(int x, int y, int cost) 236 | { 237 | vector temp; 238 | temp.push_back(x); 239 | temp.push_back(y); 240 | temp.push_back(cost); 241 | return temp; 242 | } 243 | 244 | int main() 245 | { 246 | cout << QuickKnight("(2 3)(7 5)") << endl; // 3 247 | cout << QuickKnight("(1 1)(8 8)") << endl; // 6 248 | cout << QuickKnight("(2 2)(3 3)") << endl; // 2 249 | return 0; 250 | } -------------------------------------------------------------------------------- /24_StepWalking.cpp: -------------------------------------------------------------------------------- 1 | // For this challenge you will determine how many different ways you can walk up a flight of stairs. 2 | /* 3 | have the function StepWalking(num) take the num parameter being passed which will be an integer between 1 and 15 that represents the number of stairs you will have to climb. You can climb the set of stairs by taking either 1 step or 2 steps, and you can combine these in any order. So for example, to climb 3 steps you can either do: (1 step, 1 step, 1 step) or (2, 1) or (1, 2). So for 3 steps we have 3 different ways to climb them, so your program should return 3. Your program should return the number of combinations of climbing num steps. 4 | */ 5 | 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | // NOT FINISHED 11 | 12 | int StepWalking(int num) 13 | { 14 | 15 | } 16 | 17 | int main() 18 | { 19 | cout << StepWalking(3) << endl; // 3 20 | cout << StepWalking(1) << endl; // 1 21 | return 0; 22 | } -------------------------------------------------------------------------------- /25_PentagonalNumber.cpp: -------------------------------------------------------------------------------- 1 | // For this challenge you will be finding how many dots can fit into a pentagonal shape. 2 | /* 3 | have the function PentagonalNumber(num) read num which will be a positive integer and determine how many dots exist in a pentagonal shape around a center dot on the Nth iteration. For example, in the image below you can see that on the first iteration there is only a single dot, on the second iteration there are 6 dots, on the third there are 16 dots, and on the fourth there are 31 dots. 4 | */ 5 | 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | // NOT FINISHED 11 | 12 | int PentagonalNumber(int num) 13 | { 14 | int total = 1; 15 | 16 | for (int x = 1; x < num; x++) 17 | { 18 | total += (5 * x); 19 | } 20 | 21 | return total; 22 | } 23 | 24 | int main() 25 | { 26 | cout << PentagonalNumber(2) << endl; // 6 27 | cout << PentagonalNumber(5) << endl; // 51 28 | return 0; 29 | } -------------------------------------------------------------------------------- /26_MaximalSquare.cpp: -------------------------------------------------------------------------------- 1 | // For this challenge you will be searching a matrix for the largest square submatrix. 2 | /* 3 | have the function MaximalSquare(strArr) take the strArr parameter being passed which will be a 2D matrix of 0 and 1's, and determine the area of the largest square submatrix that contains all 1's. A square submatrix is one of equal width and height, and your program should return the area of the largest submatrix that contains only 1's. For example: if strArr is ["10100", "10111", "11111", "10010"] then this looks like the following matrix: 4 | 5 | For the input above, you can see the bolded 1's create the largest square submatrix of size 2x2, so your program should return the area which is 4. You can assume the input will not be empty. 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | using namespace std; 12 | 13 | int getArea(string[], int, int, int); 14 | bool checkArea(string[], int, int, int, int); 15 | 16 | /* 17 | One approach is to step through each point 18 | 19 | for each point we locate a perimeter of equal width and height 20 | we can then check if the possible square is valid 21 | meaning it must be filled with all 1s 22 | 23 | if valid we determine the area and update our highest value 24 | */ 25 | int MaximalSquare(string strArr[], int size) 26 | { 27 | int total = 1; 28 | 29 | // traverse for valid points to analyze 30 | for (int row = 0; row < size; row++) 31 | { 32 | for (int col = 0; col < strArr[row].length(); col++) 33 | { 34 | // condition to get a starting point to analyze from 35 | if (strArr[row][col] == '1') 36 | { 37 | int area = getArea(strArr, size, row, col); 38 | 39 | // update value 40 | if (area > total) 41 | { 42 | total = area; 43 | } 44 | } 45 | } 46 | } 47 | 48 | return total; 49 | } 50 | 51 | // get area method 52 | // will analyze current point and find a square of equal width and height 53 | int getArea(string arr[],int size, int row, int col) 54 | { 55 | int tempRow = row; 56 | int tempCol = col; 57 | 58 | int area = 1; 59 | 60 | while (tempRow+1 < size && tempCol+1 < arr[0].length()) 61 | { 62 | // expand the width and height 63 | if (arr[tempRow + 1][col] == '1' && arr[row][tempCol + 1] == '1') 64 | { 65 | tempRow++; 66 | tempCol++; 67 | 68 | // check if current expansion is a valid full square 69 | if (checkArea(arr, row, col, tempRow, tempCol)) 70 | { 71 | 72 | area++; 73 | } 74 | else 75 | { 76 | return area * area; 77 | } 78 | } 79 | else 80 | { 81 | return area * area; 82 | } 83 | } 84 | 85 | return area*area; 86 | } 87 | 88 | // method to check if points provided form a full square 89 | bool checkArea(string arr[], int row, int col, int rowLimit, int colLimit) 90 | { 91 | for (row; row <= rowLimit; row++) 92 | { 93 | for (int y = col; y <= colLimit; y++) 94 | { 95 | if (arr[row][y] != '1') 96 | { 97 | return false; 98 | } 99 | } 100 | } 101 | 102 | return true; 103 | } 104 | 105 | 106 | int main() 107 | { 108 | string A[] = { "10100", "10111", "11111", "10010" }; 109 | string B[] = { "0111", "1111", "1111", "1111" }; 110 | string C[] = { "0111", "1101", "0111" }; 111 | 112 | cout << MaximalSquare(A, sizeof(A)/sizeof(A[0])) << endl; // 4 113 | cout << MaximalSquare(B, sizeof(B) / sizeof(B[0])) << endl; // 9 114 | cout << MaximalSquare(C, sizeof(C) / sizeof(C[0])) << endl; // 1 115 | return 0; 116 | } -------------------------------------------------------------------------------- /27_WildcardCharacters.cpp: -------------------------------------------------------------------------------- 1 | // For this challenge you will determine if a string matches a set of wildcard characters. 2 | /* 3 | have the function WildcardCharacters(str) read str which will contain two strings separated by a space. The first string will consist of the following sets of characters: +, *, and {N} which is optional. The plus (+) character represents a single alphabetic character, the asterisk (*) represents a sequence of the same character of length 3 unless it is followed by {N} which represents how many characters should appear in the sequence where N will be at least 1. Your goal is to determine if the second string exactly matches the pattern of the first string in the input. 4 | 5 | For example: if str is "++*{5} gheeeee" then the second string in this case does match the pattern, so your program should return the string true. If the second string does not match the pattern your program should return the string false. 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | using namespace std; 12 | 13 | /* 14 | separate wildcard and result sub string from input 15 | step through result string and check if it follows the rules 16 | 17 | at each step we analyze what rule to follow 18 | whether is single character or sequence 19 | if sequence determine if it had default length of 3 or if it is provided with a length 20 | 21 | the result string must be parallel to the rules provided by the wildcard 22 | */ 23 | string WildcardCharacters(string str) 24 | { 25 | // getting the strings to analyze 26 | int breakpoint = str.find(' '); 27 | string wildCard = str.substr(0, breakpoint); 28 | string result = str.substr(breakpoint + 1, str.length() - breakpoint); 29 | 30 | // step through the wildcard to validate the rule 31 | int index = 0; 32 | int step = 0; 33 | while (index < wildCard.length()) 34 | { 35 | // checking symbol 36 | if (wildCard[index] == '+') 37 | { 38 | step++; 39 | } 40 | else if (wildCard[index] == '*') 41 | { 42 | int sequenceLenght = 3; 43 | 44 | // condition to analyze sequence character 45 | // checking if it falls under default repetition of 3 of if it was assigned a length 46 | if (index + 1 < wildCard.length()) 47 | { 48 | // condition to get the assigned length if one is provided 49 | if (wildCard[index + 1] == '{') 50 | { 51 | // getting the length 52 | string num; 53 | while (wildCard[index] != '}') 54 | { 55 | if (wildCard[index] >= '0' && wildCard[index] <= '9') 56 | { 57 | num += wildCard[index]; 58 | } 59 | 60 | index++; 61 | } 62 | 63 | // converting the gathered number string to an int 64 | istringstream convert(num); 65 | convert >> sequenceLenght; 66 | } 67 | } 68 | 69 | // first checking for out of bounds 70 | if (step + sequenceLenght-1 > result.length()) 71 | { 72 | return "false"; 73 | } 74 | else 75 | { 76 | // loop to ensure the characters are the same in a sequence 77 | char tempChar = result[step]; 78 | while (sequenceLenght > 0) 79 | { 80 | if (result[step] != tempChar) 81 | { 82 | return "false"; 83 | } 84 | 85 | sequenceLenght--; 86 | step++; 87 | } 88 | } 89 | } 90 | 91 | index++; 92 | } 93 | 94 | // ensure the traversal was parallel 95 | // in other words for the rules to have been met in the result string we needed to cover everything without any errors 96 | if (step != result.length()) 97 | { 98 | return "false"; 99 | } 100 | 101 | return "true"; 102 | } 103 | 104 | int main() 105 | { 106 | cout << WildcardCharacters("++*{5} gheeeee") << endl; // true 107 | cout << WildcardCharacters("+++++* abcdemmmmmm") << endl; // false 108 | cout << WildcardCharacters("**+*{2} mmmrrrkbb") << endl; // true 109 | return 0; 110 | } -------------------------------------------------------------------------------- /28_BracketCombinations.cpp: -------------------------------------------------------------------------------- 1 | // This challenge will require knowledge of basic mathematical combinations. 2 | /* 3 | have the function BracketCombinations(num) read num which will be an integer greater than or equal to zero, and return the number of valid combinations that can be formed with num pairs of parentheses. For example, if the input is 3, then the possible combinations of 3 pairs of parenthesis, namely: ()()(), are ()()(), ()(()), (())(), ((())), and (()()). There are 5 total combinations when the input is 3, so your program should return 5. 4 | */ 5 | 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | // NOT FINISHED 11 | 12 | int BracketCombinations(int num) 13 | { 14 | 15 | } 16 | 17 | int main() 18 | { 19 | cout << BracketCombinations(4) << endl; // 20 | cout << BracketCombinations(4) << endl; // 21 | cout << BracketCombinations(4) << endl; // 22 | return 0; 23 | } -------------------------------------------------------------------------------- /29_ArrayRotation.cpp: -------------------------------------------------------------------------------- 1 | // This challenge will require knowledge of arrays. 2 | /* 3 | have the function ArrayRotation(arr) take the arr parameter being passed which will be an array of non-negative integers and circularly rotate the array starting from the Nth element where N is equal to the first integer in the array. For example: if arr is [2, 3, 4, 1, 6, 10] then your program should rotate the array starting from the 2nd position because the first element in the array is 2. The final array will therefore be [4, 1, 6, 10, 2, 3], and your program should return the new array as a string, so for this example your program would return 4161023. The first element in the array will always be an integer greater than or equal to 0 and less than the size of the array. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | /* 13 | we can set up a list to pass the values to 14 | first determine the starting index 15 | 16 | iterate through the array in a circular fashion until all elements have been passed 17 | pass the elements from temp list to a string 18 | return the string value 19 | */ 20 | string ArrayRotation(int arr[], int size) 21 | { 22 | // our temp list 23 | vector list; 24 | 25 | // iterating through the array until all elements have been passed; 26 | int index = arr[0]; 27 | int count = 0; 28 | 29 | while (count < size) 30 | { 31 | // passing the value 32 | list.push_back(arr[index]); 33 | 34 | // updating our index 35 | index = (index%size) + 1; 36 | if (index == size) 37 | { 38 | index = 0; 39 | } 40 | count++; 41 | } 42 | 43 | // converting result into a string 44 | ostringstream convert; 45 | for (int x = 0; x < list.size(); x++) 46 | { 47 | convert << list[x]; 48 | } 49 | 50 | return convert.str(); 51 | } 52 | 53 | int main() 54 | { 55 | int A[] = { 2, 3, 4, 1, 6, 10 }; 56 | int B[] = { 3, 2, 1, 6 }; 57 | int C[] = { 4, 3, 4, 3, 1, 2 }; 58 | 59 | cout << ArrayRotation(A, sizeof(A)/sizeof(A[0])) << endl; // 4161023 60 | cout << ArrayRotation(B, sizeof(B) / sizeof(B[0])) << endl; // 6321 61 | cout << ArrayRotation(C, sizeof(C) / sizeof(C[0])) << endl; // 124343 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /2_Calculator.cpp: -------------------------------------------------------------------------------- 1 | // For this challenge you will be evaluating a mathematical expression within a string. 2 | /* 3 | have the function Calculator(str) take the str parameter being passed and evaluate the mathematical expression within in. For example, if str were "2+(3-1)*3" the output should be 8. Another example: if str were "(2-0)(6/2)" the output should be 6. There can be parenthesis within the string so you must evaluate it properly according to the rules of arithmetic. The string will contain the operators: +, -, /, *, (, and ). If you have a string like this: #/#*# or #+#(#)/#, then evaluate from left to right. So divide then multiply, and for the second one multiply, divide, then add. The evaluations will be such that there will not be any decimal operations, so you do not need to account for rounding and whatnot. 4 | */ 5 | #include 6 | #include 7 | #include 8 | #include 9 | using namespace std; 10 | 11 | // Operation function that performs the specified calculation depending on the operator 12 | int operation(int x, int y, char symbol) 13 | { 14 | if (symbol == '+') 15 | { 16 | return x + y; 17 | } 18 | else if (symbol == '-') 19 | { 20 | return x - y; 21 | } 22 | else if (symbol == '/') 23 | { 24 | return x / y; 25 | } 26 | else if (symbol == '*') 27 | { 28 | return x * y; 29 | } 30 | else 31 | return -1; 32 | } 33 | 34 | string Calculator(string str) { 35 | int index, start, end; 36 | start = end = 0; 37 | char symbol; 38 | vector list; 39 | bool analyzed, analyzed2; 40 | string num; 41 | int number; 42 | 43 | // Creating a list of int numbers that will be parallel to the string argument 44 | // This will aid with the calculations 45 | // Example numList = 2,-1,3 would be stringArg = "2+3" 46 | for (int x = 0; x <= str.length(); x++) 47 | { 48 | if (str[x] >= '0' && str[x] <= '9') 49 | { 50 | num += str[x]; 51 | } 52 | else 53 | { 54 | // inserting a misc value if the character is a symbol/non digit 55 | if (num.empty()) 56 | { 57 | list.push_back(-1); 58 | } 59 | else 60 | { 61 | // If is the digit is multiple ex.23,100,etc manipulate the string to stay parallel to the number list 62 | if (num.length() > 1) 63 | { 64 | str.erase(x - num.length(), num.length() - 1); 65 | x -= num.length() - 1; 66 | } 67 | // Converting to an int to include to the number list 68 | istringstream(num) >> number; 69 | list.push_back(number); 70 | if (x < str.length()-1) 71 | { 72 | list.push_back(-1); 73 | } 74 | num.clear(); 75 | } 76 | } 77 | } 78 | 79 | do 80 | { 81 | index = 0; 82 | for (index; index < str.length(); index++) 83 | { 84 | analyzed = false; 85 | analyzed2 = false; 86 | // Find the start of any parenthesis 87 | if (str[index] == '(') 88 | { 89 | start = index + 1; 90 | } 91 | // Find the end of any parenthesis 92 | if (str[index] == ')') 93 | { 94 | end = index; 95 | } 96 | // Analyze the inside content when both parenthesis have been found 97 | // Once the content has been analyzed search for any other parenthesis 98 | if (start && end) 99 | { 100 | for (start; start < end && !analyzed && !analyzed2; start++) 101 | { 102 | // In the case of calculating multiple operations ex. (2+3*4+4) 103 | if (end - start > 3) 104 | { 105 | number = start; 106 | while (start < end) // Multiply or Divide 107 | { 108 | if (str[start] == '*' || str[start] == '/') 109 | { 110 | symbol = str[start]; 111 | list[start - 1] = operation(list[start - 1], list[start + 1], symbol); 112 | list.erase(list.begin() + start, list.begin() + (start + 2)); 113 | str.erase(str.begin() + start, str.begin() + (start + 2)); 114 | end -= 2; 115 | } 116 | else 117 | start++; 118 | } 119 | // Reset back to the start of the parenthesis to now check for adding or subtracting 120 | start = number; 121 | while (start < end) // Add or Subtract 122 | { 123 | if (str[start] == '-' || str[start] == '+') 124 | { 125 | symbol = str[start]; 126 | list[start - 1] = operation(list[start - 1], list[start + 1], symbol); 127 | list.erase(list.begin() + start, list.begin() + (start + 2)); 128 | str.erase(str.begin() + start, str.begin() + (start + 2)); 129 | } 130 | else 131 | start++; 132 | } 133 | analyzed2 = true; 134 | start = number; 135 | } 136 | else if (str[start] == '*' || str[start] == '/') 137 | { 138 | symbol = str[start]; 139 | // perform the calculation inside the parenthesis 140 | list[start - 2] = operation(list[start - 1], list[start + 1], symbol); 141 | str[start - 2] = 'x'; 142 | // remove parenthesis and values involved in the operation 143 | list.erase(list.begin() + start - 1, list.begin() + (start + 3)); 144 | str.erase(str.begin() + start - 1, str.begin() + (start + 3)); 145 | index -= 4; 146 | // signal that the parenthesis has been analyzed 147 | analyzed = true; 148 | } 149 | else if (str[start] == '-' || str[start] == '+') 150 | { 151 | symbol = str[start]; 152 | list[start - 2] = operation(list[start - 1], list[start + 1], symbol); 153 | str[start - 2] = 'x'; 154 | list.erase(list.begin() + start - 1, list.begin() + (start + 3)); 155 | str.erase(str.begin() + start - 1, str.begin() + (start + 3)); 156 | index -= 4; 157 | analyzed = true; 158 | } 159 | } 160 | 161 | // In the case that there were no operations to perform inside 162 | // Remove parenthesis 163 | if (analyzed2) 164 | { 165 | list[start - 2] = list[start - 1]; 166 | str[start - 2] = 'x'; 167 | list.erase(list.begin() + start - 1, list.begin() + (start + 1)); 168 | str.erase(str.begin() + start - 1, str.begin() + (start + 1)); 169 | } 170 | else if (!analyzed) 171 | { 172 | list[end - 2] = list[end - 1]; 173 | str[end - 2] = 'x'; 174 | list.erase(list.begin() + start - 1, list.begin() + (start + 1)); 175 | str.erase(str.begin() + start - 1, str.begin() + (start + 1)); 176 | } 177 | start = end = 0; // Reset back in case there are multiple parenthesis 178 | } 179 | } 180 | 181 | index = 0; 182 | // Solve for any multiplication or division operations after no parenthesis 183 | while (index < str.length()) 184 | { 185 | if (str[index] == '*' || str[index] == '/') 186 | { 187 | symbol = str[index]; 188 | // calculate the operation 189 | list[index - 1] = operation(list[index - 1], list[index + 1], symbol); 190 | // remove the values involved in the operation 191 | list.erase(list.begin() + index, list.begin() + (index + 2)); 192 | str.erase(str.begin() + index, str.begin() + (index + 2)); 193 | } 194 | // Calculating when there are neighbor parenthesis ex. (2)(3) = 6 195 | else if ((str[index] >= '0' && str[index] <= '9' && str[index + 1] == 'x') || (str[index] == 'x' && str[index+1] == 'x')) 196 | { 197 | symbol = '*'; 198 | list[index+1] = operation(list[index], list[index + 1], symbol); 199 | list.erase(list.begin() + index, list.begin() + index + 1); 200 | str.erase(str.begin() + index, str.begin() + index + 1); 201 | } 202 | else 203 | index++; 204 | } 205 | 206 | index = 0; 207 | // Solve for any adding or subtracting operations after no parenthesis 208 | while (index < str.length()) 209 | { 210 | if (str[index] == '-' || str[index] == '+') 211 | { 212 | symbol = str[index]; 213 | list[index - 1] = operation(list[index - 1], list[index + 1], symbol); 214 | list.erase(list.begin() + index, list.begin() + (index + 2)); 215 | str.erase(str.begin() + index, str.begin() + (index + 2)); 216 | } 217 | else 218 | index++; 219 | } 220 | } while (str.length() > 1); 221 | 222 | // Converting the number value to a string 223 | stringstream convert; 224 | convert << list[0]; 225 | str = convert.str(); 226 | return str; 227 | } 228 | 229 | int main() { 230 | // keep this function call here 231 | cout << Calculator("6*(4/2)+3*1") << endl; // 15 232 | cout << Calculator("2+(3-1)*3") << endl; // 8 233 | cout << Calculator("(2)+4*2") << endl; // 10 234 | cout << Calculator("(2-0)(6/2)") << endl; // 6 235 | cout << Calculator("6/3-1") << endl; // 1 236 | cout << Calculator("2+4+5") << endl; // 11 237 | cout << Calculator("3+5*2*2") << endl; // 23 238 | cout << Calculator("2+7*2+2") << endl; // 18 239 | cout << Calculator("1+4*2+3*1") << endl; // 12 240 | cout << Calculator("45-10*2-1") << endl; // 24 241 | cout << Calculator("100*2") << endl; // 200 242 | cout << Calculator("7-2+(5-2)") << endl; // 8 243 | cout << Calculator("812/2*(5-3)") << endl; // 812 244 | cout << Calculator("7-4-1+8(3)/2") << endl; // 14 245 | cout << Calculator("(5-2*0-9*0)*0") << endl; // 0 246 | cout << Calculator("8-7*(12+100/2)*9-2") << endl; // -3900 247 | return 0; 248 | } 249 | -------------------------------------------------------------------------------- /30_ArrayCouples.cpp: -------------------------------------------------------------------------------- 1 | // This challenge will require knowledge of arrays. 2 | /* 3 | have the function ArrayCouples(arr) take the arr parameter being passed which will be an array of an even number of positive integers, and determine if each pair of integers, [k, k+1], [k+2, k+3], etc. in the array has a corresponding reversed pair somewhere else in the array. For example: if arr is [4, 5, 1, 4, 5, 4, 4, 1] then your program should output the string yes because the first pair 4, 5 has the reversed pair 5, 4 in the array, and the next pair, 1, 4 has the reversed pair 4, 1 in the array as well. But if the array doesn't contain all pairs with their reversed pairs, then your program should output a string of the integer pairs that are incorrect, in the order that they appear in the array. 4 | For example: if arr is [6, 2, 2, 6, 5, 14, 14, 1] then your program should output the string 5,14,14,1 with only a comma separating the integers. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | using namespace std; 13 | 14 | /* 15 | one approach is to traverse the array 16 | at each iteration store the pairs into a hash map 17 | when iterating check if the new pair is a reversed of a pair stored in our hash map 18 | 19 | if true, than remove the stored pair 20 | else add the new pair to our table 21 | */ 22 | string ArrayCouples(int arr[], int size) 23 | { 24 | map table; 25 | 26 | // traverse our array 27 | for (int x = 0; x < size - 1; x += 2) 28 | { 29 | bool found = false; 30 | 31 | // section to analyze our hash table 32 | for (map::iterator y = table.begin(); y != table.end(); y++) 33 | { 34 | // condition to check if pair has a reverse 35 | if ((y->first == arr[x] && y->second == arr[x + 1]) || (y->first == arr[x + 1] && y->second == arr[x])) 36 | { 37 | // remove the stored pair from our table 38 | table.erase(y->first); 39 | found = true; 40 | break; 41 | } 42 | } 43 | 44 | if (!found) 45 | { 46 | // adding to our table if the pair is new 47 | table[arr[x]] = arr[x + 1]; 48 | } 49 | } 50 | 51 | // checking result based on the hash table 52 | if (table.empty()) 53 | { 54 | return "yes"; 55 | } 56 | 57 | // converting to string 58 | ostringstream convert; 59 | for (map::iterator x = table.begin(); x != table.end(); x) 60 | { 61 | convert << x->first << "," << x->second; 62 | x++; 63 | 64 | if (x != table.end()) 65 | { 66 | convert << ","; 67 | } 68 | } 69 | 70 | return convert.str(); 71 | } 72 | 73 | int main() 74 | { 75 | int A[] = { 4, 5, 1, 4, 5, 4, 4, 1 }; 76 | int B[] = { 6, 2, 2, 6, 5, 14, 14, 1 }; 77 | int C[] = { 2, 1, 1, 2, 3, 3 }; 78 | int D[] = { 5, 4, 6, 7, 7, 6, 4, 5 }; 79 | 80 | cout << ArrayCouples(A, sizeof(A)/sizeof(A[0])) << endl; // yes 81 | cout << ArrayCouples(B, sizeof(B) / sizeof(B[0])) << endl; // 5,14,14,1 82 | cout << ArrayCouples(C, sizeof(C) / sizeof(C[0])) << endl; // 3,3 83 | cout << ArrayCouples(D, sizeof(D) / sizeof(D[0])) << endl; // yes 84 | return 0; 85 | 86 | } -------------------------------------------------------------------------------- /31_SimpleSAT.cpp: -------------------------------------------------------------------------------- 1 | // This challenge will require knowledge of basic Boolean logic. 2 | /* 3 | have the function SimpleSAT(str) read str which will be a string consisting of letters, parenthesis, logical operators and tilde's representing a Boolean formula. For example: str may be "(a&b)|c" which means (a AND b) OR c. Your program should output the string yes if there is some arrangement of replacing the letters with TRUE or FALSE in such a way that the formula equates to TRUE. If there is no possible way of assigning TRUE or FALSE to the letters, then your program should output the string no. In the example above, your program would return yes because a=TRUE, b=TRUE and c=FALSE would make the formula TRUE. Another example: if str is "((a&c)&~a)" which means ((a AND c) AND NOT a) then your program should output no because it is not possible to assign TRUE or FALSE values to the letters to produce a TRUE output. 4 | 5 | A Boolean formula will always have at most 5 letters, i.e. a, b, c, d and e. A tilde will never appear outside of a parenthesis, i.e. ~(a&b). 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | using namespace std; 12 | 13 | bool checkFormula(map , string, int&); 14 | 15 | /* 16 | traverse the string input 17 | any valid letters will be stored inside a map 18 | by default their bool value will be set to true 19 | only condition in which they are set to false is if there is an AND NOT sequence 20 | 21 | to analyze the formula we will use a recursive method 22 | we keep track of our overall bool value for the section we are analyzing 23 | at each iteration, by storing our operator we update our bool value based on the current value 24 | for example if operator is & and previous overall value is true but current is false 25 | our overall value is updated to false 26 | we make a recursive call for each opening parenthesis 27 | at the same time we update our index 28 | */ 29 | string SimpleSAT(string str) 30 | { 31 | map table; 32 | 33 | // traversing the string input to extract our letters 34 | for (int x = 0; x < str.length(); x++) 35 | { 36 | // getting the letters 37 | if (str[x] >= 'a' && str[x] <= 'z') 38 | { 39 | table[str[x]] = true; 40 | } 41 | 42 | // checking for special condition of an AND NOT sequence 43 | if (str[x] == '&' && str[x + 1] == '~') 44 | { 45 | x += 2; 46 | table[str[x]] = false; 47 | } 48 | } 49 | 50 | int start = 0; 51 | if (checkFormula(table,str, start)) // calling our method to check if the boolean formula is true or false 52 | { 53 | return "yes"; 54 | } 55 | else 56 | { 57 | return "no"; 58 | } 59 | } 60 | 61 | // method to analyze the boolean formula from the string input 62 | bool checkFormula(map table, string str, int& index) 63 | { 64 | int currentResult = 0; 65 | char currentOperator = 'x'; 66 | bool notEqual = false; 67 | 68 | // traversing the string to analyze it's content 69 | for (; index < str.length(); index++) 70 | { 71 | // condition to enter and analyze a parenthesis section 72 | if (str[index] == '(') 73 | { 74 | index++; 75 | currentResult = checkFormula(table, str, index); // getting the result from that section 76 | } 77 | else if (str[index] >= 'a' && str[index] <= 'z') 78 | { 79 | // condition to analyze current value based on our rules 80 | // get current boolean value and determine if a not operator was applied to it 81 | bool temp; 82 | if (notEqual) 83 | { 84 | temp = !table[str[index]]; 85 | } 86 | else 87 | { 88 | temp = table[str[index]]; 89 | } 90 | notEqual = false; 91 | 92 | // analyze which operator was included 93 | if (currentOperator == '&') 94 | { 95 | // we update our current result only if previous was true 96 | if (currentResult) 97 | { 98 | currentResult = temp; 99 | } 100 | } 101 | else if (currentOperator == '|') 102 | { 103 | // we can replace our current result only if new boolean value is true 104 | if (temp) 105 | { 106 | currentResult = temp; 107 | } 108 | } 109 | else 110 | { 111 | currentResult = temp; 112 | } 113 | } 114 | else if (str[index] == '&') // collect the AND operator 115 | { 116 | currentOperator = '&'; 117 | } 118 | else if (str[index] == '|') // collect the OR operator 119 | { 120 | currentOperator = '|'; 121 | } 122 | else if (str[index] == '~') // collect the NOT operator 123 | { 124 | notEqual = true; 125 | } 126 | else if (str[index] == ')') 127 | { 128 | // sending back our result pertaining to a section 129 | // this represents our base case 130 | return currentResult; 131 | } 132 | } 133 | 134 | return currentResult; 135 | } 136 | 137 | int main() 138 | { 139 | cout << SimpleSAT("(a&b)|c") << endl; // yes 140 | cout << SimpleSAT("((a&c)&~a)") << endl; // no 141 | cout << SimpleSAT("(a&b&c)|~a") << endl; // yes 142 | cout << SimpleSAT("a&(b|c)&~b&~c") << endl; // no 143 | cout << SimpleSAT("(a&(b)&~c)") << endl; // yes 144 | cout << SimpleSAT("(c|a|b)&~c") << endl; // yes 145 | return 0; 146 | } 147 | -------------------------------------------------------------------------------- /32_MatrixDeterminant.cpp: -------------------------------------------------------------------------------- 1 | // For this challenge you will calculate the determinant of a square matrix. 2 | /* 3 | have the function MatrixDeterminant(strArr) read strArr which will be an array of integers represented as strings. Within the array there will also be "<>" elements which represent break points. The array will make up a matrix where the (number of break points + 1) represents the number of rows. Here is an example of how strArr may look: ["1","2","<>","3","4"]. The contents of this array are row1=[1 2] and row2=[3 4]. Your program should take the given array of elements, create the proper matrix, and then calculate the determinant. For the example above, your program should return -2. If the matrix is not a square matrix, return -1. The maximum size of strArr will be a 6x6 matrix. The determinant will always be an integer. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | using namespace std; 12 | 13 | int calculator(vector < vector >); 14 | int getSum(vector ); 15 | 16 | /* 17 | first step is to pass the contents of the input array into a matrix layout 18 | for ease of access later on the type will be turned to integers 19 | 20 | after building the matrix we check if is not squared 21 | 22 | to calculate the determinant we will use a recursive approach 23 | we will pass it a matrix and check for its squared size 24 | base case will be when the matrix is 2x2 25 | 26 | at each iteration of the recursive method 27 | we keep track of whether leading value that is multiplied by determinant is positive or negative 28 | we continue to break the matrix down until we reach base case 29 | matrix is broken down based on the rule that is must not be in the same row or column of leading value 30 | 31 | This algorithm follows the Laplace Expansion rule 32 | Reference used https://www.mathsisfun.com/algebra/matrix-determinant.html 33 | */ 34 | int MatrixDeterminant(string strArr[], int size) 35 | { 36 | vector < vector > matrix; 37 | vector temp; 38 | 39 | // traversing the input array to build our matrix 40 | for (int x = 0; x < size; x++) 41 | { 42 | // condition to check for breakpoints 43 | if (strArr[x] == "<>") 44 | { 45 | matrix.push_back(temp); 46 | temp.clear(); 47 | } 48 | else 49 | { 50 | // converting to int 51 | int value; 52 | istringstream convert(strArr[x]); 53 | convert >> value; 54 | 55 | // adding to our row 56 | temp.push_back(value); 57 | } 58 | } 59 | 60 | // adding last row 61 | matrix.push_back(temp); 62 | temp.clear(); 63 | 64 | // checking if input matrix is square 65 | for (int row = 0; row < matrix.size(); row++) 66 | { 67 | if (matrix[row].size() != matrix.size()) 68 | { 69 | return -1; 70 | } 71 | } 72 | 73 | // getting the result 74 | return calculator(matrix); 75 | } 76 | 77 | /* 78 | Determinant calculator method 79 | This takes a squared matrix as input 80 | based on the square size it will either perform the calculation when size of matrix is 2x2 81 | or continue to break down a matrix 82 | it keeps track of leading value and whether we add or subtract 83 | */ 84 | int calculator(vector < vector > currentMatrix) 85 | { 86 | // base case when a matrix is 2x2 87 | if (currentMatrix.size() == 2) 88 | { 89 | return (currentMatrix[0][0] * currentMatrix[1][1]) - (currentMatrix[0][1] * currentMatrix[1][0]); 90 | } 91 | 92 | // flag to keep track of whether to add or subtract 93 | bool positiveSign = true; 94 | 95 | // list to store results, for calculating after 96 | vector result; 97 | 98 | // traversing all the leading values for the current matrix 99 | for (int row = 0; row < 1; row++) 100 | { 101 | for (int col = 0; col < currentMatrix.size(); col++) 102 | { 103 | // getting the leading value and determine if we add or subtract 104 | int leadingValue = currentMatrix[row][col]; 105 | if (!positiveSign) 106 | { 107 | leadingValue *= -1; 108 | positiveSign = true; 109 | } 110 | else 111 | { 112 | positiveSign = false; 113 | } 114 | 115 | // section to build the new matrix that does not include the row or column of our current leading value 116 | vector < vector > newMatrix; 117 | vector temp; 118 | 119 | // iteration for building our new matrix 120 | for (int x = 0; x < currentMatrix.size(); x++) 121 | { 122 | // condition to avoid adding a row that is part of the value 123 | if (x == row) 124 | { 125 | continue; 126 | } 127 | else 128 | { 129 | for (int y = 0; y < currentMatrix.size(); y++) 130 | { 131 | // condition to avoid adding values from a column that are part of the leading value 132 | if (y == col) 133 | { 134 | continue; 135 | } 136 | else 137 | { 138 | temp.push_back(currentMatrix[x][y]); 139 | } 140 | } 141 | 142 | // adding row content to our new matrix 143 | newMatrix.push_back(temp); 144 | 145 | // clearing the contents of the row 146 | temp.clear(); 147 | } 148 | } 149 | 150 | // adding result for this leading value into a list 151 | result.push_back(leadingValue * calculator(newMatrix)); 152 | 153 | // reset the new matrix 154 | newMatrix.clear(); 155 | } 156 | } 157 | 158 | return getSum(result); 159 | } 160 | 161 | // getSum method, returns the sum of a list 162 | int getSum(vector results) 163 | { 164 | int total = 0; 165 | for (int x = 0; x < results.size(); x++) 166 | { 167 | total += results[x]; 168 | } 169 | 170 | return total; 171 | } 172 | 173 | int main() 174 | { 175 | string A[] = { "1", "2", "<>", "3", "4" }; 176 | string B[] = { "5", "0", "<>", "0", "5" }; 177 | string C[] = { "1", "2", "4", "<>", "2", "1", "1", "<>", "4", "1", "1" }; 178 | string D[] = { "3", "8", "<>", "4", "6" }; 179 | string E[] = { "6", "1", "1", "<>", "4", "-2", "5", "<>", "2", "8", "7" }; 180 | string F[] = { "1", "2", "<>", "2", "1", "<>", "1", "1", "1" }; 181 | string G[] = { "1", "2", "3", "4", "5", "<>", "2", "2", "4", "5", "6", "<>", "3", "4", "4", "5", "6", "<>", "4", "5", "5", "0", "1", "<>", "5", "6", "6", "1", "1" }; 182 | string H[] = { "1000", "2", "3", "4", "5", "<>", "2", "2", "4", "5", "6", "<>", "3", "4", "4", "5", "6", "<>", "4", "5", "5", "0", "1", "<>", "5", "6", "6", "1", "1000" }; 183 | string I[] = { "1", "2", "3", "4", "<>", "2", "6", "4", "2", "<>", "6", "6", "1", "1", "<>", "4", "8", "0", "1" }; 184 | string J[] = { "6", "4", "2", "<>", "6", "1", "1", "<>", "8", "0", "1" }; 185 | string K[] = { "1", "2", "3", "4", "<>", "5", "6", "7", "8", "<>", "9", "10", "11", "12", "<>", "13", "14", "15", "16" }; 186 | string L[] = { "4", "2", "1", "3", "<>", "8", "2", "6", "6", "<>", "1", "1", "4", "2", "<>", "0", "1", "6", "6" }; 187 | string M[] = { "2", "6", "4", "<>", "6", "6", "1", "<>", "4", "8", "0" }; 188 | string N[] = { "2", "4", "5", "6", "<>", "4", "4", "5", "6", "<>", "5", "5", "0", "1", "<>", "6", "6", "1", "1" }; 189 | 190 | cout << MatrixDeterminant(A, sizeof(A)/sizeof(A[0])) << endl; // -2 191 | cout << MatrixDeterminant(B, sizeof(B) / sizeof(B[0])) << endl; // 25 192 | cout << MatrixDeterminant(C, sizeof(C) / sizeof(C[0])) << endl; // -4 193 | cout << MatrixDeterminant(D, sizeof(D) / sizeof(D[0])) << endl; // -14 194 | cout << MatrixDeterminant(E, sizeof(E) / sizeof(E[0])) << endl; // -306 195 | cout << MatrixDeterminant(F, sizeof(F) / sizeof(F[0])) << endl; // -1 196 | cout << MatrixDeterminant(G, sizeof(G) / sizeof(G[0])) << endl; // 43 197 | cout << MatrixDeterminant(H, sizeof(H) / sizeof(H[0])) << endl; // 49801192 198 | cout << MatrixDeterminant(I, sizeof(I) / sizeof(I[0])) << endl; // -294 199 | cout << MatrixDeterminant(J, sizeof(J) / sizeof(J[0])) << endl; // -2 200 | cout << MatrixDeterminant(K, sizeof(K) / sizeof(K[0])) << endl; // 0 201 | cout << MatrixDeterminant(L, sizeof(L) / sizeof(L[0])) << endl; // -148 202 | cout << MatrixDeterminant(M, sizeof(M) / sizeof(M[0])) << endl; // 104 203 | cout << MatrixDeterminant(N, sizeof(N) / sizeof(N[0])) << endl; // -62 204 | return 0; 205 | } 206 | -------------------------------------------------------------------------------- /33_CountingAnagrams.cpp: -------------------------------------------------------------------------------- 1 | // For this challenge you will determine how many anagrams exist in a string. 2 | /* 3 | have the function CountingAnagrams(str) take the str parameter and determine how many anagrams exist in the string. An anagram is a new word that is produced from rearranging the characters in a different word, for example: cars and arcs are anagrams. Your program should determine how many anagrams exist in a given string and return the total number. For example: if str is "cars are very cool so are arcs and my os" then your program should return 2 because "cars" and "arcs" form 1 anagram and "so" and "os" form a 2nd anagram. The word "are" occurs twice in the string but it isn't an anagram because it is the same word just repeated. The string will contain only spaces and lowercase letters, no punctuation, numbers, or uppercase letters. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | using namespace std; 13 | 14 | 15 | /* 16 | Solution will involve 17 | first traverse the string and extract each word 18 | at each step store the words into a table, with the word and its length 19 | 20 | we make comparisons of words with equal length 21 | first ensure they are not repeats 22 | second we iterate and check if all characters match 23 | if true remove previous stored pair from table 24 | 25 | continue stepping through the input 26 | until all words have been analyzed 27 | */ 28 | int CountingAnagrams(string str) 29 | { 30 | vector list; 31 | map table; 32 | int total = 0; 33 | 34 | istringstream convert(str); 35 | 36 | // loop to pass the words to our list for ease of use later on 37 | string current; 38 | while (convert >> current) 39 | { 40 | bool repeat = false; 41 | 42 | // condition to avoid adding repeats 43 | for (int x = 0; x < list.size(); x++) 44 | { 45 | if (current == list[x]) 46 | { 47 | repeat = true; 48 | break; 49 | } 50 | } 51 | 52 | if (!repeat) 53 | { 54 | list.push_back(current); 55 | } 56 | } 57 | 58 | // adding first word 59 | table[list[0]] = list[0].length(); 60 | 61 | // loop to analyze each word from our input 62 | for (int x = 1; x < list.size(); x++) 63 | { 64 | // check if there are possible anagrams in our table 65 | for (map::iterator y = table.begin(); y != table.end(); y++) 66 | { 67 | // possible match 68 | if (y->second == list[x].length()) 69 | { 70 | // ensure is not a repeat 71 | if (y->first != list[x]) 72 | { 73 | string temp = y->first; 74 | bool anagram = true; 75 | 76 | // traverse current words and check if they match 77 | for (int z = 0; z < list[x].length(); z++) 78 | { 79 | int currentIndex = temp.find(list[x][z]); 80 | 81 | // ensure all characters match 82 | // also that no repeat of characters is found (aabc compared with abbc) 83 | if (currentIndex == -1) 84 | { 85 | // not anagrams so we add new word to the table 86 | table[list[x]] = list[x].length(); 87 | anagram = false; 88 | break; 89 | } 90 | else 91 | { 92 | temp.erase(temp.begin() + currentIndex); 93 | } 94 | } 95 | 96 | // update our total; 97 | if (anagram) 98 | { 99 | total++; 100 | break; 101 | } 102 | } 103 | } 104 | else 105 | { 106 | // adding new word to list that has no possible matching anagram 107 | table[list[x]] = list[x].length(); 108 | } 109 | } 110 | } 111 | 112 | return total; 113 | } 114 | 115 | int main() 116 | { 117 | cout << CountingAnagrams("cars are very cool so are arcs and my os") << endl; // 2 118 | cout << CountingAnagrams("aa aa odg dog gdo") << endl; // 2 119 | cout << CountingAnagrams("a c b c run urn urn") << endl; // 1 120 | cout << CountingAnagrams("mom omm mmo pop opp") << endl; // 3 121 | return 0; 122 | } -------------------------------------------------------------------------------- /34_BipartiteMatching.cpp: -------------------------------------------------------------------------------- 1 | // For this challenge you will be finding the maximum cardinality matching of a bipartite graph. 2 | /* 3 | have the function BipartiteMatching(strArr) read strArr which will be an array of hyphenated letters representing paths from the first node to the second node. For example: ["a->d", "a->e", "b->f", "c->e"] means that there is a path from node a to d, a to e, b to f, and so on. The graph will be bipartite meaning that it is possible to separate the nodes into two disjoint sets such that every edge only connects a node from the lefthand side to a node on the righthand side. Your program should determine the maximum cardinality matching of the bipartite graph, which means finding the largest possible number of non-adjacent edges that are matching. So for the example above, your program should return 3 because it is possible to connect every single node on the left to a node on the right. 4 | 5 | The input will only contain lowercase alphabetic characters with a -> between them signifying an edge between them going from the left node to the right node. The input will contain at least 1 edge connecting 2 nodes. 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | using namespace std; 14 | 15 | 16 | /* 17 | first traverse the string array to store the vertices 18 | at each iteration we can insert the right hand vertex into a hash table 19 | if the key/right hand vertex is repeated we ignore the current connection 20 | we update our count only when right hand vextex is not part of the connections we have gathered 21 | also when left hand vertex does not repeat 22 | we will apply this greedy approach to both scenarios of start to end 23 | and end to start 24 | */ 25 | int BipartiteMatching(string strArr[], int size) 26 | { 27 | map table; 28 | int total = 0; 29 | int total2 = 0; 30 | 31 | // traverse the input array 32 | // greedy approach from start to end 33 | for (int x = 0; x < size; x++) 34 | { 35 | // analyzing the current connection 36 | string current = strArr[x]; 37 | 38 | // extracting the node values 39 | char leftNode = current[0]; 40 | char rightNode = current[3]; 41 | 42 | // condition to check if edge connection is unique 43 | if (table.count(rightNode) == 0) 44 | { 45 | bool repeat = false; 46 | 47 | // check that left hand vertex does not repeat 48 | for (map::iterator y = table.begin(); y != table.end(); y++) 49 | { 50 | if (y->second == leftNode) 51 | { 52 | repeat = true; 53 | break; 54 | } 55 | } 56 | 57 | // updates our total if current edge connection is valid 58 | if (!repeat) 59 | { 60 | table[rightNode] = leftNode; 61 | total++; 62 | } 63 | } 64 | } 65 | 66 | // reseting our table 67 | table.clear(); 68 | 69 | // greedy approach from end to start 70 | for (int x = size-1; x >= 0; x--) 71 | { 72 | // analyzing the current connection 73 | string current = strArr[x]; 74 | 75 | // extracting the node values 76 | char leftNode = current[0]; 77 | char rightNode = current[3]; 78 | 79 | // condition to check if edge connection is unique 80 | if (table.count(rightNode) == 0) 81 | { 82 | bool repeat = false; 83 | 84 | // check that left hand vertex does not repeat 85 | for (map::iterator y = table.begin(); y != table.end(); y++) 86 | { 87 | if (y->second == leftNode) 88 | { 89 | repeat = true; 90 | break; 91 | } 92 | } 93 | 94 | if (!repeat) 95 | { 96 | table[rightNode] = leftNode; 97 | total2++; 98 | } 99 | } 100 | } 101 | 102 | // getting the result 103 | if (total > total2) 104 | { 105 | return total; 106 | } 107 | return total2; 108 | } 109 | 110 | int main() 111 | { 112 | string A[] = { "a->d", "a->e", "b->f", "c->e" }; 113 | string B[] = { "a->w", "a->x", "b->x", "b->y", "c->x", "c->z", "d->w" }; 114 | string C[] = { "a->b", "c->b", "c->d", "e->b" }; 115 | string D[] = { "a->w", "a->x", "b->y", "c->y", "d->z", "d->r", "e->z", "f->y" }; 116 | 117 | cout << BipartiteMatching(A, sizeof(A)/sizeof(A[0])) << endl; // 3 118 | cout << BipartiteMatching(B, sizeof(B) / sizeof(B[0])) << endl; // 4 119 | cout << BipartiteMatching(C, sizeof(C) / sizeof(C[0])) << endl; // 2 120 | cout << BipartiteMatching(D, sizeof(D) / sizeof(D[0])) << endl; // 4 121 | return 0; 122 | } -------------------------------------------------------------------------------- /35_NoughtsDeterminer.cpp: -------------------------------------------------------------------------------- 1 | // For this challenge you will be determining the winning position of a Tic-tac-toe board. 2 | /* 3 | have the function NoughtsDeterminer(strArr) take the strArr parameter being passed which will be an array of size eleven. The array will take the shape of a Tic-tac-toe board with spaces strArr[3] and strArr[7] being the separators ("<>") between the rows, and the rest of the spaces will be either "X", "O", or "-" which signifies an empty space. So for example strArr may be ["X","O","-","<>","-","O","-","<>","O","X","-"]. This is a Tic-tac-toe board with each row separated double arrows ("<>"). Your program should output the space in the array by which any player could win by putting down either an "X" or "O". In the array above, the output should be 2 because if an "O" is placed in strArr[2] then one of the players wins. Each board will only have one solution for a win, not multiple wins. You output should never be 3 or 7 because those are the separator spaces. 4 | */ 5 | 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | bool checkHorizontal(string[],int,string); 11 | bool checkVertical(string[],int,string); 12 | bool checkDiagonal(string[],int, string); 13 | 14 | /* 15 | Solution involves traversing the input array 16 | at each index equal to "-" we check for possible solutions 17 | we call on helper functions to check for horizontal,vertical and diagonal solution 18 | */ 19 | int NoughtsDeterminer(string strArr[]) 20 | { 21 | // traverse the array 22 | for (int x = 0; x < 11; x++) 23 | { 24 | // condition to check if current spot has a winning condition for either X or O 25 | if (strArr[x] == "-") 26 | { 27 | if (checkHorizontal(strArr, x, "O") || checkVertical(strArr, x, "O") || checkDiagonal(strArr,x, "O")) 28 | { 29 | return x; 30 | } 31 | else if (checkHorizontal(strArr, x, "X") || checkVertical(strArr, x, "X") || checkDiagonal(strArr,x, "X")) 32 | { 33 | return x; 34 | } 35 | } 36 | } 37 | } 38 | 39 | // method to check for winning solution going horizontal 40 | bool checkHorizontal(string arr[], int index, string symbol) 41 | { 42 | // checking which row to analyze 43 | if (index < 3) 44 | { 45 | for (int x = 0; x < 3; x++) 46 | { 47 | if (x == index) 48 | { 49 | continue; 50 | } 51 | 52 | if (arr[x] != symbol) 53 | { 54 | return false; 55 | } 56 | } 57 | return true; 58 | } 59 | else if (index > 3 && index < 7) 60 | { 61 | for (int x = 4; x < 7; x++) 62 | { 63 | if (x == index) 64 | { 65 | continue; 66 | } 67 | 68 | if (arr[x] != symbol) 69 | { 70 | return false; 71 | } 72 | } 73 | return true; 74 | } 75 | else if (index > 7) 76 | { 77 | for (int x = 8; x < 11; x++) 78 | { 79 | if (x == index) 80 | { 81 | continue; 82 | } 83 | 84 | if (arr[x] != symbol) 85 | { 86 | return false; 87 | } 88 | } 89 | return true; 90 | } 91 | 92 | return false; 93 | } 94 | 95 | // method to check for a winning solution going vertical 96 | bool checkVertical(string arr[], int index, string symbol) 97 | { 98 | // locating index location 99 | if (index < 3) 100 | { 101 | if (arr[index+4] == symbol && arr[index+8] == symbol) 102 | { 103 | return true; 104 | } 105 | } 106 | else if (index > 3 && index < 7) 107 | { 108 | if (arr[index+4] == symbol && arr[index-4] == symbol) 109 | { 110 | return true; 111 | } 112 | } 113 | else if (index > 7) 114 | { 115 | if (arr[index-4] == symbol && arr[index-8] == symbol) 116 | { 117 | return true; 118 | } 119 | } 120 | 121 | return false; 122 | } 123 | 124 | // method to check for a winning solution going diagonal 125 | bool checkDiagonal(string arr[], int index, string symbol) 126 | { 127 | // checking which row to analyze 128 | if (index < 3) 129 | { 130 | if ((arr[5] == symbol && arr[8] == symbol && index == 2) || (arr[5] == symbol && arr[10] == symbol && index == 0)) 131 | { 132 | return true; 133 | } 134 | } 135 | else if (index > 3 && index < 7) 136 | { 137 | if ((arr[2] == symbol && arr[8] == symbol && index == 5) || (arr[0] == symbol && arr[10] == symbol && index == 5)) 138 | { 139 | return true; 140 | } 141 | } 142 | else if (index > 7) 143 | { 144 | if ((arr[5] == symbol && arr[0] == symbol && index == 10) || (arr[5] == symbol && arr[2] == symbol && index == 8)) 145 | { 146 | return true; 147 | } 148 | } 149 | 150 | return false; 151 | } 152 | 153 | int main() 154 | { 155 | string A[] = { "X", "O", "-", "<>", "-", "O", "-", "<>", "O", "X", "-" }; 156 | string B[] = { "X", "-", "O", "<>", "-", "-", "O", "<>", "-", "-", "X" }; 157 | string C[] = { "X", "O", "X", "<>", "-", "O", "O", "<>", "X", "X", "O" }; 158 | string D[] = { "O", "-", "O", "<>", "-", "X", "-", "<>", "-", "-", "X" }; 159 | string E[] = { "X", "-", "X", "<>", "-", "O", "-", "<>", "-", "-", "O" }; 160 | string F[] = { "X", "-", "X", "<>", "-", "-", "O", "<>", "O", "-", "-" }; 161 | string G[] = { "X", "O", "X", "<>", "-", "O", "-", "<>", "-", "-", "-" }; 162 | 163 | cout << NoughtsDeterminer(A) << endl; // 2 164 | cout << NoughtsDeterminer(B) << endl; // 5 165 | cout << NoughtsDeterminer(C) << endl; // 4 166 | cout << NoughtsDeterminer(D) << endl; // 1 167 | cout << NoughtsDeterminer(E) << endl; // 1 168 | cout << NoughtsDeterminer(F) << endl; // 1 169 | cout << NoughtsDeterminer(G) << endl; // 9 170 | return 0; 171 | } -------------------------------------------------------------------------------- /36_SquareFigures.cpp: -------------------------------------------------------------------------------- 1 | // For this challenge you will be determining squares of certain numbers. 2 | /* 3 | have the function SquareFigures(num) read num which will be an integer. Your program should return the smallest integer that when squared has a length equal to num. For example: if num is 6 then your program should output 317 because 317^2 = 100489 while 316^2 = 99856 which does not have a length of six. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | using namespace std; 10 | 11 | /* 12 | first get the total length as a squared value 13 | so instance if input is 2, length as value is 10 14 | 3 = 100 15 | 4 = 1000 16 | etc 17 | 18 | we than apply a square root to our length value to determine a starting point 19 | for finding smallest integer that when squared has same length as input 20 | doing the square root, works similar to a binary search, we can eliminate non redundant iterations 21 | */ 22 | long long SquareFigures(int num) 23 | { 24 | long long length = 1; 25 | 26 | // base case 27 | if (num == 1) 28 | { 29 | return 0; 30 | } 31 | 32 | // getting the length as a value 33 | for (int x = 0; x < num - 1; x++) 34 | { 35 | length *= 10; 36 | } 37 | 38 | // getting start number through square root to avoid having to do a linear approach 39 | long long start = sqrt(length); 40 | long long squaredResult = pow(start, 2); 41 | 42 | // iterate from the start integer until the squared result has same length as input 43 | while (squaredResult < length) 44 | { 45 | start++; 46 | 47 | // updating our squared result 48 | squaredResult = pow(start, 2); 49 | } 50 | 51 | return start; 52 | } 53 | 54 | int main() 55 | { 56 | cout << SquareFigures(6) << endl; // 317 57 | cout << SquareFigures(2) << endl; // 4 58 | cout << SquareFigures(1) << endl; // 0 59 | cout << SquareFigures(3) << endl; // 10 60 | cout << SquareFigures(5) << endl; // 100 61 | cout << SquareFigures(7) << endl; // 1000 62 | cout << SquareFigures(9) << endl; // 10000 63 | cout << SquareFigures(11) << endl; // 10000 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /37_AlphabetRunEncryption.cpp: -------------------------------------------------------------------------------- 1 | // For this challenge you will be decoding a message. 2 | /* 3 | have the function AlphabetRunEncryption(str) read the str parameter being passed which will be an encrypted string and your program should output the original decrypted string. The encryption being used is the following: For every character i in str up to the second to last character, take the i and i+1 characters and encode them by writing the letters of the alphabet, in order, that range in the same direction between those chosen characters. For example: if the original string were bo then it would be encoded as cdefghijklmn, but if the string were boa then bo is encoded as cdefghijklmn and oa is encoded as nmlkjihgfedcb with the final encrypted string being cdefghijklmnnmlkjihgfedcb. So str may be something like the encrypted string just written, and your program should decrypt it and output the original message. 4 | 5 | The input string will only contains lowercase characters (a...z). There are also three important rules to this encryption based on specific character sequences. 6 | 7 | 1) If the original string contains only one letter between two chosen characters, such as the string ac then this would be encrypted as bR with R standing for what direction in the alphabet to go in determining the original characters. The encrypted string bR represents ac but the encrypted string bL represents ca (R = right, L = left). 8 | 9 | 2) If the original string contains zero letters between two chosen characters, such as the string ab then this would be encrypted as abS, with S representing the fact that no decryption is needed on the two letters preceding S. For example, if the original string were aba then the encryption would be abSbaS, but be careful because decrypting this you get abba, but the actual original string is aba. 10 | 11 | 3) If the original string contains a repeat of letters, such as the string acc then this would be encrypted as bRcN, with N representing the fact that no change in characters occurred on the character preceding N. The input string will never only be composed of repeated characters. 12 | */ 13 | 14 | #include 15 | #include 16 | using namespace std; 17 | 18 | void sequenceBreak(string&, char, char, bool&, bool&); 19 | 20 | /* 21 | as we traverse the string we check if next character is an increment or decrement alphabetically 22 | we keep track of our starting letter and ending letter 23 | 24 | when sequence breaks, if it broke due to a letter 25 | we write out the pair (cdef) = bg 26 | 27 | else if next letter of start is 'N' just process the repeat 28 | 29 | if next letter of start/current is 'R' get pair from right to left 30 | if is 'L' get pair from left to right 31 | 32 | if next letter of start/current is 'S' process the pair 33 | note always check for possible repeats, that is if another pair starts with same letter 34 | as previous pair (abba = aba) 35 | */ 36 | string AlphabetRunEncryption(string str) 37 | { 38 | char start = NULL; 39 | char end = NULL; 40 | bool forward = false; 41 | bool backward = false; 42 | 43 | string result = ""; 44 | string temp = ""; 45 | 46 | // traverse the string 47 | for (int current = 0; current < str.length(); current++) 48 | { 49 | // condition to determine a possible sequence start 50 | if (start == NULL) 51 | { 52 | start = str[current]; 53 | end = str[current]; 54 | } 55 | // forward sequence = a->b->c etc 56 | // providing a bound check in case of neighboring characters that belong to the S rule 57 | else if (str[current] == char(end + 1) && current < str.length() - 2 && str[current + 2] != 'S') 58 | { 59 | end = str[current]; 60 | forward = true; 61 | } 62 | // backward sequence = c->b->a etc 63 | else if (str[current] == char(end - 1) && current < str.length()-2 && str[current + 2] != 'S') 64 | { 65 | end = str[current]; 66 | backward = true; 67 | } 68 | // contains no letter between the characters 69 | else if (str[current] == 'S') 70 | { 71 | // first check for no repeats before appending 72 | if (!result.empty() && result[result.length() - 1] == start) 73 | { 74 | result.push_back(end); 75 | } 76 | else 77 | { 78 | result.push_back(start); 79 | result.push_back(end); 80 | } 81 | 82 | // reseting our start and end characters to analyze a new sequence 83 | start = end = NULL; 84 | } 85 | // condition for repeat in letters 86 | else if (str[current] == 'N') 87 | { 88 | // fix possible sequence break 89 | if (end != start) 90 | { 91 | sequenceBreak(result, start, str[current-2], forward, backward); 92 | } 93 | 94 | // append repeating character 95 | result.push_back(end); 96 | 97 | // reseting our start and end characters 98 | start = end = NULL; 99 | } 100 | // single letter between characters going to the right direction 101 | else if (str[current] == 'R') 102 | { 103 | // checking for repeats 104 | if (!result.empty() && result[result.length() - 1] == char(start - 1)) 105 | { 106 | result.push_back(char(start + 1)); 107 | } 108 | else 109 | { 110 | result.push_back(char(start - 1)); 111 | result.push_back(char(start + 1)); 112 | } 113 | 114 | // reseting our start and end characters 115 | start = end = NULL; 116 | } 117 | // single letter going to the left direction 118 | else if (str[current] == 'L') 119 | { 120 | if (!result.empty() && result[result.length() - 1] == char(start + 1)) 121 | { 122 | result.push_back(char(start - 1)); 123 | } 124 | else 125 | { 126 | result.push_back(char(start + 1)); 127 | result.push_back(char(start - 1)); 128 | } 129 | 130 | // reseting our start and end characters 131 | start = end = NULL; 132 | } 133 | // if no other conditions are met a sequence was broken due to different characters 134 | else 135 | { 136 | // will analyze sequence only when all valid character pertaining to the sequence are gathered 137 | // if not analyzed we continue appending 138 | if ((start != char(end + 1) && start != char(end - 1) && start != end) && 139 | !(current == str.length() - 2 && str[current + 1] >= 'a' && str[current + 1] <= 'z') && 140 | current != str.length()-1) 141 | { 142 | sequenceBreak(result, start, end, forward, backward); 143 | 144 | // resetting our start and end to the current letter 145 | start = str[current]; 146 | end = str[current]; 147 | } 148 | else if (str[current] == char(end + 1)) 149 | { 150 | end = str[current]; 151 | } 152 | else if (str[current] == char(end - 1)) 153 | { 154 | end = str[current]; 155 | } 156 | } 157 | } 158 | 159 | // final condition in case last character is part of a sequence that was not analyzed 160 | if (end >= 'a' && end <= 'z') 161 | { 162 | sequenceBreak(result, start, end, forward, backward); 163 | } 164 | 165 | return result; 166 | } 167 | 168 | // helper function that will update our result when a sequence breaks due to different alphabetical characters 169 | void sequenceBreak(string& result, char start, char end, bool& forward, bool& backward) 170 | { 171 | // checking the direction 172 | if (forward) 173 | { 174 | // avoiding repeats 175 | if (!result.empty() && result[result.length() - 1] == char(start - 1)) 176 | { 177 | result.push_back(char(end + 1)); 178 | } 179 | else 180 | { 181 | result.push_back(char(start - 1)); 182 | result.push_back(char(end + 1)); 183 | } 184 | 185 | forward = false; 186 | } 187 | else if (backward) 188 | { 189 | if (!result.empty() && result[result.length() - 1] == char(start + 1)) 190 | { 191 | result.push_back(char(end - 1)); 192 | } 193 | else 194 | { 195 | result.push_back(char(start + 1)); 196 | result.push_back(char(end - 1)); 197 | } 198 | 199 | backward = false; 200 | } 201 | } 202 | 203 | int main() 204 | { 205 | cout << AlphabetRunEncryption("cdefghijklmnnmlkjihgfedcb") << endl; // boa 206 | cout << AlphabetRunEncryption("bcdefghijklmnopqrstN") << endl; // att 207 | cout << AlphabetRunEncryption("abSbaSaNbR") << endl; // abaac 208 | cout << AlphabetRunEncryption("defghijklmnnmlkjihgfedeS") << endl; // code 209 | return 0; 210 | } -------------------------------------------------------------------------------- /38_SymmetricMatrix.cpp: -------------------------------------------------------------------------------- 1 | // For this challenge you will determine whether a matrix is symmetric or not. 2 | /* 3 | have the function SymmetricMatrix(strArr) read strArr which will be an array of integers represented as strings. Within the array there will also be "<>" elements which represent break points. The array will make up a matrix where the (number of break points + 1) represents the number of rows. Here is an example of how strArr may look: ["1","0","1","<>","0","1","0","<>","1","0","1"]. There are two "<>", so 2 + 1 = 3. Therefore there will be three rows in the array and the contents will be row1=[1 0 1], row2=[0 1 0] and row3=[1 0 1]. Your program should take the given array of elements, create the proper matrix, and then determine whether the matrix is symmetric, in other words, if matrix M is equal to M transpose. If it is, return the string symmetric and if it isn't return the string not symmetric. A matrix may or may not be a square matrix and if this is the case you should return the string not possible. For the example above, your program should return symmetric. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | using namespace std; 10 | 11 | /* 12 | first step is to traverse the string array and build a matrix 13 | separate to a different row when we reach the element "<>" 14 | 15 | once the matrix is build first check if is a square 16 | we can get a size for the rows and columns 17 | if not a square return "not possible" 18 | 19 | if is a square we check if is symmetric 20 | we traverse our build matrix for each row create a column in a new matrix 21 | after new matrix is build we can check that all elements are equals in both 22 | */ 23 | string SymmetricMatrix(string strArr[], int size) 24 | { 25 | vector > matrix; 26 | vector > matrix2; 27 | vector temp; 28 | 29 | // traversing input array to build matrix 30 | for (int x = 0; x < size; x++) 31 | { 32 | // adding the new row 33 | if (strArr[x] == "<>") 34 | { 35 | matrix.push_back(temp); 36 | temp.clear(); 37 | } 38 | else 39 | { 40 | temp.push_back(strArr[x]); 41 | } 42 | } 43 | 44 | // adding the last row 45 | matrix.push_back(temp); 46 | temp.clear(); 47 | 48 | // checking that the matrix is squared; 49 | int width = matrix[0].size(); 50 | int heigth = matrix.size(); 51 | 52 | if (width != heigth) 53 | { 54 | return "not possible"; 55 | } 56 | 57 | // creating a skeleton for our second matrix 58 | for (int x = 0; x < heigth; x++) 59 | { 60 | vector tempRow; 61 | 62 | matrix2.push_back(tempRow); 63 | } 64 | 65 | // creating a transpose of our current matrix 66 | for (int x = 0; x < matrix.size(); x++) 67 | { 68 | // get the elements of current row which will represent a column in our second matrix 69 | for (int y = 0; y < matrix[x].size(); y++) 70 | { 71 | temp.push_back(matrix[x][y]); 72 | } 73 | 74 | // creating the column for our second matrix 75 | for (int z = 0; z < temp.size(); z++) 76 | { 77 | matrix2[z].push_back(temp[z]); 78 | } 79 | 80 | // reseting the row 81 | temp.clear(); 82 | } 83 | 84 | // traversal to check if matrix is symmetric 85 | for (int row = 0; row < matrix.size(); row++) 86 | { 87 | for (int col = 0; col < matrix[row].size(); col++) 88 | { 89 | if (matrix[row][col] != matrix2[row][col]) 90 | { 91 | return "not symmetric"; 92 | } 93 | } 94 | } 95 | 96 | return "symmetric"; 97 | } 98 | 99 | int main() 100 | { 101 | string A[] = { "1", "0", "1", "<>", "0", "1", "0", "<>", "1", "0", "1" }; 102 | string B[] = { "5", "0", "<>", "0", "5" }; 103 | string C[] = { "1", "2", "4", "<>", "2", "1", "1", "<>", "-4", "1", "-1" }; 104 | 105 | cout << SymmetricMatrix(A,sizeof(A)/sizeof(A[0])) << endl; // symmetric 106 | cout << SymmetricMatrix(B, sizeof(B) / sizeof(B[0])) << endl; // symmetric 107 | cout << SymmetricMatrix(C, sizeof(C) / sizeof(C[0])) << endl; // not symmetric 108 | return 0; 109 | } -------------------------------------------------------------------------------- /39_SwitchSort.cpp: -------------------------------------------------------------------------------- 1 | // For this challenge you will determine how quickly you can sort an array based on a specific sorting technique. 2 | /* 3 | have the function SwitchSort(arr) take arr which will be an an array consisting of integers 1...size(arr) and determine what the fewest number of steps is in order to sort the array from least to greatest using the following technique: Each element E in the array can swap places with another element that is arr[E] spaces to the left or right of the chosen element. You can loop from one end of the array to the other. For example: if arr is the array [1, 3, 4, 2] then you can choose the second element which is the number 3, and if you count 3 places to the left you'll loop around the array and end up at the number 4. Then you swap these elements and arr is then [1, 4, 3, 2]. From here only one more step is required, you choose the last element which is the number 2, count 2 places to the left and you'll reach the number 4, then you swap these elements and you end up with a sorted array [1, 2, 3, 4]. Your program should return an integer that specifies the least amount of steps needed in order to sort the array using the following switch sort technique. 4 | 5 | The array arr will at most contain five elements and will contain at least two elements. 6 | */ 7 | 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | 13 | // NOT FINISHED 14 | 15 | int SwitchSort(int arr[], int size) 16 | { 17 | 18 | } 19 | 20 | int main() 21 | { 22 | int A[] = { 1, 3, 4, 2 }; 23 | int B[] = {3,1,2}; 24 | int C[] = {1,3,4,2}; 25 | 26 | cout << SwitchSort(A,sizeof(A)/sizeof(A[0])) << endl; // 2 27 | cout << SwitchSort(B, sizeof(B) / sizeof(B[0])) << endl; // 2 28 | cout << SwitchSort(C, sizeof(C) / sizeof(C[0])) << endl; // 2 29 | return 0; 30 | } -------------------------------------------------------------------------------- /3_PatternChaser.cpp: -------------------------------------------------------------------------------- 1 | // For this challenge you will be given a string and you will have to determine whether some sort of pattern exists. 2 | /* 3 | have the function PatternChaser(str) take str which will be a string and return the longest pattern within the string. A pattern for this challenge will be defined as: if at least 2 or more adjacent characters within the string repeat at least twice. So for example "aabecaa" contains the pattern aa, on the other hand "abbbaac" doesn't contain any pattern. Your program should return yes/no pattern/null. So if str were "aabejiabkfabed" the output should be yes abe. If str were "123224" the output should return no null. The string may either contain all characters (a through z only), integers, or both. But the parameter will always be a string type. The maximum length for the string being passed in will be 20 characters. If a string for example is "aa2bbbaacbbb" the pattern is "bbb" and not "aa". You must always return the longest pattern possible. 4 | */ 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | // loop and take a substring to compare 10 | // loop again from the corresponding index and compare with the original substring 11 | // Keep track of the longest pattern 12 | // Repeat the process and replace if another longer pattern has been found 13 | 14 | string PatternChaser(string str) { 15 | string pattern, pattern2, result; 16 | int count,high, index,index2; 17 | index = high = 0; 18 | 19 | // Loop to analyze any patterns within the string 20 | do 21 | { 22 | for (int x = index; x < str.length(); x++) 23 | { 24 | pattern.push_back(str[x]); // begin analyzing the string to find a pattern to compare 25 | 26 | // Once we have a pattern ex. ab 27 | // Analyze the other values of the string to check if the pattern repeats 28 | if (pattern.length() > 1) 29 | { 30 | index2 = x + 1; 31 | do 32 | { 33 | for (int y = index2; y < str.length(); y++) 34 | { 35 | pattern2.push_back(str[y]); 36 | 37 | if (pattern2 == pattern && pattern.length() > high) 38 | { 39 | high = pattern.length(); 40 | result = pattern; 41 | } 42 | else if (pattern2.length() == pattern.length()) 43 | { 44 | // reset back to analyze the other patterns and see if they match to the original 45 | pattern2.clear(); 46 | } 47 | } 48 | pattern2.clear(); 49 | index2++; 50 | } while (index2 < str.length()); 51 | } 52 | } 53 | pattern.clear(); 54 | index++; 55 | } while (index < str.length()); 56 | 57 | if (high) 58 | { 59 | return "yes " + result; 60 | } 61 | else 62 | { 63 | return "no null"; 64 | } 65 | } 66 | 67 | int main() { 68 | // keep this function call here 69 | cout << PatternChaser("da2kr32a2") << endl; // yes a2 70 | cout << PatternChaser("sskfssbbb9bbb") << endl; // yes bbb 71 | cout << PatternChaser("aabecaa") << endl; // yes aa 72 | cout << PatternChaser("abbbaac") << endl; // no null 73 | cout << PatternChaser("aabejiabkfabed") << endl; // yes abe 74 | cout << PatternChaser("123224") << endl; // no null 75 | cout << PatternChaser("aa2bbbaacbbb") << endl; // yes bbb 76 | return 0; 77 | } -------------------------------------------------------------------------------- /40_MatrixBorder.cpp: -------------------------------------------------------------------------------- 1 | // For this challenge you will be transposing rows and columns within an array. 2 | /* 3 | have the function MatrixBorder(strArr) read the strArr parameter being passed which will represent an NxN matrix filled with 1's and 0's. Your program should determine the number of swaps between two rows or two columns that must be made to change the matrix such that the border of the matrix contains all 1's and the inside contains 0's. The format of strArr will be: ["(n,n,n...)","(...)",...] where n represents either a 1 or 0. The smallest matrix will be a 3x3 and the largest will be a 6x6 matrix. 4 | 5 | For example: if strArr is: ["(0,1,1)","(1,1,1)","(1,1,1)"] then you can swap the first two columns and then swap the first two rows to create a matrix with the 1's on the border and the 0 on the inside, therefore your program should output 2. 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | using namespace std; 12 | 13 | void swapColumn(vector >&, int); 14 | void swapRow(vector >&, int); 15 | 16 | /* 17 | create a matrix based on the input string 18 | 19 | simple solution would be to analyze the border rows and columns 20 | as we traverse we check for any 0 21 | if 0 is at a column border swap with a column that has all 1s 22 | if 0 is at a row border swap with a row that all 1s 23 | 24 | keep track of the number of swaps made 25 | */ 26 | int MatrixBorder(string strArr[], int size) 27 | { 28 | vector < vector > matrix; 29 | int swapCount = 0; 30 | 31 | // traverse input to create the matrix 32 | for (int x = 0; x < size; x++) 33 | { 34 | vector temp; 35 | 36 | for (int y = 0; y < strArr[x].length(); y++) 37 | { 38 | if (strArr[x][y] == '1' || strArr[x][y] == '0') 39 | { 40 | temp.push_back(strArr[x][y]); 41 | } 42 | } 43 | 44 | // fill in the row 45 | matrix.push_back(temp); 46 | } 47 | 48 | // analyzing the matrix to assure no border has a 0 49 | for (int row = 0; row < matrix.size(); row++) 50 | { 51 | for (int col = 0; col < matrix[row].size(); col++) 52 | { 53 | // condition to check the borders only 54 | if (row == 0 || row == matrix.size() - 1 || col == 0 || col == matrix[row].size()-1) 55 | { 56 | if (matrix[row][col] == '0') 57 | { 58 | // column needs to be swapped 59 | if (col == 0 || col == matrix[row].size() - 1) 60 | { 61 | swapColumn(matrix, col); 62 | swapCount++; 63 | } 64 | // row needs to be swapped 65 | else if (row == 0 || row == matrix.size()-1) 66 | { 67 | swapRow(matrix, row); 68 | swapCount++; 69 | } 70 | } 71 | } 72 | } 73 | } 74 | 75 | return swapCount; 76 | } 77 | 78 | // method to swap 2 columns 79 | void swapColumn(vector >& matrix, int col) 80 | { 81 | // traverse to find a column that we can swap with 82 | for (int y = 0; y < matrix[0].size(); y++) 83 | { 84 | // ignore same column or border columns 85 | if (y == col || y == 0 || y == matrix[0].size()-1) 86 | { 87 | continue; 88 | } 89 | else 90 | { 91 | bool valid = true; 92 | 93 | // analyze current column to check if is valid for swapping 94 | for (int row = 0; row < matrix.size(); row++) 95 | { 96 | if (matrix[row][y] == '0') 97 | { 98 | valid = false; 99 | break; 100 | } 101 | } 102 | 103 | // preform the swap between the 2 columns 104 | if (valid) 105 | { 106 | char temp; 107 | 108 | for (int x = 0; x < matrix.size(); x++) 109 | { 110 | temp = matrix[x][col]; 111 | matrix[x][col] = matrix[x][y]; 112 | matrix[x][y] = temp; 113 | } 114 | 115 | return; 116 | } 117 | } 118 | } 119 | } 120 | 121 | // method to swap 2 rows 122 | void swapRow(vector >& matrix, int row) 123 | { 124 | // traverse to find a row that we can swap with 125 | for (int x = 0; x < matrix.size(); x++) 126 | { 127 | // ignore the same row, or any border rows 128 | if (x == row || x== 0 || x == matrix.size()-1) 129 | { 130 | continue; 131 | } 132 | else 133 | { 134 | bool valid = true; 135 | 136 | // analyze current row to check if is valid for swapping 137 | for (int col = 0; col < matrix[x].size(); col++) 138 | { 139 | if (matrix[x][col] == '0') 140 | { 141 | valid = false; 142 | break; 143 | } 144 | } 145 | 146 | // preform the swap between the 2 rows 147 | if (valid) 148 | { 149 | char temp; 150 | 151 | for (int y = 0; y < matrix.size(); y++) 152 | { 153 | temp = matrix[row][y]; 154 | matrix[row][y] = matrix[x][y]; 155 | matrix[x][y] = temp; 156 | } 157 | 158 | return; 159 | } 160 | } 161 | } 162 | } 163 | 164 | int main() 165 | { 166 | string A[] = { "(0,1,1)", "(1,1,1)", "(1,1,1)" }; 167 | string B[] = { "(0,1,0,1)", "(1,1,1,1)", "(0,1,0,1)", "(1,1,1,1)" }; 168 | 169 | cout << MatrixBorder(A, sizeof(A) / sizeof(A[0])) << endl; // 2 170 | cout << MatrixBorder(B, sizeof(B) / sizeof(B[0])) << endl; // 2 171 | return 0; 172 | } -------------------------------------------------------------------------------- /41_ArrayJumping.cpp: -------------------------------------------------------------------------------- 1 | // For this challenge you will determine how many times you can jump around within an array. 2 | /* 3 | have the function ArrayJumping(arr) take the array of numbers stored in arr and first determine the largest element in the array, and then determine whether or not you can reach that same element within the array by moving left or right continuously according to whatever integer is in the current spot. If you can reach the same spot within the array, then your program should output the least amount of jumps it took. For example: if the input is [2, 3, 5, 6, 1] you'll start at the spot where 6 is and if you jump 6 spaces to the right while looping around the array you end up at the last element where the 1 is. Then from here you jump 1 space to the left and you're back where you started, so your program should output 2. If it's impossible to end up back at the largest element in the array your program should output -1. The largest element in the array will never equal the number of elements in the array. The largest element will be unique. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | /* 13 | first locate the largest number in the array 14 | based on the target location we get the left and right index array jumps 15 | 16 | using BFS we will store the new index locations into our queue 17 | note that we keep track of our count 18 | we also ignore any indexes that have already been analyzed 19 | we continue this process until either everything has been analyzed or the target was found 20 | */ 21 | struct node 22 | { 23 | int index; 24 | int count; 25 | }; 26 | 27 | int ArrayJumping(int arr[], int size) 28 | { 29 | int target = 0; 30 | int index; 31 | 32 | // map to later check if an index has already been analyzed; 33 | map indexFound; 34 | 35 | // first locate the largest number 36 | for (int x = 0; x < size; x++) 37 | { 38 | indexFound[x] = false; 39 | 40 | if (arr[x] > target) 41 | { 42 | target = arr[x]; 43 | index = x; 44 | } 45 | } 46 | 47 | // gathering the left and right index based on the target location 48 | // also setting conditions for bound checking 49 | int leftIndex = index - target; 50 | while(leftIndex < 0) 51 | { 52 | leftIndex = size + leftIndex; 53 | } 54 | int rightIndex = index + target; 55 | while (rightIndex > size-1) 56 | { 57 | rightIndex = rightIndex - size; 58 | } 59 | 60 | // nodes to represent the left and right locations after an array jump 61 | node left; 62 | left.index = leftIndex; 63 | left.count = 1; 64 | 65 | node right; 66 | right.index = rightIndex; 67 | right.count = 1; 68 | 69 | // adding them to our queue 70 | queue list; 71 | list.push(left); 72 | list.push(right); 73 | 74 | 75 | // BFS 76 | while (!list.empty()) 77 | { 78 | // get the current index 79 | node current = list.front(); 80 | list.pop(); 81 | 82 | // check if we hit our target location 83 | if (current.index == index) 84 | { 85 | return current.count; 86 | } 87 | 88 | // update the discovery for the current index 89 | indexFound[current.index] = true; 90 | 91 | // gathering the left and right index for the current index 92 | // also setting conditions for bound checking 93 | leftIndex = current.index - arr[current.index]; 94 | while (leftIndex < 0) 95 | { 96 | leftIndex = size + leftIndex; 97 | } 98 | 99 | rightIndex = current.index + arr[current.index]; 100 | while (rightIndex > size - 1) 101 | { 102 | rightIndex = rightIndex - size; 103 | } 104 | 105 | // updating the count for both index 106 | left.index = leftIndex; 107 | left.count = current.count + 1; 108 | right.index = rightIndex; 109 | right.count = current.count + 1; 110 | 111 | // check if the new indexes have been previously analyzed 112 | if (!indexFound[left.index]) 113 | { 114 | indexFound[left.index] = true; 115 | list.push(left); 116 | } 117 | if (!indexFound[right.index]) 118 | { 119 | indexFound[right.index] = true; 120 | list.push(right); 121 | } 122 | } 123 | 124 | return -1; 125 | } 126 | 127 | int main() 128 | { 129 | int A[] = { 2, 3, 5, 6, 1 }; 130 | int B[] = { 1, 2, 3, 4, 2 }; 131 | int C[] = { 1, 7, 1, 1, 1, 1 }; 132 | int D[] = { 1, 2, 1, 2, 1, 12 }; 133 | int E[] = { 0, 5, 2 }; 134 | 135 | cout << ArrayJumping(A, sizeof(A)/sizeof(A[0])) << endl; // 2 136 | cout << ArrayJumping(B, sizeof(B) / sizeof(B[0])) << endl; // 3 137 | cout << ArrayJumping(C, sizeof(C) / sizeof(C[0])) << endl; // 2 138 | cout << ArrayJumping(D, sizeof(D) / sizeof(D[0])) << endl; // 1 139 | cout << ArrayJumping(E, sizeof(E) / sizeof(E[0])) << endl; // 2 140 | return 0; 141 | } -------------------------------------------------------------------------------- /42_PolynomialExpansion.cpp: -------------------------------------------------------------------------------- 1 | // This challenge will require knowledge of polynomial expansion. 2 | /* 3 | have the function PolynomialExpansion(str) take str which will be a string representing a polynomial containing only (+/-) integers, a letter, parenthesis, and the symbol "^", and return it in expanded form. For example: if str is "(2x^2+4)(6x^3+3)", then the output should be "12x^5+24x^3+6x^2+12". Both the input and output should contain no spaces. The input will only contain one letter, such as "x", "y", "b", etc. There will only be four parenthesis in the input and your output should contain no parenthesis. The output should be returned with the highest exponential element first down to the lowest. 4 | 5 | More generally, the form of str will be: ([+/-]{num}[{letter}[{^}[+/-]{num}]]...[[+/-]{num}]...)(copy) where "[]" represents optional features, "{}" represents mandatory features, "num" represents integers and "letter" represents letters such as "x". 6 | */ 7 | 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | // NOT FINISHED 13 | 14 | string PolynomialExpansion(string str) 15 | { 16 | 17 | } 18 | 19 | int main() 20 | { 21 | cout << PolynomialExpansion("(2x^2+4)(6x^3+3)") << endl; // 12x^5+24x^3+6x^2+12 22 | cout << PolynomialExpansion("(1x)(2x^-2+1)") << endl; // x+2x^-1 23 | cout << PolynomialExpansion("(-1x^3)(3x^3+2)") << endl; // -3x^6-2x^3 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /43_MatchingCouples.cpp: -------------------------------------------------------------------------------- 1 | // This challenge will require knowledge of basic mathematical combinations. 2 | /* 3 | have the function MatchingCouples(arr) take the arr parameter being passed which will be an array of integers in the following format: [B, G, N] where B represents the number of boys, G represents the number of girls, and N represents how many people you want to pair together. Your program should return the number of different ways you can match boys with girls given the different arguments. For example: if arr is [5, 3, 2], N=2 here so you want to pair together 2 people, so you'll need 1 boy and 1 girl. You have 5 ways to choose a boy and 3 ways to choose a girl, so your program should return 15. Another example: if arr is [10, 5, 4], here N=4 so you need 2 boys and 2 girls. We can choose 2 boys from a possible 10, and we can choose 2 girls from a possible 5. Then we have 2 different ways to pair the chosen boys and girls. Our program should therefore return 900 4 | 5 | N will always be an even number and it will never be greater than the maximum of (B, G). B and G will always be greater than zero. 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | using namespace std; 12 | 13 | /* 14 | we use a step down approach 15 | we gather the amount of possible combinations pertaining to each boy 16 | */ 17 | int MatchingCouples(int arr[]) 18 | { 19 | int pairSize = arr[2]/2; 20 | int total = 0; 21 | 22 | if (pairSize == 1) 23 | { 24 | return arr[0] * arr[1]; 25 | } 26 | else 27 | { 28 | for (int x = arr[0]; x > 0; x--) 29 | { 30 | int currentTotal = (x - 1)*((pairSize-1)*(arr[1] - 1))*arr[1]; 31 | total += currentTotal; 32 | } 33 | } 34 | 35 | return total; 36 | } 37 | 38 | int main() 39 | { 40 | int A[] = { 5, 3, 2 }; 41 | int B[] = { 10, 5, 4 }; 42 | int C[] = { 5, 5, 4 }; 43 | int D[] = { 2, 2, 2 }; 44 | int E[] = { 10, 10, 6 }; 45 | int F[] = { 15, 10, 6 }; 46 | 47 | cout << MatchingCouples(A) << endl; // 15 48 | cout << MatchingCouples(B) << endl; // 900 49 | cout << MatchingCouples(C) << endl; // 200 50 | cout << MatchingCouples(D) << endl; // 4 51 | cout << MatchingCouples(E) << endl; // 86400 52 | cout << MatchingCouples(F) << endl; // 327600 53 | 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /4_GasStation.cpp: -------------------------------------------------------------------------------- 1 | // For this challenge you will be determining whether a car can get around a route with a limited amount of gas. 2 | /* 3 | have the function GasStation(strArr) take strArr which will be an an array consisting of the following elements: N which will be the number of gas stations in a circular route and each subsequent element will be the string g:c where g is the amount of gas in gallons at that gas station and c will be the amount of gallons of gas needed to get to the following gas station. For example strArr may be: ["4","3:1","2:2","1:2","0:1"]. Your goal is to return the index of the starting gas station that will allow you to travel around the whole route once, otherwise return the string impossible. For the example above, there are 4 gas stations, and your program should return the string 1 because starting at station 1 you receive 3 gallons of gas and spend 1 getting to the next station. Then you have 2 gallons + 2 more at the next station and you spend 2 so you have 2 gallons when you get to the 3rd station. You then have 3 but you spend 2 getting to the final station, and at the final station you receive 0 gallons and you spend your final gallon getting to your starting point. Starting at any other gas station would make getting around the route impossible, so the answer is 1. If there are multiple gas stations that are possible to start at, return the smallest index (of the gas station). N will be >= 2. 4 | */ 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | // loop through string to compare g and c 11 | // check for stations that provide surplus of gallons or even amount 12 | // calculate the difference in gallons left over and move to the next station 13 | // analyze if is possible to travel the whole route 14 | 15 | // Helper function to convert both the g and c values from the string 16 | void expenses(string arr[], int index, int pos, int& gallon, int& travel) 17 | { 18 | string num; 19 | // Loop to find the amount of gallons at a station 20 | for (int x = 0; x < pos; x++) 21 | { 22 | num += arr[index][x]; 23 | } 24 | istringstream(num) >> gallon; 25 | num.clear(); 26 | // Loop to find amount of gas needed 27 | for (int y = pos+1; y < arr[index].length(); y++) 28 | { 29 | num += arr[index][y]; 30 | } 31 | istringstream(num) >> travel; 32 | num.clear(); 33 | } 34 | 35 | string GasStation(string strArr[], int size) { 36 | int gallon, travel, station,total, result; 37 | bool route; 38 | station = size*2; 39 | result = -1; 40 | total = 0; 41 | 42 | // Loop through the gas stations 43 | for (int x = 1; x < size; x++) 44 | { 45 | int pos = strArr[x].find(':'); // index to help locate g:c 46 | expenses(strArr, x, pos, gallon, travel); 47 | 48 | // Condition for when having a surplus or even amount of gallons to travel ratio 49 | if (gallon >= travel) 50 | { 51 | total = gallon - travel; // get the amount of gallons left 52 | 53 | // loop again through the stations back to the starting route/station from which we started 54 | int y = x + 1; 55 | do 56 | { 57 | route = true; 58 | 59 | for (y; y < size; y++) 60 | { 61 | // ignore the station that we started from 62 | // Also signal when there is not enough gallons to move to the next station 63 | if (y == x || total < 0) 64 | { 65 | route = false; 66 | break; 67 | } 68 | 69 | pos = strArr[y].find(':'); 70 | expenses(strArr, y, pos, gallon, travel); 71 | total += gallon; 72 | total -= travel; 73 | } 74 | 75 | y = 1; // reset back in the case that our starting station is not at the beginning 76 | } while (route); 77 | 78 | if (total >= 0 && x < station) // Keeping track of the smallest index in case of multiple stations 79 | { 80 | result = total; 81 | station = x; 82 | } 83 | } 84 | } 85 | 86 | // Condition to analyze if it was possible to travel the whole route 87 | if (result < 0) 88 | { 89 | return "impossible"; 90 | } 91 | else 92 | { 93 | stringstream convert; 94 | convert << station; 95 | return convert.str(); 96 | } 97 | } 98 | 99 | int main() { 100 | // keep this function call here 101 | /* Note: In C++ you first have to initialize an array and set 102 | it equal to the stdin to test your code with arrays. */ 103 | string A[] = { "4", "1:1", "2:2", "1:2", "0:1" }; 104 | string B[] = { "4", "0:1", "2:2", "1:2", "3:1" }; 105 | string C[] = { "4", "3:1", "2:2", "1:2", "0:1" }; 106 | string D[] = { "3", "2:3", "2:1", "4:4"}; 107 | string E[] = { "5", "3:3", "1:2", "2:2", "3:2", "4:3" }; 108 | string F[] = { "5", "0:1", "2:1", "3:2", "4:6", "4:3" }; 109 | string G[] = { "2", "1:2", "1:2" }; 110 | string H[] = { "6", "3:2", "2:2", "10:6", "0:4", "1:1", "30:10" }; 111 | string I[] = { "5", "2:3", "2:3", "2:3", "500:1", "0:495" }; 112 | cout << GasStation(A, sizeof(A) / sizeof(A[0])) << endl; // impossible 113 | cout << GasStation(B, sizeof(B) / sizeof(B[0])) << endl; // 4 114 | cout << GasStation(C, sizeof(C) / sizeof(C[0])) << endl; // 1 115 | cout << GasStation(D, sizeof(D) / sizeof(D[0])) << endl; // 2 116 | cout << GasStation(E, sizeof(E) / sizeof(E[0])) << endl; // 3 117 | cout << GasStation(F, sizeof(F) / sizeof(F[0])) << endl; // 2 118 | cout << GasStation(G, sizeof(G) / sizeof(G[0])) << endl; // impossible 119 | cout << GasStation(H, sizeof(H) / sizeof(H[0])) << endl; // 1 120 | cout << GasStation(I, sizeof(I) / sizeof(I[0])) << endl; // 4 121 | return 0; 122 | } -------------------------------------------------------------------------------- /5_ReversePolishNotation.cpp: -------------------------------------------------------------------------------- 1 | // This challenge will require knowledge of postfix notation for arithmetic expressions. 2 | /* 3 | have the function ReversePolishNotation(str) read str which will be an arithmetic expression composed of only integers and the operators: +,-,* and / and the input expression will be in postfix notation (Reverse Polish notation), an example: 4 | (1 + 2) * 3 would be 1 2 + 3 * in postfix notation. Your program should determine the answer for the given postfix expression. For example: if str is 2 12 + 7 / then your program should output 2. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | using namespace std; 12 | 13 | 14 | /* 15 | we will utilize a stack ADT 16 | as we traverse the string we store any operands we encounter 17 | when we reach an operator, we pop the last 2 operands from our stack 18 | we evaluate the 2 values and push the result back into the stack 19 | */ 20 | int ReversePolishNotation(string str) 21 | { 22 | stack list; 23 | string num = ""; 24 | 25 | for (int x = 0; x < str.length(); x++) 26 | { 27 | 28 | // condition to check if current character represents a number 29 | if (str[x] >= '0' && str[x] <= '9') 30 | { 31 | num.push_back(str[x]); 32 | } 33 | else if (str[x] == '+' || str[x] == '-' || str[x] == '*' || str[x] == '/') 34 | { 35 | // We retrieve the last 2 values added to the list for evaluation 36 | int value1 = list.top(); 37 | list.pop(); 38 | 39 | int value2 = list.top(); 40 | list.pop(); 41 | 42 | // Here we evaluate based on the operation 43 | // After we add the result to the stack 44 | int result; 45 | switch (str[x]) 46 | { 47 | case '+': 48 | result = value1 + value2; 49 | break; 50 | 51 | case '-': 52 | result = value2 - value1; 53 | break; 54 | 55 | case '*': 56 | result = value1* value2; 57 | break; 58 | 59 | case '/': 60 | result = value2 / value1; 61 | break; 62 | } 63 | 64 | list.push(result); 65 | } 66 | else 67 | { 68 | // condition to convert our string number to a valid integer 69 | // will also add it to the stack 70 | 71 | if (num.length() >= 1) 72 | { 73 | int value; 74 | 75 | istringstream(num) >> value; 76 | list.push(value); 77 | 78 | num = ""; 79 | } 80 | 81 | } 82 | } 83 | 84 | return list.top(); 85 | } 86 | 87 | int main() 88 | { 89 | cout << ReversePolishNotation("2 12 + 7 /") << endl; // 2 90 | cout << ReversePolishNotation("1 1 + 1 + 1 +") << endl; // 4 91 | cout << ReversePolishNotation("4 5 + 2 1 + *") << endl; // 27 92 | cout << ReversePolishNotation("6 2 * 5 2 * * 4 2 * * 1 5 + +") << endl; // 966 93 | 94 | return 0; 95 | } -------------------------------------------------------------------------------- /6_MaximalRectangle.cpp: -------------------------------------------------------------------------------- 1 | // For this challenge you will be searching a matrix for the largest rectangle submatrix. 2 | /* 3 | have the function MaximalRectangle(strArr) take the strArr parameter being passed which will be a 2D matrix of 0 and 1's, and determine the area of the largest rectangular submatrix that contains all 1's. For example: if strArr is ["10100", "10111", "11111", "10010"] then this looks like the following matrix: 4 | 5 | For the input above, you can see the bolded 1's create the largest rectangular submatrix of size 2x3, so your program should return the area which is 6. You can assume the input will not be empty. 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | using namespace std; 12 | 13 | int getArea(string[], int, int, int); 14 | bool checkArea(string[], int, int, int, int); 15 | 16 | /* 17 | One approach is to step through each point 18 | 19 | for each point we expand its width and height 20 | we can then check if the possible rectangle is valid 21 | meaning it must be filled with all 1s 22 | 23 | if valid we determine the area and update our highest value 24 | */ 25 | int MaximalRectangle(string strArr[], int size) 26 | { 27 | int total = 1; 28 | 29 | // traverse for valid points to analyze 30 | for (int row = 0; row < size; row++) 31 | { 32 | for (int col = 0; col < strArr[row].length(); col++) 33 | { 34 | // condition to get a starting point to analyze from 35 | if (strArr[row][col] == '1') 36 | { 37 | int area = getArea(strArr, size, row, col); 38 | 39 | // update value 40 | if (area > total) 41 | { 42 | total = area; 43 | } 44 | } 45 | } 46 | } 47 | 48 | return total; 49 | } 50 | 51 | // get area method 52 | // will analyze current point and find a rectangle by expanding out 53 | int getArea(string arr[], int size, int row, int col) 54 | { 55 | int tempRow = row; 56 | int tempCol = col; 57 | 58 | int width = 1; 59 | int height = 1; 60 | bool widthExpansion; 61 | bool heightExpansion; 62 | 63 | while (tempRow + 1 < size || tempCol + 1 < arr[0].length()) 64 | { 65 | // flags to help determine if either both the width and height were valid in expanding 66 | widthExpansion = false; 67 | heightExpansion = false; 68 | 69 | // expand the width or height 70 | if (tempRow + 1 < size && arr[tempRow + 1][col] == '1') 71 | { 72 | tempRow++; 73 | heightExpansion = true; 74 | } 75 | 76 | if (tempCol + 1 < arr[0].length() && arr[row][tempCol + 1] == '1') 77 | { 78 | tempCol++; 79 | widthExpansion = true; 80 | } 81 | 82 | // check if current expansion is a valid rectangle for both the width and height 83 | if (widthExpansion && heightExpansion && checkArea(arr, row, col, tempRow, tempCol)) 84 | { 85 | width++; 86 | height++; 87 | } 88 | else if (widthExpansion && checkArea(arr, row, col, tempRow, tempCol)) // valid width expansion 89 | { 90 | width++; 91 | } 92 | else if (heightExpansion && checkArea(arr, row, col, tempRow, tempCol)) // valid height expansion 93 | { 94 | height++; 95 | } 96 | else 97 | { 98 | return width * height; 99 | } 100 | } 101 | 102 | return width * height; 103 | } 104 | 105 | // method to check if points provided form a full rectangle 106 | bool checkArea(string arr[], int row, int col, int rowLimit, int colLimit) 107 | { 108 | for (row; row <= rowLimit; row++) 109 | { 110 | for (int y = col; y <= colLimit; y++) 111 | { 112 | if (arr[row][y] != '1') 113 | { 114 | return false; 115 | } 116 | } 117 | } 118 | 119 | return true; 120 | } 121 | 122 | int main() 123 | { 124 | string A[] = { "10100", "10111", "11111", "10010" }; 125 | string B[] = { "1011", "0011", "0111", "1111" }; 126 | string C[] = { "101", "111", "001" }; 127 | 128 | cout << MaximalRectangle(A, sizeof(A) / sizeof(A[0])) << endl; // 6 129 | cout << MaximalRectangle(B, sizeof(B) / sizeof(B[0])) << endl; // 8 130 | cout << MaximalRectangle(C, sizeof(C) / sizeof(C[0])) << endl; // 3 131 | return 0; 132 | 133 | } -------------------------------------------------------------------------------- /7_LCS.cpp: -------------------------------------------------------------------------------- 1 | // For this challenge you will be determining the longest common subsequence of two strings. 2 | /* 3 | have the function LCS(strArr) take the strArr parameter being passed which will be an array of two strings containing only the characters {a,b,c} and have your program return the length of the longest common subsequence common to both strings. A common subsequence for two strings does not require each character to occupy consecutive positions within the original strings. For example: if strArr is ["abcabb","bacb"] then your program should return 3 because one longest common subsequence for these two strings is "bab" and there are also other 3-length subsequences such as "acb" and "bcb" but 3 is the longest common subsequence for these two strings. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | using namespace std; 10 | 11 | /* 12 | An efficient approach will be to use DP 13 | 14 | the technique will be straight forward we first set up our table 15 | This will store solutions to subproblems we solve and allow us to reuse those solutions to solve current problems 16 | 17 | We will set our base case 18 | than traverse one of the strings and compare it to the other 19 | the condition we set will check for the optimal solution 20 | for instance if current characters do not match, than select what the most optimal solution is when shift the indexes of either sequence 21 | 22 | unlike the brute force approach or recursive approach the DP technique will allow us to avoid having to do more work, since we are storing solutions. In the case when the characters are not equal, instead of solving what happens if we only shift the index in sequence A, we can just take the max from our previously solved problems. 23 | */ 24 | int LCS(string strArr[]) 25 | { 26 | // setting our table 27 | int size1 = strArr[0].length(); 28 | int size2 = strArr[1].length(); 29 | 30 | // note we add an extra row and column to store the base cases 31 | int** table = new int*[size1+1]; 32 | for (int x = 0; x < size1+1; x++) 33 | { 34 | table[x] = new int[size2+2]; 35 | } 36 | 37 | // initializing our table with default base cases 38 | // here if we don't have a sequence to compare than our result will be zero 39 | for (int row = 0; row <= size1; row++) 40 | { 41 | table[row][0] = 0; 42 | } 43 | for (int col = 0; col <= size2; col++) 44 | { 45 | table[0][col] = 0; 46 | } 47 | 48 | // loop to traverse the string and tackle each subproblems 49 | /* 50 | to visualize it, we first tackle what is the LCS when the size of sequence A is only 1 51 | than our next subproblem is what is the LCS when size of sequence A is only 2 and so forth 52 | by the time we get the last character we can utilize the previously solved problems stored in our table to determine the final solution 53 | */ 54 | for (int row = 1; row <= size1; row++) 55 | { 56 | for (int col = 1; col <= size2; col++) 57 | { 58 | // condition to check if current characters are equal, if so than increment the count 59 | // we take the previous optimal solution and add 1 to it 60 | if (strArr[0][row - 1] == strArr[1][col - 1]) 61 | { 62 | table[row][col] = table[row - 1][col - 1] + 1; 63 | } 64 | else 65 | { 66 | // else here we take what is the most optimal if we either shift the index in sequence A or sequence B 67 | table[row][col] = max(table[row - 1][col], table[row][col - 1]); 68 | } 69 | } 70 | } 71 | 72 | // the last element in our 2D table represents the optimal solution 73 | return table[size1][size2]; 74 | } 75 | 76 | int main() 77 | { 78 | string A[] = { "abcabb", "bacb" }; 79 | string B[] = { "abc", "cb" }; 80 | string C[] = { "bcacb", "aacabb" }; 81 | 82 | cout << LCS(A) << endl; // 3 83 | cout << LCS(B) << endl; // 1 84 | cout << LCS(C) << endl; // 3 85 | 86 | return 0; 87 | } -------------------------------------------------------------------------------- /8_ParallelSums.cpp: -------------------------------------------------------------------------------- 1 | // For this challenge you will determine how to properly split an array into two sets. 2 | /* 3 | have the function ParallelSums(arr) take the array of integers stored in arr which will always contain an even amount of integers, and determine how they can be split into two even sets of integers each so that both sets add up to the same number. If this is impossible return -1. If it's possible to split the array into two sets, then return a string representation of the first set followed by the second set with each integer separated by a comma and both sets sorted in ascending order. The set that goes first is the set with the smallest first integer. 4 | 5 | For example: if arr is [16, 22, 35, 8, 20, 1, 21, 11], then your program should output 1,11,20,35,8,16,21,22 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | using namespace std; 15 | 16 | 17 | // NOT FINISHED 18 | 19 | 20 | /* 21 | first add up all the values of the input array 22 | we divide by 2 to check if is possible to split into 2 sets 23 | 24 | If possible to get 2 sets we sort our values in increasing order 25 | Our selection for the sets will be, select the lowest and highest value and add it to one of the sets 26 | we update our indexes and now select the current lowest and highest values and add it to the other set 27 | We repeat this step until all values have been copied to our sets. 28 | */ 29 | string ParallelSums(int arr[], int size) 30 | { 31 | // calculate total sum 32 | int sum = 0; 33 | int setSum; 34 | for (int x = 0; x < size; x++) 35 | { 36 | sum += arr[x]; 37 | } 38 | 39 | // check if input values can be split into 2 even sets 40 | if (sum % 2 != 0) 41 | { 42 | return "-1"; 43 | } 44 | else 45 | { 46 | setSum = sum / 2; 47 | } 48 | 49 | // making a copy of our input array to a vector for ease of use 50 | // we will also sort the values in ascending order to apply our greedy approach 51 | vector values(arr,arr + size); 52 | sort(values.begin(), values.end()); 53 | 54 | // indexes used for our selection we will also be collecting the sum for both sets 55 | int low = 0; 56 | int high = size - 1; 57 | bool front = true; // flag signal to determine if we are getting the current lowest or highest 58 | 59 | // our sets 60 | vector set1; 61 | vector set2; 62 | 63 | // loop to perform our greedy selection 64 | while (low < high) 65 | { 66 | // special condition when only 2 choices are left 67 | // will decide which value to apply to a set 68 | if (low + 1 == high) 69 | { 70 | int currentSum = accumulate(set1.begin(), set1.end(), 0); 71 | int difference = setSum - currentSum; 72 | 73 | if (difference == values[low]) 74 | { 75 | set1.push_back(values[low++]); 76 | set2.push_back(values[high--]); 77 | } 78 | else 79 | { 80 | set1.push_back(values[high--]); 81 | set2.push_back(values[low++]); 82 | } 83 | } 84 | else if (front) 85 | { 86 | // adding the lowest values from the input 87 | set1.push_back(values[low++]); 88 | set2.push_back(values[low++]); 89 | 90 | // update our flag signal 91 | front = false; 92 | } 93 | else 94 | { 95 | set1.push_back(values[high--]); 96 | set2.push_back(values[high--]); 97 | front = true; 98 | } 99 | } 100 | 101 | string result = ""; 102 | 103 | // sorting both sets 104 | sort(set1.begin(), set1.end()); 105 | sort(set2.begin(), set2.end()); 106 | 107 | // storing both sets into a string 108 | for (auto current : set1) 109 | { 110 | result += to_string(current); 111 | result += ','; 112 | } 113 | for (auto current : set2) 114 | { 115 | result += to_string(current); 116 | result += ','; 117 | } 118 | result.pop_back(); 119 | 120 | return result; 121 | } 122 | 123 | 124 | int main() 125 | { 126 | int A[] = { 16, 22, 35, 8, 20, 1, 21, 11 }; 127 | int B[] = { 1, 2, 3, 4 }; 128 | int C[] = { 1, 2, 1, 5 }; 129 | int D[] = { 9, 1, 0, 5, 3, 2 }; 130 | int E[] = { 2, 3, 1, 9, 3, 4, 4, 4 }; 131 | int F[] = { 6, 2, 4, 1, 10, 25, 5, 3, 40, 4 }; 132 | 133 | cout << ParallelSums(A, sizeof(A)/sizeof(A[0])) << endl; // 1,11,20,35,8,16,21,22 134 | cout << ParallelSums(B, sizeof(B) / sizeof(B[0])) << endl; // 1,4,2,3 135 | cout << ParallelSums(C, sizeof(C) / sizeof(C[0])) << endl; // -1 136 | cout << ParallelSums(D, sizeof(D) / sizeof(D[0])) << endl; // 0,1,9,2,3,5 137 | cout << ParallelSums(E, sizeof(E) / sizeof(E[0])) << endl; // 1,2,3,9,3,4,4,4 138 | cout << ParallelSums(F, sizeof(F) / sizeof(F[0])) << endl; // 1,2,3,4,40,4,5,6,10,25 139 | 140 | return 0; 141 | } -------------------------------------------------------------------------------- /9_ShortestPath.cpp: -------------------------------------------------------------------------------- 1 | // For this challenge you will have to determine the shortest path from one node to an end node. 2 | 3 | /* 4 | have the function ShortestPath(strArr) take strArr which will be an array of strings which models a non-looping Graph. The structure of the array will be as follows: The first element in the array will be the number of nodes N (points) in the array as a string. The next N elements will be the nodes which can be anything (A, B, C .. Brick Street, Main Street .. etc.). Then after the Nth element, the rest of the elements in the array will be the connections between all of the nodes. They will look like this: (A-B, B-C .. Brick Street-Main Street .. etc.). Although, there may exist no connections at all. 5 | 6 | An example of strArr may be: ["4","A","B","C","D","A-B","B-D","B-C","C-D"]. Your program should return the shortest path from the first Node to the last Node in the array separated by dashes. So in the example above the output should be A-B-D. Here is another example with strArr being ["7","A","B","C","D","E","F","G","A-B","A-E","B-C","C-D","D-F","E-D","F-G"]. The output for this array should be A-E-D-F-G. There will only ever be one shortest path for the array. If no path between the first and last node exists, return -1. The array will at minimum have two nodes. Also, the connection A-B for example, means that A can get to B and B can get to A. 7 | */ 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | using namespace std; 17 | 18 | // hash table to quickly access the nodes 19 | map nodeIndex; 20 | 21 | const string unknown = "unknown"; 22 | 23 | /* 24 | First we need to represent the input as a graph 25 | the graph will be represented as an adjacency list 26 | set up as a 2d vector storing structures that represent the nodes 27 | 28 | the nodes will store a distance cost also a parent node 29 | the parents will be used to determine in the end the path we took 30 | */ 31 | struct vertex 32 | { 33 | string name; 34 | int cost; 35 | string parent; 36 | bool visited; 37 | }; 38 | 39 | // method to set up the vertices for our graph 40 | void createNodes(vector < vector >& graph, vector nodes) 41 | { 42 | // resetting the hash table for each call before we add values to it 43 | nodeIndex.clear(); 44 | 45 | for (int x = 0; x < nodes.size(); x++) 46 | { 47 | // adding key value pair to our table 48 | nodeIndex.insert(make_pair(nodes[x], x)); 49 | 50 | // creating the vertices for our graph 51 | graph[x].push_back(new vertex); 52 | 53 | // initializing values to default 54 | graph[x][0]->cost = 100*100; // basically all are set to infinity/large value since we don't know distance yet 55 | graph[x][0]->name = nodes[x]; 56 | graph[x][0]->parent = unknown; 57 | graph[x][0]->visited = false; 58 | } 59 | } 60 | 61 | // method to make the edge connection in our graph 62 | void makePair(vector < vector >& graph, string pair) 63 | { 64 | // getting the nodes we are connecting 65 | string source, partner; 66 | int breakpoint = pair.find('-'); 67 | source = pair.substr(0, breakpoint); 68 | partner = pair.substr(breakpoint + 1); 69 | 70 | /* 71 | make the undirected connection 72 | we utilized a hash to quickly target the list of the nodes we are working with 73 | since this is a bi-directional connection,if the first node connects to the third node 74 | then the third node must also connect to the first node 75 | */ 76 | graph[nodeIndex[source]].push_back(graph[nodeIndex[partner]][0]); 77 | graph[nodeIndex[partner]].push_back(graph[nodeIndex[source]][0]); 78 | } 79 | 80 | string ShortestPath(string strArr[], int size) 81 | { 82 | string source, destination; 83 | 84 | // total number of nodes in our graph 85 | int totalNodes; 86 | istringstream value(strArr[0]); 87 | value >> totalNodes; 88 | 89 | // getting the name of each node 90 | vector nodes; 91 | for (int x = 1; x <= totalNodes; x++) 92 | { 93 | // condition to get the names of our starting node and our destination 94 | if (x == 1) 95 | { 96 | source = strArr[x]; 97 | } 98 | else if (x == totalNodes) 99 | { 100 | destination = strArr[x]; 101 | } 102 | 103 | nodes.push_back(strArr[x]); 104 | } 105 | 106 | // setting up our nodes in the graph 107 | vector < vector > graph(totalNodes); 108 | createNodes(graph, nodes); 109 | 110 | // making the edge connection based on the pair inputs 111 | for (int x = totalNodes + 1; x < size; x++) 112 | { 113 | string currentPair = strArr[x]; 114 | 115 | makePair(graph, currentPair); 116 | } 117 | 118 | /* 119 | Now we will perform a BFS to our graph 120 | when we find an optimal path to our neighboring node we need to update their cost and their parent 121 | we will utilize a queue and to commence we add our source node 122 | we check the neighbors and update their stats, we will continue the BFS until the queue is empty meaning all possible connections have been checked 123 | In the end if the parent of the destination node is unknown than we can conclude that no path was found from the source 124 | else if a parent is located we can backtrack from the destination and collect the parent nodes which showcases the shortest path we took 125 | */ 126 | queue < vector < vertex* > > list; 127 | // starting node will have a cost of 0 128 | graph[0][0]->cost = 0; 129 | list.push(graph[0]); 130 | 131 | // BFS 132 | while (!list.empty()) 133 | { 134 | vector current = list.front(); 135 | current[0]->visited = true; // update the current node 136 | list.pop(); 137 | 138 | // now we check all of it's unvisited neighbors and update their stats 139 | for (int x = 1; x < current.size(); x++) 140 | { 141 | if (!current[x]->visited) 142 | { 143 | /* 144 | here we check for optimal paths 145 | if the neighbors can be reached sooner from this current node than update the cost of our neighbor 146 | also update their parent 147 | */ 148 | if (current[0]->cost + 1 < current[x]->cost) 149 | { 150 | current[x]->cost = current[0]->cost + 1; 151 | current[x]->parent = current[0]->name; 152 | } 153 | 154 | // adding the valid neighbors to the queue 155 | list.push(graph[nodeIndex[current[x]->name]]); 156 | } 157 | } 158 | } 159 | 160 | // condition to check if a path was found 161 | if (graph[nodeIndex[destination]][0]->parent == unknown) 162 | { 163 | return "-1"; 164 | } 165 | else 166 | { 167 | stack result; 168 | 169 | vertex* current = graph[nodeIndex[destination]][0]; 170 | result.push(current->name); // initially add the destination to our result 171 | 172 | // tracing back 173 | while (current->parent != unknown) 174 | { 175 | // adding parent of current node to our path 176 | string parent = current->parent; 177 | result.push("-"); 178 | result.push(parent); 179 | 180 | // updating our current node 181 | current = graph[nodeIndex[parent]][0]; 182 | } 183 | 184 | // getting the elements from our stack to showcase the result 185 | string output = ""; 186 | 187 | while (!result.empty()) 188 | { 189 | output+=result.top(); 190 | result.pop(); 191 | } 192 | 193 | return output; 194 | } 195 | } 196 | 197 | int main() 198 | { 199 | string A[] = { "4", "A", "B", "C", "D", "A-B", "B-D", "B-C", "C-D" }; 200 | string B[] = { "7", "A", "B", "C", "D", "E", "F", "G", "A-B", "A-E", "B-C", "C-D", "D-F", "E-D", "F-G" }; 201 | string C[] = { "5", "A", "B", "C", "D", "F", "A-B", "A-C", "B-C", "C-D", "D-F" }; 202 | string D[] = { "4", "X", "Y", "Z", "W", "X-Y", "Y-Z", "X-W" }; 203 | string E[] = { "7", "C", "B", "A", "D", "E", "G", "F", "A-B", "B-E", "E-G", "C-D", "D-B", "D-E", "E-F" }; 204 | string F[] = { "9", "Z", "B", "C", "D", "R", "A", "Y", "Q", "E", "A-Z", "A-R", "Z-Y", "Z-C", "C-B", "Y-Q", "Q-D", "D-E", "R-E" }; 205 | string G[] = { "5", "N1", "N2", "N3", "N4", "N5", "N1-N3", "N3-N4", "N4-N5", "N5-N2", "N2-N1" }; 206 | 207 | cout << ShortestPath(A, sizeof (A)/sizeof(A[0])) << endl; // A-B-D 208 | cout << ShortestPath(B, sizeof(B) / sizeof(B[0])) << endl; // A-E-D-F-G 209 | cout << ShortestPath(C, sizeof(C) / sizeof(C[0])) << endl; // A-C-D-F 210 | cout << ShortestPath(D, sizeof(D) / sizeof(D[0])) << endl; // X-W 211 | cout << ShortestPath(E, sizeof(E) / sizeof(E[0])) << endl; // C-D-E-F 212 | cout << ShortestPath(F, sizeof(F) / sizeof(F[0])) << endl; // Z-A-R-E 213 | cout << ShortestPath(G, sizeof(G) / sizeof(G[0])) << endl; // N1-N2-N5 214 | 215 | return 0; 216 | } -------------------------------------------------------------------------------- /Debug/32_MatrixDeterminant.obj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gutty333/Hard-Programming-Challenges/f63f6d97fab7fe48b41bbe1671035d82d3f953ba/Debug/32_MatrixDeterminant.obj -------------------------------------------------------------------------------- /Debug/Fun Practice 3.Build.CppClean.log: -------------------------------------------------------------------------------- 1 | c:\users\gutty333\documents\visual studio 2013\projects\fun practice 3\fun practice 3\debug\vc120.pdb 2 | c:\users\gutty333\documents\visual studio 2013\projects\fun practice 3\fun practice 3\debug\vc120.idb 3 | c:\users\gutty333\documents\visual studio 2013\projects\fun practice 3\fun practice 3\debug\32_matrixdeterminant.obj 4 | c:\users\gutty333\documents\visual studio 2013\projects\fun practice 3\fun practice 3\debug\15_kaprekarsconstant.obj 5 | c:\users\gutty333\documents\visual studio 2013\projects\fun practice 3\fun practice 3\debug\17_optimalassignment.obj 6 | c:\users\gutty333\documents\visual studio 2013\projects\fun practice 3\fun practice 3\debug\19_chessboardtraveling.obj 7 | c:\users\gutty333\documents\visual studio 2013\projects\fun practice 3\fun practice 3\debug\20_knightjumps.obj 8 | c:\users\gutty333\documents\visual studio 2013\projects\fun practice 3\fun practice 3\debug\22_queencheck.obj 9 | c:\users\gutty333\documents\visual studio 2013\projects\fun practice 3\fun practice 3\debug\23_quickknight.obj 10 | c:\users\gutty333\documents\visual studio 2013\projects\fun practice 3\fun practice 3\debug\25_pentagonalnumber.obj 11 | c:\users\gutty333\documents\visual studio 2013\projects\fun practice 3\fun practice 3\debug\26_maximalsquare.obj 12 | c:\users\gutty333\documents\visual studio 2013\projects\fun practice 3\fun practice 3\debug\27_wildcardcharacters.obj 13 | c:\users\gutty333\documents\visual studio 2013\projects\fun practice 3\fun practice 3\debug\29_arrayrotation.obj 14 | c:\users\gutty333\documents\visual studio 2013\projects\fun practice 3\fun practice 3\debug\30_arraycouples.obj 15 | c:\users\gutty333\documents\visual studio 2013\projects\fun practice 3\fun practice 3\debug\31_simplesat.obj 16 | c:\users\gutty333\documents\visual studio 2013\projects\fun practice 3\fun practice 3\debug\33_countinganagrams.obj 17 | c:\users\gutty333\documents\visual studio 2013\projects\fun practice 3\fun practice 3\debug\34_bipartitematching.obj 18 | c:\users\gutty333\documents\visual studio 2013\projects\fun practice 3\fun practice 3\debug\35_noughtsdeterminer.obj 19 | c:\users\gutty333\documents\visual studio 2013\projects\fun practice 3\fun practice 3\debug\36_squarefigures.obj 20 | c:\users\gutty333\documents\visual studio 2013\projects\fun practice 3\fun practice 3\debug\37_alphabetrunencryption.obj 21 | c:\users\gutty333\documents\visual studio 2013\projects\fun practice 3\fun practice 3\debug\38_symmetricmatrix.obj 22 | c:\users\gutty333\documents\visual studio 2013\projects\fun practice 3\fun practice 3\debug\source.obj 23 | c:\users\gutty333\documents\visual studio 2013\projects\fun practice 3\fun practice 3\debug\source1.obj 24 | c:\users\gutty333\documents\visual studio 2013\projects\fun practice 3\fun practice 3\debug\fun practice 3.ilk 25 | c:\users\gutty333\documents\visual studio 2013\projects\fun practice 3\fun practice 3\debug\vc140.idb 26 | c:\users\gutty333\documents\visual studio 2013\projects\fun practice 3\fun practice 3\debug\fun practice 3.pdb 27 | c:\users\gutty333\documents\visual studio 2013\projects\fun practice 3\fun practice 3\debug\vc140.pdb 28 | c:\users\gutty333\documents\visual studio 2013\projects\fun practice 3\debug\fun practice 3.pdb 29 | c:\users\gutty333\documents\visual studio 2013\projects\fun practice 3\fun practice 3\debug\fun practice 3.tlog\cl.command.1.tlog 30 | c:\users\gutty333\documents\visual studio 2013\projects\fun practice 3\fun practice 3\debug\fun practice 3.tlog\cl.read.1.tlog 31 | c:\users\gutty333\documents\visual studio 2013\projects\fun practice 3\fun practice 3\debug\fun practice 3.tlog\cl.write.1.tlog 32 | c:\users\gutty333\documents\visual studio 2013\projects\fun practice 3\fun practice 3\debug\fun practice 3.tlog\link.command.1.tlog 33 | c:\users\gutty333\documents\visual studio 2013\projects\fun practice 3\fun practice 3\debug\fun practice 3.tlog\link.read.1.tlog 34 | c:\users\gutty333\documents\visual studio 2013\projects\fun practice 3\fun practice 3\debug\fun practice 3.tlog\link.write.1.tlog 35 | -------------------------------------------------------------------------------- /Debug/Fun Practice 3.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gutty333/Hard-Programming-Challenges/f63f6d97fab7fe48b41bbe1671035d82d3f953ba/Debug/Fun Practice 3.exe -------------------------------------------------------------------------------- /Debug/Fun Practice 3.log: -------------------------------------------------------------------------------- 1 | Build started 5/29/2018 2:40:01 PM. 2 | 1>Project "C:\Users\gutty333\Documents\Visual Studio 2013\Projects\Fun Practice 3\Fun Practice 3\Fun Practice 3.vcxproj" on node 2 (Build target(s)). 3 | 1>ClCompile: 4 | C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\CL.exe /c /ZI /nologo /W3 /WX- /sdl /Od /Oy- /D WIN32 /D _DEBUG /D _CONSOLE /D _LIB /D _UNICODE /D UNICODE /Gm /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Fo"Debug\\" /Fd"Debug\vc120.pdb" /Gd /TP /analyze- /errorReport:prompt test.cpp 5 | test.cpp 6 | 1>c:\users\gutty333\documents\visual studio 2013\projects\fun practice 3\fun practice 3\test.cpp(31): warning C4018: '<' : signed/unsigned mismatch 7 | Link: 8 | C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\link.exe /ERRORREPORT:PROMPT /OUT:"C:\Users\gutty333\Documents\Visual Studio 2013\Projects\Fun Practice 3\Debug\Fun Practice 3.exe" /INCREMENTAL /NOLOGO kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /MANIFEST /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /manifest:embed /DEBUG /PDB:"C:\Users\gutty333\Documents\Visual Studio 2013\Projects\Fun Practice 3\Debug\Fun Practice 3.pdb" /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:"C:\Users\gutty333\Documents\Visual Studio 2013\Projects\Fun Practice 3\Debug\Fun Practice 3.lib" /MACHINE:X86 Debug\test.obj 9 | Fun Practice 3.vcxproj -> C:\Users\gutty333\Documents\Visual Studio 2013\Projects\Fun Practice 3\Debug\Fun Practice 3.exe 10 | 1>Done Building Project "C:\Users\gutty333\Documents\Visual Studio 2013\Projects\Fun Practice 3\Fun Practice 3\Fun Practice 3.vcxproj" (Build target(s)). 11 | 12 | Build succeeded. 13 | 14 | Time Elapsed 00:00:01.85 15 | -------------------------------------------------------------------------------- /Debug/Fun Practice 3.tlog/CL.read.1.tlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gutty333/Hard-Programming-Challenges/f63f6d97fab7fe48b41bbe1671035d82d3f953ba/Debug/Fun Practice 3.tlog/CL.read.1.tlog -------------------------------------------------------------------------------- /Debug/Fun Practice 3.tlog/CL.write.1.tlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gutty333/Hard-Programming-Challenges/f63f6d97fab7fe48b41bbe1671035d82d3f953ba/Debug/Fun Practice 3.tlog/CL.write.1.tlog -------------------------------------------------------------------------------- /Debug/Fun Practice 3.tlog/Fun Practice 3.lastbuildstate: -------------------------------------------------------------------------------- 1 | #TargetFrameworkVersion=v4.0:PlatformToolSet=v120:EnableManagedIncrementalBuild=false:VCToolArchitecture=Native32Bit 2 | Debug|Win32|C:\Users\gutty333\Documents\Visual Studio 2013\Projects\Fun Practice 3\| 3 | -------------------------------------------------------------------------------- /Debug/Fun Practice 3.tlog/cl.command.1.tlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gutty333/Hard-Programming-Challenges/f63f6d97fab7fe48b41bbe1671035d82d3f953ba/Debug/Fun Practice 3.tlog/cl.command.1.tlog -------------------------------------------------------------------------------- /Debug/Fun Practice 3.tlog/link.command.1.tlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gutty333/Hard-Programming-Challenges/f63f6d97fab7fe48b41bbe1671035d82d3f953ba/Debug/Fun Practice 3.tlog/link.command.1.tlog -------------------------------------------------------------------------------- /Debug/Fun Practice 3.tlog/link.read.1.tlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gutty333/Hard-Programming-Challenges/f63f6d97fab7fe48b41bbe1671035d82d3f953ba/Debug/Fun Practice 3.tlog/link.read.1.tlog -------------------------------------------------------------------------------- /Debug/Fun Practice 3.tlog/link.write.1.tlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gutty333/Hard-Programming-Challenges/f63f6d97fab7fe48b41bbe1671035d82d3f953ba/Debug/Fun Practice 3.tlog/link.write.1.tlog -------------------------------------------------------------------------------- /Debug/vc120.idb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gutty333/Hard-Programming-Challenges/f63f6d97fab7fe48b41bbe1671035d82d3f953ba/Debug/vc120.idb -------------------------------------------------------------------------------- /Fun Practice 3.VC.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gutty333/Hard-Programming-Challenges/f63f6d97fab7fe48b41bbe1671035d82d3f953ba/Fun Practice 3.VC.db -------------------------------------------------------------------------------- /Fun Practice 3.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25123.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Fun Practice 3", "Fun Practice 3.vcxproj", "{607FC734-623F-43EA-BFA7-A655A53AC8E5}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x86 = Debug|x86 11 | Release|x86 = Release|x86 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {607FC734-623F-43EA-BFA7-A655A53AC8E5}.Debug|x86.ActiveCfg = Debug|Win32 15 | {607FC734-623F-43EA-BFA7-A655A53AC8E5}.Debug|x86.Build.0 = Debug|Win32 16 | {607FC734-623F-43EA-BFA7-A655A53AC8E5}.Release|x86.ActiveCfg = Release|Win32 17 | {607FC734-623F-43EA-BFA7-A655A53AC8E5}.Release|x86.Build.0 = Release|Win32 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /Fun Practice 3.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | 15 | 16 | 17 | {607FC734-623F-43EA-BFA7-A655A53AC8E5} 18 | Win32Proj 19 | FunPractice3 20 | 8.1 21 | 22 | 23 | 24 | Application 25 | true 26 | v120 27 | Unicode 28 | 29 | 30 | Application 31 | false 32 | v140 33 | true 34 | Unicode 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | true 48 | 49 | 50 | false 51 | 52 | 53 | 54 | 55 | 56 | Level3 57 | Disabled 58 | WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 59 | true 60 | 61 | 62 | Console 63 | true 64 | 65 | 66 | 67 | 68 | Level3 69 | 70 | 71 | MaxSpeed 72 | true 73 | true 74 | WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 75 | true 76 | 77 | 78 | Console 79 | true 80 | true 81 | true 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /Fun Practice 3.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Fun Practice 3.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | false 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Fun-Practice-3 2 | Hard programing challenges from coderbyte 3 | 4 | ### Highlights ### 5 | Folders and Cows 6 | Longest Common Subsequence 7 | Graph Traversal (DFS and BFS) 8 | Chess Algorithms 9 | Greedy Algorithms 10 | Matrix Determinant 11 | -------------------------------------------------------------------------------- /code2.cpp: -------------------------------------------------------------------------------- 1 | // For this challenge you will be optimally assigning tasks to a number of machines. 2 | /* 3 | have the function OptimalAssignments(strArr) read strArr which will represent an NxN matrix and it will be in the following format: ["(n,n,n...)","(...)",...] where the n's represent integers. This matrix represents a machine at row i performing task at column j. The cost for this is matrix[i][j]. Your program should determine what machine should perform what task so as to minimize the whole cost and it should return the pairings of machines to tasks in the following format: (i-j)(...)... Only one machine can perform one task. For example: if strArr is ["(5,4,2)","(12,4,3)","(3,4,13)"] then your program should return (1-3)(2-2)(3-1) because assigning the machines to these tasks gives the least cost. The matrix will range from 2x2 to 6x6, there will be no negative costs in the matrix, and there will always be a unique answer. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | // Not finished, Logical Error 13 | 14 | // Linear Search 15 | bool search(vector arr, int size, int value) 16 | { 17 | for (int x = 0; x < size; x++) 18 | { 19 | if (value == arr[x]) 20 | { 21 | return true; 22 | } 23 | } 24 | return false; 25 | } 26 | 27 | // Optimal Checker function 28 | // Recursive function to check for the optimal assignment 29 | // It checks for the zeros corresponding to its row it then checks the whole matrix to find which columns correspond to each machine 30 | // Since the other steps have been done prior a solution will be found no MATTER WHAT :) 31 | void optimalChecker(string& optimal, vector > strArr, int& row, int col, int size, vector & colList) 32 | { 33 | // Check to see if we found an optimal solution 34 | if (colList.size() == size) 35 | { 36 | return; 37 | } 38 | else if (row < size && colList.size() == row) 39 | { 40 | optimal.push_back('('); 41 | optimal.push_back(char(row + 49)); 42 | optimal.push_back('-'); 43 | for (col; col < size && row < size; col++) 44 | { 45 | // Set the possible combinations 46 | if (strArr[row][col] == 0 && !search(colList, colList.size(), col)) 47 | { 48 | colList.push_back(col); // Keep track of the column location for that combination 49 | // Check the current combination 50 | optimal.push_back(char(colList[colList.size()-1] + 49)); 51 | optimal.push_back(')'); 52 | row++; 53 | optimalChecker(optimal, strArr, row, 0, size, colList); 54 | } 55 | } 56 | } 57 | // If no match was found with the current combination 58 | // Note that a match will be found regardless 59 | // Basically this will take a step back and allow us to analyze other possible combinations 60 | if (colList.size() != size) 61 | { 62 | optimal.erase(optimal.size()-5); // Remove the output column 63 | row--; // Trace back to previous row 64 | colList.pop_back(); // Remove last recorded column index 65 | } 66 | else 67 | { 68 | return; 69 | } 70 | } 71 | 72 | // This function performs the step of step 3 in the Hungarian method 73 | bool lineCover(vector > newList, int size, vector& rowList, vector & colList) 74 | { 75 | // Step 3 includes covering the zeros of the matrix 76 | int count,x,y; 77 | int lines = 0; 78 | rowList.clear(); 79 | colList.clear(); 80 | 81 | // Loop checking for multiple zeros in a x 82 | for (x = 0; x < size; x++) 83 | { 84 | count = 0; 85 | for (y = 0; y < size; y++) 86 | { 87 | if (newList[x][y] == 0) 88 | { 89 | count++; 90 | } 91 | } 92 | if (count > 1) 93 | { 94 | lines++; 95 | rowList.push_back(x); 96 | } 97 | } 98 | // Loop to check for zeros in the columns 99 | for (y = 0; y < size; y++) 100 | { 101 | count = 0; 102 | for (x = 0; x < size; x++) 103 | { 104 | if (newList[x][y] == 0 && !search(rowList, rowList.size(), x)) 105 | { 106 | count++; 107 | } 108 | } 109 | if (count >= 1) 110 | { 111 | lines++; 112 | colList.push_back(y); 113 | } 114 | } 115 | 116 | if (lines == size) 117 | { 118 | return true; 119 | } 120 | else 121 | { 122 | return false; 123 | } 124 | } 125 | 126 | // This function will performs the procedures of step 5 found in the Hungarian method 127 | void smallestEntry(vector>& newList, int size, vector rowList, vector colList) 128 | { 129 | int x, y, low; 130 | // Step 5 we find the smallest entry not covered by a line 131 | 132 | do 133 | { 134 | for (x = 0; x < size; x++) 135 | { 136 | low = 10000 * 1000; 137 | // Only checking the uncovered lines 138 | // In this case if that column was covered by a line, ignore and analyze the next 139 | if (!search(rowList, rowList.size(), x)) 140 | { 141 | for (y = 0; y < size; y++) 142 | { 143 | // Here also make sure that if the column was cover ignore values that fall in that column 144 | if (!search(colList, colList.size(), y) && newList[x][y] < low) 145 | { 146 | low = newList[x][y]; 147 | } 148 | } 149 | } 150 | 151 | // Subtracting 5 from each uncovered row 152 | for (x = 0; x < size; x++) 153 | { 154 | if (!search(rowList, rowList.size(), x)) 155 | { 156 | for (y = 0; y < size; y++) 157 | { 158 | newList[x][y] -= 5; 159 | } 160 | } 161 | } 162 | 163 | // Adding 5 to each covered column 164 | for (y = 0; y < size; y++) 165 | { 166 | if (search(colList, colList.size(), y)) 167 | { 168 | for (x = 0; x < size; x++) 169 | { 170 | newList[x][y] += 5; 171 | } 172 | } 173 | } 174 | } 175 | } while (!lineCover(newList, size, rowList, colList)); 176 | // Continues to loop back to step 3 until the minimum number of lines is equal to n 177 | } 178 | 179 | string OptimalAssignments(string strArr[], int size) { 180 | vector > newList(size); // 2D vector 181 | string num; 182 | int temp; 183 | // Make the string argument into a list of integers for ease of handling down the line 184 | for (int x = 0; x < size; x++) 185 | { 186 | for (int y = 0; y < strArr[x].length(); y++) 187 | { 188 | if ((strArr[x][y] == '(' || strArr[x][y] == ')' || strArr[x][y] == ',') && !num.empty()) 189 | { 190 | istringstream(num) >> temp; 191 | newList[x].push_back(temp); 192 | num.clear(); 193 | } 194 | else if (isdigit(strArr[x][y])) 195 | { 196 | num += strArr[x][y]; 197 | } 198 | } 199 | } 200 | 201 | // Here we perform step 1 from the Hungarian method 202 | // This includes subtracting the smallest value from its current row 203 | int row, col; 204 | int low; 205 | for (row = 0; row < size; row++) 206 | { 207 | low = 1000 * 100000; 208 | // Finding the low value for that row 209 | for (col = 0; col < size; col++) 210 | { 211 | if (newList[row][col] < low) 212 | { 213 | low = newList[row][col]; 214 | } 215 | } 216 | // Subtract that value from the current row it belongs to 217 | for (col = 0; col < size; col++) 218 | { 219 | newList[row][col] -= low; 220 | } 221 | } 222 | 223 | // Here is step 2 from the Hungarian method 224 | // Now we subtract the smallest value from the columns 225 | for (col = 0; col < newList[0].size(); col++) 226 | { 227 | low = 1000 * 10000; 228 | // Find the low entry in the column 229 | for (row = 0; row < size; row++) 230 | { 231 | if (newList[row][col] < low) 232 | { 233 | low = newList[row][col]; 234 | } 235 | } 236 | // Subtract the low entry from its current column 237 | for (row = 0; row < size; row++) 238 | { 239 | newList[row][col] -= low; 240 | } 241 | } 242 | 243 | // Step 4 checking if the number of covering lines is equal to n 244 | // n = size 245 | vector rowList; 246 | vector colList; 247 | string optimal; 248 | if (lineCover(newList, size, rowList, colList)) 249 | { 250 | row = 0; 251 | colList.clear(); 252 | for (int x = 0; x < size; x++) 253 | { 254 | for (int y = 0; y < size; y++) 255 | { 256 | cout << newList[x][y] << " "; 257 | } 258 | cout << endl; 259 | } 260 | optimalChecker(optimal, newList, row, 0, size, colList); 261 | return optimal; 262 | } 263 | else 264 | { 265 | smallestEntry(newList, size, rowList, colList); 266 | row = 0; 267 | colList.clear(); 268 | for (int x = 0; x < size; x++) 269 | { 270 | for (int y = 0; y < size; y++) 271 | { 272 | cout << newList[x][y] << " "; 273 | } 274 | cout << endl; 275 | } 276 | optimalChecker(optimal, newList, row, 0, size, colList); 277 | return optimal; 278 | } 279 | } 280 | 281 | int main() { 282 | // keep this function call here 283 | /* Note: In C++ you first have to initialize an array and set 284 | it equal to the stdin to test your code with arrays. */ 285 | string A[] = { "(1,2,1)", "(4,1,5)", "(5,2,1)" }; 286 | string B[] = { "(13,4,7,6)", "(1,11,5,4)", "(6,7,2,8)", "(1,3,5,9)" }; 287 | string C[] = { "(5,4,2)", "(12,4,3)", "(3,4,13)" }; 288 | string D[] = { "(90,75,75,80)", "(35,85,55,65)", "(125,95,90,105)", "(45,110,95,115)" }; 289 | 290 | cout << OptimalAssignments(A, sizeof(A) / sizeof(A[0])) << endl; // (1-1)(2-2)(3-3) 291 | cout << OptimalAssignments(B, sizeof(B) / sizeof(B[0])) << endl; // (1-2)(2-4)(3-3)(4-1) 292 | cout << OptimalAssignments(C, sizeof(C) / sizeof(C[0])) << endl; // (1-3)(2-2)(3-1) 293 | cout << OptimalAssignments(D, sizeof(D) / sizeof(D[0])) << endl; // (1-4)(2-3)(3-2)(4-1) or (1-2)(2-4)(3-3)(4-1) 294 | return 0; 295 | } -------------------------------------------------------------------------------- /extra_FoldersAndCows.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | using namespace std; 25 | 26 | const string shared = "Shared"; 27 | const string confidential = "Confidential"; 28 | 29 | 30 | // structure used to represent each folder 31 | struct folder 32 | { 33 | int folderId; 34 | int cowCount; 35 | string type; 36 | vector cowIds; 37 | 38 | folder* left; 39 | folder* right; 40 | folder* parent; 41 | }; 42 | 43 | // method to add folders/nodes to our table 44 | // the hash table will later allow us to quickly access any of the folders 45 | void addFolder(map& graph, int ID, int cowCount, string type, vector cowIds) 46 | { 47 | // creating the folder and adding its content 48 | folder* newFolder = new folder; 49 | newFolder->folderId = ID; 50 | newFolder->cowCount = cowCount; 51 | newFolder->type = type; 52 | newFolder->cowIds = cowIds; 53 | 54 | newFolder->left = NULL; 55 | newFolder->right = NULL; 56 | newFolder->parent = NULL; 57 | 58 | // adding the folder to our graph 59 | graph[ID] = newFolder; 60 | } 61 | 62 | 63 | // method to create the relationship between the folders (parent/child relation) 64 | void makePair(map graph, int parent, int child) 65 | { 66 | // get the current parent and children; 67 | folder* currentParent = graph[parent]; 68 | folder* currentChild = graph[child]; 69 | 70 | // creating the child connection, first we locate a possible space 71 | if (currentParent->left == NULL && currentParent->right == NULL) 72 | { 73 | currentParent->left = currentChild; 74 | } 75 | else if (currentParent->left == NULL) 76 | { 77 | currentParent->left = currentChild; 78 | } 79 | else if (currentParent->right == NULL) 80 | { 81 | currentParent->right = currentChild; 82 | } 83 | 84 | // creating the parent connection 85 | currentChild->parent = currentParent; 86 | } 87 | 88 | 89 | // method to locate the root of the hierarchy 90 | folder* locateRoot(folder* current) 91 | { 92 | while (current->parent != NULL) 93 | { 94 | current = current->parent; 95 | } 96 | 97 | return current; 98 | } 99 | 100 | 101 | /* 102 | method checking for uncool cows 103 | we analyze the current cow and check if that has access to the leaves of the hierarchy 104 | after locating the root node we traverse down the tree 105 | 106 | 107 | we check the type of current folder 108 | note if folder is shared it can borrow from parent as long as parent was also shared 109 | if folder is confidential it must include the current cow we are checking if is a leaf 110 | 111 | when we reach a leaf and the folder is shared we check if the current cow followed it down or was found there 112 | when we reach a leaf and the folder is confidential we check the current folder's cow ids and check if is included there 113 | */ 114 | bool findCow(folder* root, int cowID, bool parentHas) 115 | { 116 | // base case when we reach a leaf node 117 | if (root == NULL) 118 | { 119 | return true; 120 | } 121 | if (root->left == NULL && root->right == NULL) 122 | { 123 | // analyze the cow ids of the confidential folder 124 | if (root->type == confidential) 125 | { 126 | for (int x = 0; x < root->cowIds.size(); x++) 127 | { 128 | if (cowID == root->cowIds[x]) 129 | { 130 | return true; 131 | } 132 | } 133 | 134 | return false; 135 | } 136 | else 137 | { 138 | // analyzing the a leaf shared folder 139 | // if the parent had that cow than it can access this folder 140 | // else if not found in the parent it must be located here to not be uncool 141 | if (parentHas) 142 | { 143 | return true; 144 | } 145 | else 146 | { 147 | for (int x = 0; x < root->cowIds.size(); x++) 148 | { 149 | if (cowID == root->cowIds[x]) 150 | { 151 | return true; 152 | } 153 | } 154 | 155 | return false; 156 | } 157 | } 158 | } 159 | 160 | // no need to bother checking if current is shared and the we already located the cow in parent shared folder 161 | if (parentHas && root->type == shared) 162 | { 163 | return findCow(root->left, cowID, parentHas) && findCow(root->right, cowID, parentHas); 164 | } 165 | 166 | // check if cow ID is located in the current folder 167 | for (int x = 0; x < root->cowIds.size(); x++) 168 | { 169 | if (cowID == root->cowIds[x] && root->type == shared) 170 | { 171 | parentHas = true; 172 | break; 173 | } 174 | 175 | parentHas = false; 176 | } 177 | 178 | // recursive call to ensure the cow ID is accessible in the leaf folders 179 | return findCow(root->left, cowID, parentHas) && findCow(root->right, cowID, parentHas); 180 | } 181 | 182 | 183 | // method that will analyze all the cows and check their placement in the hierarchy 184 | void FoldersAndCows(folder* root, int totalCows) 185 | { 186 | vector result; 187 | 188 | // checking all the cows 189 | for (int x = 0; x < totalCows; x++) 190 | { 191 | cout << "Current cow we are analyzing is " << x << endl; 192 | // condition to see if the cow is uncool 193 | if (!findCow(root, x, false)) 194 | { 195 | result.push_back(x); 196 | } 197 | } 198 | 199 | // outputting the result 200 | for (int x = 0; x < result.size(); x++) 201 | { 202 | cout << result[x] << " "; 203 | } 204 | cout << endl; 205 | } 206 | 207 | // simple level order traversal method 208 | void levelOrderTraversal(folder* root) 209 | { 210 | queue list; 211 | list.push(root); 212 | 213 | while (!list.empty()) 214 | { 215 | folder* current = list.front(); 216 | list.pop(); 217 | 218 | cout << "Current folder is " << current->folderId << endl; 219 | cout << "The children of this folder is/are" << endl; 220 | for (int x = 0; x < current->cowIds.size(); x++) 221 | { 222 | cout << x + 1 << ". cow ID = " << current->cowIds[x] << endl; 223 | } 224 | cout << endl; 225 | 226 | if (current->left != NULL) 227 | { 228 | list.push(current->left); 229 | } 230 | 231 | if (current->right != NULL) 232 | { 233 | list.push(current->right); 234 | } 235 | } 236 | } 237 | 238 | 239 | int main() 240 | { 241 | // getting total amount of cows 242 | cout << "Enter the total amount of cows" << endl; 243 | int cowSize; 244 | cin >> cowSize; 245 | 246 | // hash table to represent our graph 247 | map graph; 248 | 249 | // section to get how many share and confidential folders we are working with 250 | int shareFolderSize; 251 | int confidentialFolderSize; 252 | cout << "Total amount of Shared folders" << endl; 253 | cin >> shareFolderSize; 254 | cout << "Total amount of Confidential folders" << endl; 255 | cin >> confidentialFolderSize; 256 | 257 | // temp to retrieve a starting point for the tree 258 | // from that point we can locate the root of the whole hierarchy since all folders will have only one parent 259 | int source; 260 | 261 | // adding our share folders to our graph 262 | for (int x = 0; x < shareFolderSize; x++) 263 | { 264 | int id; 265 | int cowCount; 266 | cout << "Enter the shared folder ID and how many cows it will have" << endl; 267 | cin >> id >> cowCount; 268 | 269 | // extracting a folder id for later use 270 | if (x == 0) 271 | { 272 | source = id; 273 | } 274 | 275 | vector cowIds; 276 | for (int y = 0; y < cowCount; y++) 277 | { 278 | int num; 279 | cout << "Enter the cow ID for cow #" << y + 1 << endl; 280 | cin >> num; 281 | cowIds.push_back(num); 282 | } 283 | addFolder(graph, id, cowCount, shared, cowIds); 284 | } 285 | 286 | 287 | // adding our confidential folders to our graph 288 | for (int x = 0; x < confidentialFolderSize; x++) 289 | { 290 | int id; 291 | int cowCount; 292 | cout << "Enter the confidential folder ID and how many cows it will have" << endl; 293 | cin >> id >> cowCount; 294 | 295 | vector cowIds; 296 | for (int y = 0; y < cowCount; y++) 297 | { 298 | int num; 299 | cout << "Enter the cow ID for cow #" << y + 1 << endl; 300 | cin >> num; 301 | cowIds.push_back(num); 302 | } 303 | addFolder(graph, id, cowCount, confidential, cowIds); 304 | } 305 | 306 | // getting the total number of connections 307 | int pairTotal; 308 | cout << "How many pair connections are there" << endl; 309 | cin >> pairTotal; 310 | 311 | for (int x = 0; x < pairTotal; x++) 312 | { 313 | int parent; 314 | int child; 315 | cout << "Enter the parent and child ID to create a connection" << endl; 316 | cin >> parent >> child; 317 | makePair(graph, parent, child); 318 | } 319 | 320 | // getting any possible folder 321 | folder* current = graph[1]; 322 | 323 | // getting the root folder of our hierarchy 324 | folder* root = locateRoot(current); 325 | 326 | // optional output for feedback 327 | cout << endl; 328 | levelOrderTraversal(root); 329 | cout << endl << endl; 330 | 331 | // algorithm implementing the folders and cows challenge 332 | FoldersAndCows(root, cowSize); 333 | 334 | return 0; 335 | } --------------------------------------------------------------------------------