forked from freewilll/wcc
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathset.c
More file actions
140 lines (106 loc) · 4.04 KB
/
set.c
File metadata and controls
140 lines (106 loc) · 4.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "wcc.h"
Set *new_set(int max_value) {
Set *result = wmalloc(sizeof(Set));
result->max_value = max_value;
result->elements = wcalloc(max_value + 1, sizeof(char));
result->cached_element_count = 0;
result->cached_elements = 0;
return result;
}
void free_set(Set *s) {
if (s->cached_elements) wfree(s->cached_elements);
wfree(s->elements);
wfree(s);
}
void empty_set(Set *s) {
memset(s->elements, 0, (s->max_value + 1) * sizeof(char));
}
Set *copy_set(Set *s) {
Set *result = new_set(s->max_value);
memcpy(result->elements, s->elements, (s->max_value + 1) * sizeof(char));
return result;
}
void copy_set_to(Set *dst, Set *src) {
memcpy(dst->elements, src->elements, (src->max_value + 1) * sizeof(char));
}
void cache_set_elements(Set *s) {
if (!s->cached_elements) s->cached_elements = wmalloc((s->max_value + 1) * sizeof(int));
int *cached_elements = s->cached_elements;
int count = 0;
for (int i = 0; i <= s->max_value; i++)
if (s->elements[i]) cached_elements[count++] = i;
s->cached_element_count = count;
}
int set_len(Set *s) {
int max_value = s->max_value;
char *elements = s->elements;
int result = 0;
for (int i = 0; i <= max_value; i++) result += elements[i];
return result;
}
void print_set(Set *s) {
int first = 1;
printf("{");
for (int i = 0; i <= s->max_value; i++) {
if (s->elements[i]) {
if (!first) { printf(", "); }
printf("%d", i);
first = 0;
}
}
printf("}");
}
void *delete_from_set(Set *s, int value) {
if (value > s->max_value) panic("Max set value of %d exceeded with %d in delete_from_set", s->max_value, value);
s->elements[value] = 0;
}
int in_set(Set *s, int value) {
if (value > s->max_value) panic("Max set value of %d exceeded with %d in in_set", s->max_value, value);
return s->elements[value] == 1;
}
int set_eq(Set *s1, Set *s2) {
if (s1->max_value != s2->max_value) panic("Unequal set sizes in set_eq");
return memcmp(s1->elements, s2->elements, (s1->max_value + 1) * sizeof(char)) ? 0 : 1;
}
Set *set_intersection(Set *s1, Set *s2) {
if (s1->max_value != s2->max_value) panic("Unequal set sizes in set_intersection");
Set *result = new_set(s1->max_value);
for (int i = 0; i <= s1->max_value; i++)
result->elements[i] = s1->elements[i] && s2->elements[i];
return result;
}
void set_intersection_to(Set *dst, Set *s1, Set *s2) {
if (s1->max_value != s2->max_value) panic("Unequal set sizes in set_intersection_to");
if (s1->max_value != dst->max_value) panic("Unequal set sizes in set_intersection_to");
for (int i = 0; i <= s1->max_value; i++)
dst->elements[i] = s1->elements[i] && s2->elements[i];
}
Set *set_union(Set *s1, Set *s2) {
if (s1->max_value != s2->max_value) panic("Unequal set sizes in set_union");
Set *result = new_set(s1->max_value);
for (int i = 0; i <= s1->max_value; i++)
result->elements[i] = s1->elements[i] || s2->elements[i];
return result;
}
void set_union_to(Set *dst, Set *s1, Set *s2) {
if (s1->max_value != s2->max_value) panic("Unequal set sizes in set_union_to");
if (s1->max_value != dst->max_value) panic("Unequal set sizes in set_union_to");
for (int i = 0; i <= s1->max_value; i++)
dst->elements[i] = s1->elements[i] || s2->elements[i];
}
Set *set_difference(Set *s1, Set *s2) {
if (s1->max_value != s2->max_value) panic("Unequal set sizes in set_difference");
Set *result = new_set(s1->max_value);
for (int i = 0; i <= s1->max_value; i++)
result->elements[i] = s1->elements[i] && !s2->elements[i];
return result;
}
void set_difference_to(Set *dst, Set *s1, Set *s2) {
if (s1->max_value != s2->max_value) panic("Unequal set sizes in set_difference_to");
if (s1->max_value != dst->max_value) panic("Unequal set sizes in set_difference_to");
for (int i = 0; i <= s1->max_value; i++)
dst->elements[i] = s1->elements[i] && !s2->elements[i];
}