without haste but without rest

[C / 자료구조] 4주차 과제 - 뱅킹 시뮬레이션 본문

Homework

[C / 자료구조] 4주차 과제 - 뱅킹 시뮬레이션

JinungKim 2020. 4. 9. 22:48
# include <stdio.h>
# include <stdlib.h>


// 프로그램 5.2에서 다음과 같은 부분을 복사한다. 
// ================ 원형큐 정의부 시작 =================
typedef struct { // 요소 타입
	int id;
	int arrival_time;
	int service_time;
	int start_time;
} element;			// 교체!
// ================ 원형큐 정의부 종료 =================
// ===== 원형큐 코드 시작 ======
#define MAX_QUEUE_SIZE 30

typedef struct { // 큐 타입
	element  data[MAX_QUEUE_SIZE];
	int  front, rear;
} QueueType;

// 오류 함수
void error(char* message)
{
	fprintf(stderr, "%s\n", message);
	exit(1);
}

// 공백 상태 검출 함수
void init_queue(QueueType* q)
{
	q->front = q->rear = 0;
}

// 공백 상태 검출 함수
int is_empty(QueueType* q)
{
	return (q->front == q->rear);
}

// 포화 상태 검출 함수
int is_full(QueueType* q)
{
	return ((q->rear + 1) % MAX_QUEUE_SIZE == q->front);
}

// 원형큐 출력 함수
void queue_print(QueueType* q)
{
	printf("QUEUE(front=%d rear=%d) = ", q->front, q->rear);
	if (!is_empty(q)) {
		int i = q->front;
		do {
			i = (i + 1) % (MAX_QUEUE_SIZE);
			printf("%d | ", q->data[i]);
			if (i == q->rear)
				break;
		} while (i != q->front);
	}
	printf("\n");
}

// 삽입 함수
void enqueue(QueueType* q, element item)
{
	if (is_full(q))
		error("큐가 포화상태입니다");
	q->rear = (q->rear + 1) % MAX_QUEUE_SIZE;
	q->data[q->rear] = item;
}

// 삭제 함수
element dequeue(QueueType* q)
{
	if (is_empty(q))
		error("큐가 공백상태입니다");
	q->front = (q->front + 1) % MAX_QUEUE_SIZE;
	return q->data[q->front];
}

// 삭제 함수
element peek(QueueType* q)
{
	if (is_empty(q))
		error("큐가 공백상태입니다");
	return q->data[(q->front + 1) % MAX_QUEUE_SIZE];
}
// ===== 원형큐 코드 끝 ======


// ===== 과제 추가 기능 ======
int get_count(QueueType* q) {
	if (q->front <= q->rear) return q->rear - q->front;
	else return (q->rear + 1) + (MAX_QUEUE_SIZE -1 - q->front);
}
// ===== 과제 코드 완료  ======


int main(void)
{
	int minutes = 60;
	int total_wait = 0;
	int total_customers = 0;
	int service_time = 0;
	int service_customer;
	QueueType queue;
	QueueType log;
	init_queue(&queue);
	init_queue(&log);

	srand(time(NULL));
	for (int clock = 0; clock < minutes; clock++) {
		printf("현재시각=%d [%d명 대기]\n", clock, get_count(&queue));
		if ((rand() % 10) < 3) {
			element customer;
			customer.id = total_customers++;
			customer.arrival_time = clock;
			customer.service_time = rand() % 3 + 1;
			enqueue(&queue, customer);
			printf("고객 %d이 %d분에 들어옵니다. 업무처리시간= %d분\n",
				customer.id, customer.arrival_time, customer.service_time);
		}
		if (service_time > 0) {
			printf("고객 %d 업무처리중입니다. \n", service_customer);
			service_time--;
		}
		else {
			if (!is_empty(&queue)) {
				element customer = dequeue(&queue);

				// customer를 log 큐에 인큐,
				customer.start_time = clock;
				enqueue(&log, customer);
				// 추가할 정보 -> 작업 시작 시간

				service_customer = customer.id;
				service_time = customer.service_time;
				printf("고객 %d이 %d분에 업무를 시작합니다. 대기시간은 %d분이었습니다.\n",
					customer.id, clock, clock - customer.arrival_time);
				total_wait += clock - customer.arrival_time;
			}
		}
	}
	printf("전체 대기 시간=%d분 \n", total_wait);
	printf("\n대기고객 %d명\n", get_count(&queue));
	if (!is_empty(&queue)) {
		if (queue.front < queue.rear) {
			for (int i = queue.front + 1; i <= queue.rear; i++) {
				printf("[%d] %d분 도착, [%d분 대기] 작업시간 %d분\n",
					queue.data[i].id, queue.data[i].arrival_time,
					minutes - queue.data[i].arrival_time, queue.data[i].service_time);
			}
		}
		else {
			for (int i = queue.front + 1; i < MAX_QUEUE_SIZE; i++) {
				printf("[%d] %d분 도착, [%d분 대기] 작업시간 %d분\n",
					queue.data[i].id, queue.data[i].arrival_time,
					minutes - queue.data[i].arrival_time, queue.data[i].service_time);
			}
			for (int i = 0; i < queue.rear + 1; i++) {
				printf("[%d] %d분 도착, [%d분 대기] 작업시간 %d분\n",
					queue.data[i].id, queue.data[i].arrival_time,
					minutes - queue.data[i].arrival_time, queue.data[i].service_time);
			}
		}
	}
	printf("\n고객 로그\n");
	if (!is_empty(&log)) {
		for (int i = log.front + 1; i <= log.rear; i++) {
			printf("[%2d] %2d분 도착, [%2d분 대기] %2d~ %2d분\n",
				log.data[i].id, log.data[i].arrival_time,
				log.data[i].start_time - log.data[i].arrival_time,
				log.data[i].start_time, log.data[i].start_time + log.data[i].service_time);
		}
	}
	return 0;
}
Comments