Esempio n. 1
0
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");
	}
}
Esempio n. 2
0
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;
}
Esempio n. 3
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;
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
/* 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, &currentPos);		// 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;
}