Example #1
0
// Removes the string from the front of the queue and sets it to s
void deQ(Queue *q, char **s) {
	if (isEmptyQ(q)) {
		DIE("Queue is empty");
	}

	if (!isEmptyS(&(q->stack2))) {
		popS(&(q->stack2), s);
	}
	else {
		while (!isEmptyS(&(q->stack1))) {
			popS(&(q->stack1), s);
			pushS(&(q->stack2), *s);
		}
		popS(&(q->stack2), s);
	}
}
Example #2
0
char* popQ( StrQueue* queue )
{
	if( isEmptyQ(queue) == 0 ){
		char* temp;

		queue->front = (queue->front + 1) % Q_ARR_MAX;
		temp = queue->queue[ queue->front ];
		queue->queue[ queue->front ] = 0;

		return temp;

	}else{
		printf("queue is empty");
		return NULL;
	}
}
Example #3
0
int dequeue(QUEUE *Q,int *data)
{
	int i;
	if(isEmptyQ(*Q))
		return 0;
	else
	{
		 	*data=Q->q[Q->front];
			i=Q->front;
						
			while(i!=Q->rear)
			{
				Q->q[i]=Q->q[i+1];
				i++;		
			}			
			//(Q->front)--;
			
			if(Q->front==Q->rear)
				--(Q->front);
			--(Q->rear);
			
			return 1;
	}
}
Example #4
0
/* Pops off string pointer in FIFO order by taking from Stack 2 if it has
values and otherwise pouring all the values from Stack 1 into Stack 2 before
popping off the top of Stack 2, which will be the first element pushed onto
Stack 1. Returns TRUE if successful and puts popped value into *pos.
*/
bool dequeue (Stack *stk1, Stack *stk2, char **pos)
{
	if (!isEmptyQ(stk1, stk2))			// The queue is NOT empty
	{
		if (!isEmptyS(stk2))			// stk2 has vals, pop off top one
		{
			popS(stk2, pos);
			return true;
		}
		else							// No vals in stk2
		{
			while (!isEmptyS(stk1))		// pour all of stk1 into stk2
			{
				popS(stk1, pos);
				pushS(stk2, *pos);
			}
			popS(stk2, pos);			// Now pop off top of stk2
			return true;
		}
		
	}
	else
		return false;					// Queue was empty
}
Example #5
0
int main(int argc, char *argv[])
{

	bool rFlag = false;		// Flag to tell if -r is specified
	int height = 3;			// HEIGHT of the Rubik's square
	int width = 3;			// WIDTH of the Rubik's square
	int maxlength;			// MAXLENGTH of a series of moves
	char *initial = NULL;	// The INITIAL string
	char *goal = NULL;		// The GOAL string

	/*
	INPUT ERROR CHECKING
	*/

	// Check for correct number of args
	if (argc <  4 || argc > 7) {
		DIE("RubikSq: RubikSq [-r] [HEIGHT WIDTH] MAXLENGTH INITIAL GOAL");
	}

	if (argc == 5 || argc == 7) {
		// Check to make sure the first arg is "-r"
		if (strcmp(argv[1], "-r") != 0) {
				DIE("RubikSq: Invalid [-r] Flag");
		}
		rFlag = true;
	}

	if (argc == 6 || argc == 7) {
		char *check = argv[argc-5];	// Used to check for non-numeric chars in the args
		for (int i = 0; i < strlen(check); i++) {
			if (!isdigit(check[i])) {
				DIE("RubikSq: Invalid HEIGHT");
			}
		}

		char *end = NULL;	// End pointer for strtol
		height = strtol(argv[argc-5], &end, 10);
		if (*end != '\0') {
			DIE("RubikSq: Invalid HEIGHT");
		}

		char *check2 = argv[argc-4]; // Used to check for non-numeric chars in the args
		for (int i = 0; i < strlen(check2); i++) {
			if (!isdigit(check2[i])) {
				DIE("RubikSq: Invalid WIDTH");
			}
		}

		char *end2 = NULL;	// End pointer for strtol
		width = strtol(argv[argc-4], &end2, 10);
		if (*end2 != '\0') {
			DIE("RubikSq: Invalid WIDTH");
		}
	}

	char *check3 = argv[argc-3];	// Used to check for non-numeric chars in the args
	for (int i = 0; i < strlen(check3); i++) {
		if (!isdigit(check3[i])) {
			DIE("RubikSq: Invalid MAXLENGTH");
		}
	}

	char *end3 = NULL;		// End pointer for strtol
	maxlength = strtol(argv[argc-3], &end3, 10);
	if (*end3 != '\0') {
		DIE("RubikSq: Invalid MAXLENGTH");
	}

	// Check for non-alpha chars in the args
	initial = argv[argc-2];
	for (int i = 0; i < strlen(initial); i++) {
		if (!isalpha(initial[i])) {
			DIE("RubikSq: Invalid INITIAL");
		}
	}

	// Check for non-alpha chars in the args
	goal = argv[argc-1];
	for (int i = 0; i < strlen(goal); i++) {
		if (!isalpha(goal[i])) {
			DIE("RubikSq: Invalid GOAL");
		}
	}

	if (maxlength < 0) {
		DIE("RubikSq: MAXLENGTH < 0");
	}

	if (height < 2 || height > 5 || width < 2 || width > 5) {
		DIE("RubikSq: HEIGHT/WIDTH must be between 2 and 5, inclusive");
	}

	if (strlen(initial) != strlen(goal)){
		DIE("RubikSq: Length of INITIAL does not equal length of GOAL");
	}

	if ((height*width) != strlen(initial)) {
		DIE("RubikSq: HEIGHT*WIDTH does not match length of INITIAL/GOAL");
	}

	// If GOAL and INITIAL are the same, print and exit
	if (strcmp(initial, goal) == 0) {
		printf("%s\n", initial);
		exit(0);
	}

	// Make an alphabetized copy of INITIAL
	char *initialSort = malloc(strlen(initial)+1);	// An alphabetized version of INITIAL
	strcpy(initialSort, initial);
	sortAlphabetical(initialSort);

	// Make an alphabetized copy of GOAL
	char *goalSort = malloc(strlen(goal)+1);		// An alphabetized version of GOAL
	strcpy(goalSort, goal);
	sortAlphabetical(goalSort);

	if (strcmp(initialSort, goalSort) != 0) {
		DIE("RubikSq: INITIAL and GOAL do not contain the same letters");
	}

	// Make sure all letters are between A and L, inclusive
	if (initialSort[0] < 'A' || initialSort[strlen(initialSort)-1] > 'L' ||
		goalSort[0] < 'A' || goalSort[strlen(goalSort)-1] > 'L') {
		DIE("RubikSq: INITIAL/GOAL contain invalid letters");
	}

	/*
	ALGORITHM
	*/

	Trie dict;			// The dictionary trie for storing past positions
	createT(&dict);
	addT(&dict, goal, NULL, 0, 0);

	Queue moves;		// The queue of positions to analyze
	createQ(&moves);
	enQ(&moves, goal);

	// Main loop
	while (!isEmptyQ(&moves)) {
		char *pos = NULL;	// The current position P
		deQ(&moves, &pos);

		int len = getLengthT(&dict, pos, 0);	// The length of P in the dictionary

		if (len < maxlength) {
			int total;		// The total number of possible moves

			// If -r is specified, there are more possible moves
			if (rFlag) {
				total = (width-1)*height + (height-1)*width;
			}
			else {
				total = width + height;
			}
			char *primes[total];	// The array of possible positions P'

			char *copy;		// Used to find all P' to put in the array

			// If the -r flag is specified, we can move right or down multiple times
			if (rFlag) {
				for (int i = 1; i <= height; i++) {
					copy = pos;
					for (int j = 1; j < width; j++){
						copy = moveRight(i, width, copy);
						primes[(i-1)*(width-1)+j-1] = copy;
					}
				}

				for (int i = 1; i <= width; i++) {
					copy = pos;
					for (int j = 1; j < height; j++){
						copy = moveDown(i, width, height, copy);
						primes[height*(width-1)+(i-1)*(height-1)+j-1] = copy;
					}
				}
			}
			// Otherwise, we can only make one move
			else {
				for (int i = 1; i <= height; i++) {
					primes[i-1] = moveRight(i, width, pos);
				}

				for (int i = 1; i <= width; i++) {
					primes[i+height-1] = moveDown(i, width, height, pos);
				}
			}

			// P' checking for loop
			for (int i = 0; i < total; i++) {

				// If P' is INITIAL, print the moves and exit
				if (strcmp(primes[i], initial) == 0) {
					printf("%s\n", primes[i]);
					printf("%s\n", pos);

					while (getFromT(&dict, pos, 0) != NULL) {
						pos = getFromT(&dict, pos, 0);
						printf("%s\n", pos);
					}

					// Free the sorted INITIAL and GOAL
					free(initialSort);
					free(goalSort);
					exit(0);
				}

				// Else if P' is not in the dictionary, add it to the dict and queue
				else if (!isMemberT(&dict, primes[i], 0)) {
					addT(&dict, primes[i], pos, len+1, 0);
					enQ(&moves, primes[i]);
				}

				// Else free the storage
				else {
					free(primes[i]);
				}
			}
		}
	}

	// Free the sorted INITIAL and GOAL
	free(initialSort);
	free(goalSort);
	return 0;
}
Example #6
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;
}