int main(int argc, char *argv[]) { int pos = 0; // Value of POS, initialized at 0 int len = INT_MAX; // Value of LEN, initialized at INT_MAX // If there are no arguments, exit if (argc < 2) { exit(0); } int firstfile = 1; // The index of the first filename // Read in values of POS and LEN if they exist if (*argv[1] == '-') { // Fail if just a "-" with no numbers if (*(argv[1]+1) == '\0') { DIE("Invalid POS/LEN"); } char* next = NULL; // End pointer for strtol // Retrieve the POS value from argv pos = strtol(argv[1]+1, &next, 10); if (*next == ',') { if (*(next+1) != '\0') { char* check = NULL; // Second end pointer for strtol // Retrieve the LEN value from the first end pointer len = strtol(next+1, &check, 10); // Fail if there are characters after "-POS,LEN" if (*check != '\0') { DIE("Invalid POS/LEN"); } } // Fail if just "-POS," else { DIE("Invalid POS/LEN"); } } // Fail if there is a non-comma value after POS else if (*next != '\0') { DIE("Invalid POS/LEN"); } firstfile++; } Stack A, B, C; // The three stack pointers // Create the stacks if (!createS(&A) || !createS(&B) || !createS(&C)) { DIE("Create stack failed"); } int numLines = 0; // The number of lines read FILE* file = NULL; // The current file pointer // File reading loop for (int i = firstfile; i < argc; i++) { file = fopen(argv[i], "r"); if (file == NULL) { DIE("Unreadable File"); } char* line; // The current line pointer // Line reading loop while ((line = getLine(file)) != NULL) { char* newline = strchr(line, '\n'); // Pointer to check for newlines // Remove trailing newlines if (newline != NULL) { *newline = '\0'; } // Push the lines into stack A if (!pushS(&A, line)) { DIE("Push failed"); } numLines++; } fclose(file); } quicksort(&A, &B, &C, true, 1, numLines, pos, len); // Line printing loop for (int i = 0; i < numLines; i++) { char *line; // The current line to print // Pop off a line to be printed if (!popS(&A, &line)) { DIE("Pop failed"); } fprintf(stdout, "%s\n", line); free(line); } // Destroy the stacks if (!destroyS(&A) || !destroyS(&B) || !destroyS(&C)) { DIE("Destroy stack failed"); } }
int main(int numargs, char *args[]){ //should have either 4, 5, 6, or 7 arguments //if 7, [1] must be -r, [2,3,4] must be ints, initial and goal are letters //if 6, must not include -r, include all else //if 5 must include -r and not height OR width //if 4, must have int for maxlength and letters for other, and nothing else //height and width are ints between 2 and 5 (Default is 3) //maxlength is non-negative int (can be 0) //INITIAL and GOAL have the necessary number of letters for the size of the tray //letters between only A and L (duplicates ok) int width = 3; //width of the tray, default is 3 int height = 3; //height of the tray, default is 3 int maxlength = -1; //maxlength of the pattern int tilelen; //number of tiles char *temp; bool flag; //true is -r is specified bool used; char *initial; //initial position char *goal; //goal position //if all the command-line args follow the rules for 4 args if((numargs == 4) && checkNum(args[1]) && checkTiles(args[2], args[3])){ maxlength = (int)strtol(args[1], &temp, 10); tilelen = strlen(args[2]); flag = false; //no flag present initial = args[2]; goal = args[3]; } //if all the command-line args follow the rules for 5 args else if((numargs == 5) && checkFlag(args[1]) && checkNum(args[2]) && checkTiles(args[3], args[4])){ maxlength = (int)strtol(args[2], &temp, 10); tilelen = strlen(args[3]); flag = true; //flag present initial = args[3]; goal = args[4]; } //if all the command-line args follow the rules for 6 args else if((numargs == 6) && checkNum(args[1]) && checkNum(args[2]) && checkNum(args[3]) && checkTiles(args[4], args[5])){ height = (int)strtol(args[1], &temp, 10); width = (int)strtol(args[2], &temp, 10); maxlength = (int)strtol(args[3], &temp, 10); tilelen = strlen(args[4]); flag = false; //no flag present initial = args[4]; goal = args[5]; } //if all the command-line args follow the rules for 7 args else if((numargs == 7) && checkFlag(args[1]) && checkNum(args[2]) && checkNum(args[3]) && checkNum(args[4]) && checkTiles(args[5], args[6])){ height = (int)strtol(args[2], &temp, 10); width = (int)strtol(args[3], &temp, 10); maxlength = (int)strtol(args[4], &temp, 10); tilelen = strlen(args[5]); flag = true; //flag present initial = args[5]; goal = args[6]; } else{//invalid command line args fprintf(stderr, "Invalid command line arguments\n"); exit(1); } if((height >= 2) && (height <= 5) && (width >= 2) && (width <= 5) && (tilelen == height*width)){} else{//if the height and width aren't right, then quit fprintf(stderr, "Invalid command line arguments\n"); exit(1); } Stack q1; //create the two stacks for the queue Stack q2; createS(&q1); createS(&q2); char *nextStr; //holds what is popped off queue 'P' int nextLen; //holds the length of P Trie root; //root of the trie dictionary root.len = -1; root.from = NULL; for(int k = 0; k < 12; k++) root.children[k] = NULL; insert(&root, goal, NULL, 0); //insert root in queue & dictionary pushS(&q1, goal); if(!(strcmp(goal, initial))){ //if goal is initial printf("%s\n", initial); destroyS(&q1); destroyS(&q2); return 0; } while(!(isEmptyS(&q1) && isEmptyS(&q2))){ //while queue not empty popQ(&q1, &q2, &nextStr); nextLen = lenInTrie(&root, nextStr); used = false; if(nextLen < maxlength){ //generate all the possible tiles for(int c = 0; c < width; c++){ //for all column shifts if(flag){//-r, then do it for all possible shifts for(int sh = 1; sh < width; sh++){ char *nextTiles = shiftC(nextStr, height, width, c, height - sh); //next tile pattern generated by a shift if(!strcmp(nextTiles, initial)){ insert(&root, nextTiles, nextStr, nextLen + 1); printSteps(root, nextTiles); destroyS(&q1); destroyS(&q2); return 0; } if(insert(&root, nextTiles, nextStr, nextLen + 1)){ pushS(&q1, nextTiles); //add it to the queue and dictionary used = true; } else free(nextTiles); } } else{//else do it for shift is one step only char *nextTiles = shiftC(nextStr, height, width, c, height - 1); //next tile pattern generated by a shift if(!strcmp(nextTiles, initial)){ insert(&root, nextTiles, nextStr, nextLen + 1); printSteps(root, nextTiles); destroyS(&q1); destroyS(&q2); return 0; } if(insert(&root, nextTiles, nextStr, nextLen + 1)){ pushS(&q1, nextTiles); //add it to the queue and dictionary used = true; } else free(nextTiles); } } for(int r = 0; r < height; r++){//for all possible row shifts if(flag){//-r, then do it for all possible shifts for(int sh = 1; sh < height; sh++){ char *nextTiles = shiftR(nextStr, height, width, r, width - sh); //next tile pattern generated by a shift if(!strcmp(nextTiles, initial)){ insert(&root, nextTiles, nextStr, nextLen + 1); printSteps(root, nextTiles); destroyS(&q1); destroyS(&q2); return 0; } if(insert(&root, nextTiles, nextStr, nextLen + 1)){ pushS(&q1, nextTiles); //add it to the queue and dictionary used = true; } else free(nextTiles); } } else{//else do it for shift is one step only char *nextTiles = shiftR(nextStr, height, width, r, width - 1); //next tile pattern generated by a shift if(!strcmp(nextTiles, initial)){ insert(&root, nextTiles, nextStr, nextLen + 1); printSteps(root, nextTiles); destroyS(&q1); destroyS(&q2); return 0; } if(insert(&root, nextTiles, nextStr, nextLen + 1)){ pushS(&q1, nextTiles); //add it to the queue and dictionary used = true; } else free(nextTiles); } } } if(!used) free(nextStr); }//end of while queue is not empty destroyS(&q1); destroyS(&q2); return 0; }
int parse (FILE *in, FILE *out) { char *input = malloc(MAXLEN); char *test = fgets(input, MAXLEN, in); size_t n = atoi(test); //number of events size_t step = 1; //current step; //create Events stacks AStack *Events = initEvents(n); if (!Events) { return 1; } //create process queue AQueue aQ = initQ(sizeof(TProcess)); int check = 1; //used for checking function output test = fgets(input, MAXLEN, in); while (test != NULL && test[0] != '\n') { //tokenize input char *cmd[3] = {0}; int i = 0; char *aux = strtok(test, " \n"); while (aux != NULL) { cmd[i] = aux; ++i; aux = strtok(NULL, " \n"); } if (cmd[0] != NULL) { //call function accordingly if (!strcmp(cmd[0], "start")) { check = start(atoi(cmd[1]), atoi(cmd[2]), step, aQ); } else if (!strcmp(cmd[0], "wait")) { check = wait(atoi(cmd[1]), atoi(cmd[2]), &aQ, Events); } else if (!strcmp(cmd[0], "event")) { check = event(atoi(cmd[1]), aQ, Events); } else if (!strcmp(cmd[0], "end")) { check = end(atoi(cmd[1]), &aQ); } } //if some of the functions encountered problems exit loop (and program) //most probably will not happen if (check != 1) { for (size_t i = 0; i < n; i++) { destroyS(&Events[i]); } free(Events); destroyQ(&aQ); free(input); return check; } printEnv(step, n, aQ, Events, out); test = fgets(input, MAXLEN, in); ++step; } //free what needs to be freed for (size_t i = 0; i < n; i++) { destroyS(&Events[i]); } free(Events); destroyQ(&aQ); free(input); return 1; }
int main(int argc, char * argv[]){ Stack stack1; Stack stack2; Stack stack3; createS(&stack1); createS(&stack2); createS(&stack3); int flipped = 1; //equals 1 if lines are in same relative order as in files, -1 if flipped int pos = 0; int len = INT_MAX; int filestart = 1; //variable is incremented if there is a len/pos key int nlines = 0; //Number of lines beeing sorted char * end; if( argc == 1 ){ exit(1); } if(argv[1][0] == '-'){ filestart +=1; pos = strtol(&argv[1][1],&end,10); if(end[0] != ',' && strlen(end) != 0){ DIE("Invalid input"); } else if (strlen(end) != 0 ){ len = strtol(&end[1],&end,10); printf("%d", len); } if (strlen(end) != 0){ DIE("Invalid input"); } } char * line; FILE * fp; for(int m=filestart; m < argc; m++) { if(argv[m][0] == '-'){ fp = stdin; } else if ((fp = fopen(argv[m],"r")) == NULL){ DIE("Cannot read file"); } while((line = getLine(fp)) != NULL){ remove_break(&line); if(!pushS(&stack1, line)){ DIE("pushS failed to execute"); } nlines += 1; } fclose(fp); } split(&stack2, &stack1, &stack3, nlines, pos, len, -1, flipped * -1); while(!isEmptyS(&stack2)){ popS(&stack2, &line); printf("%s", line); free(line); printf("\n"); } while(!isEmptyS(&stack1)){ popS(&stack1, &line); printf("%s", line); free(line); printf("\n"); } destroyS(&stack1); destroyS(&stack2); destroyS(&stack3); return 1; }
/* RubikSq.c | Stephen Krewson | CPSC 223b. USAGE: RubikSq [-r] [HEIGHT WIDTH] MAXLENGTH INITIAL GOAL. RubikSq solves a Rubik's square puzzle using a trie data structure and breadth-first search to find the fewest number of moves necessary to transform INITIAL into GOAL. */ int main (int argc, char *argv[]) { // 1. PARSING COMMAND-LINE ARGS bool rFlag = false; int maxLength = 0; int pos = 0; // pos is counter for moving through argv[] int height = 3, width = 3; // default values char *initial = NULL; char *goal = NULL; if (argc % 2 != 0) // "-r" specified { if (argc > 3) { if (strcmp(argv[1], "-r") != 0) KILL("ERROR: '-r' flag improperly specified."); else rFlag = true; } else KILL("ERROR: Insufficient number of arguments."); } if (argc == 6 || argc == 7) // HEIGHT and WIDTH specified { // Indexes depend on -r flag pos = (rFlag == true) ? 2 : 1; initial = strdup(argv[pos+3]); // use malloc bc we will call free() goal = strdup(argv[pos+4]); // on all the dict nodes if (!(height = atoi(argv[pos])) || !(width = atoi(argv[pos+1])) || (height < 2 || height > 5) || (width < 2 || width > 5)) KILL("ERROR: Invalid HEIGHT and WIDTH values."); char *endPtr; maxLength = (int) strtol(argv[pos+2], &endPtr, 10); if (endPtr < argv[pos+2] + strlen(argv[pos+2])) KILL("ERROR: MAXLENGTH contains nun-numeric characters."); else if (maxLength < 0) KILL ("ERROR: MAXLENGTH is negative."); if (!checkTray(height, width, initial, goal)) KILL("ERROR: Invalid tray sequences."); } // HEIGHT, WIDTH NOT specified else if (argc == 4 || argc == 5) { pos = (rFlag == true) ? 2 : 1; initial = strdup(argv[pos+1]); goal = strdup(argv[pos+2]); char *endPtr; maxLength = (int) strtol(argv[pos], &endPtr, 10); if (endPtr < argv[pos] + strlen(argv[pos])) KILL("ERROR: MAXLENGTH contains nun-numeric characters."); else if (maxLength < 0) KILL ("ERROR: MAXLENGTH is negative."); if (!checkTray(height, width, initial, goal)) KILL("ERROR: Invalid tray sequences."); } else { KILL("ERROR: Invalid number of arguments."); } Trie dict; // Initialize trie data structure createT(&dict); Stack stk1, stk2; // Initialize the "queue" createS(&stk1); createS(&stk2); char *currentPos = NULL; // pointer for position being processed char *prevPos = NULL; // pointer to "from" attr in the dict long lengthPos = 0; // address to hold "length" attr in the dict int permutations = 0; // hold # of permutations getPerms returns insertT(&dict, goal, NULL, 0); // Add GOAL to dictionary enqueue(&stk1, &stk2, goal); // push GOAL onto the queue while (!isEmptyQ(&stk1, &stk2)) // While the queue is not empty { dequeue(&stk1, &stk2, ¤tPos); // Remove P from head of queue searchT(&dict, currentPos, &prevPos, &lengthPos); // lengPos holds length of P if (lengthPos + 2 < maxLength) // +2 because currentPos is 1 { // more than the previous distance and each // permutation is another distance of 1 char **perms; // array of pointers to permutations of P perms = getPerms(currentPos, height, width, rFlag, &permutations); for (int j = 0; j < permutations; j++) // for each position . . . { if (strcmp(initial, perms[j]) == 0) // if P' is the INITIAL { // add it so we can trace insertT(&dict, perms[j], currentPos, lengthPos+1); printf("%s\n", initial); // print INITIAL printf("%s\n", currentPos); // reached INITIAL from... char *holder2; // follow path of search holder2 = currentPos; // start at currentPos while (strcmp(holder2, goal) != 0) { if(!searchT(&dict, currentPos, &holder2, &lengthPos)) { KILL("ERROR: searchT() failed."); } printf("%s\n", holder2); currentPos = holder2; } destroyS(&stk1); // get rid of the queue destroyS(&stk2); deleteT(dict, dict); free(dict); // Remember root node free(perms[j]); free(perms); // free the pointer array exit(0); // Successful exit! } else if (!searchT(&dict, perms[j], &prevPos, &lengthPos)) { // Put p' in dict, on queue if (!insertT(&dict, perms[j], currentPos, lengthPos+1)) { KILL("ERROR: insertT() failed."); } enqueue(&stk1, &stk2, perms[j]); } else // else P' is already in the dictionary { free(perms[j]); // don't need it anymore! } } free(perms); // Free the pointer array } } destroyS(&stk1); // Cleanup in case of no valid sequence destroyS(&stk2); deleteT(dict, dict); free(dict); // Remember to clean root node of dict return EXIT_SUCCESS; }