#include<stdio.h>
#include<stdlib.h>
#include <stdbool.h>

#pragma warning(disable : 4996)
#define MAX 100		 // 집합의 최대 크기를 위한 상수

void setout(bool* A);
void set_union(bool* A, bool* B);
void set_intersect(bool* A, bool* B);
void set_minus(bool* A, bool* B);

void main()
{
	bool* A = (bool*)calloc(MAX, sizeof(bool));	// 집합 A를 위한 0으로 초기화된 배열
	bool* B = (bool*)calloc(MAX, sizeof(bool));	// 집합 B를 위한 0으로 초기화된 배열
	size_t size_A, size_B;				// 집합들의 크기를 위한 변수
	int input = 0;				// 사용자가 입력할 자연수를 위한 변수

	// 해당 프로그램에 대한 안내를 출력
	printf("\n\t\t\t\u250c---------------------------\u2510\n");
	printf("\t\t\t|    집합 연산 프로그램     |\n");
	printf("\t\t\t\u2514---------------------------\u2518\n\n");

	// 집합 A에 대한 필요한 정보를 사용자로부터 입력받음
	printf("집합 A가 가질 원소의 개수를 입력하라.: ");
	scanf("%d", &size_A);

	printf("%d 개의 집합 A의 원소들을 입력하라.: (자연수 원소 \u2208 [1;100]) : ", size_A);

	for (int i = 0; i < size_A; i++) {
		scanf("%d", &input);
		if (0 < input < MAX && A[input] == true) {
			printf("\n집합 A가 중복된 원소를 갖고 있다. 원소를 하나 더 입력하라.: ");
			i--;
			continue;
		}
		A[input] = true;
	}

	// 집합 B에 대한 필요한 정보를 사용자로부터 입력받음
	printf("집합 B가 가질 원소의 개수를 입력하라.: ");
	scanf("%d", &size_B);

	printf("%d 개의 집합 B의 원소들을 입력하라.: (자연수 원소 \u2208 [1;100]) : ", size_B);

	for (int i = 0; i < size_B; i++) {
		scanf("%d", &input);
		if (0 < input < MAX && B[input] == true) {
			printf("\n집합 B가 중복된 원소를 갖고 있다. 원소를 하나 더 입력하라.: ");
			i--;
			continue;
		}
		B[input] = true;
	}

	// 집합 A를 출력
	printf("\nA = {");
	setout(A);

	// 집합 B를 출력 
	printf("\nB = {");
	setout(B);

	// 집합 A와 B의 합집합을 계산하고 출력 
	printf("A \u222A B = {");
	set_union(A, B);

	// 집합 A와 B의 교집합을 계산하고 출력 
	printf("A \u2229 B = {");
	set_intersect(A, B);

	// 집합 A와 B의 차집합(A-B)을 계산하고 출력 
	printf("A \u2216 B = {");
	set_minus(A, B);

	// 집합 A와 B의 차집합(B-A)을 계산하고 출력 
	printf("B \u2216 A = {");
	set_minus(B, A);

	free(A), free(B);
	system("PAUSE");
}
// setout 함수가 주어진 집합을 출력
void setout(bool* A) {
	int count = 0, i;
	for (i = 0; i < MAX; i++) {
		if (A[i] == 1)
			break;
	}
	if (i == MAX) {
		printf("}\n");
		return;
	}

	for (i = 0; i < MAX; i++) {
		if (A[i] == 1) {
			if (count != 0) {
				printf(",");
			}
			printf("%3d", i);
			count = 1;
		}
	}
	printf(" }\n");
}

// Union 함수가 집합 A와 B의 합집합을 계산해서 출력
void set_union(bool* A, bool* B) {
	bool* result = (bool*)calloc(MAX, sizeof(bool));
	for (int i = 0; i < MAX; i++) {
		if (A[i] || B[i])
			result[i] = true;
	}

	setout(result);
	free(result);
}

// Inter 함수가 집합 A와 B의 교집합을 계산해서 출력
void set_intersect(bool* A, bool* B) {
	bool* result = (bool*)calloc(MAX, sizeof(bool));

	for (int i = 0; i < MAX; i++) {
		if (A[i] && B[i])
			result[i] = true;
	}

	setout(result);
	free(result);
}

// Minus 함수가 집합 A와 B의 차집합(A-B)을 계산해서 출력
void set_minus(bool* A, bool* B) {
	bool* result = (bool*)calloc(MAX, sizeof(bool));

	for (int i = 0; i < MAX; i++) {
		if (A[i] == true && B[i] == false)
			result[i] = true;
	}

	setout(result);
	free(result);
}