Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- typedef struct plist plist;
- typedef struct {
- char *name;
- plist *friends;
- } person;
- struct plist {
- person *data;
- plist *next;
- };
- static person *person_alloc(char *name) {
- person *new = calloc(sizeof(*new), 1);
- new->name = strdup(name), new->friends = NULL;
- return new;
- }
- static void print_person(person *p) {
- printf("Name: %s, friends: { ", p->name);
- for (plist *pl = p->friends; pl; pl = pl->next) {
- printf("%s, ", pl->data->name);
- }
- puts("}");
- }
- static void plist_add(plist **plp, person *p) {
- plist *new = calloc(sizeof(*new), 1);
- new->data = p, new->next = *plp, *plp = new;
- }
- static void become_friends(person *p1, person *p2) {
- plist_add(&(p1->friends), p2), plist_add(&(p2->friends), p1);
- }
- static void print_common_friends(person *p1, person *p2) {
- printf("%s and %s have common friends: { ", p1->name, p2->name);
- for (plist *pl1 = p1->friends; pl1; pl1 = pl1->next) {
- for (plist *pl2 = p2->friends; pl2; pl2 = pl2->next) {
- if (pl1->data == pl2->data) { printf("%s, ", pl1->data->name); }
- }
- }
- puts("}");
- }
- typedef struct pqueue_data pqueue_data;
- struct pqueue_data {
- person *person;
- int hop;
- pqueue_data *next;
- };
- typedef struct pqueue pqueue;
- struct pqueue {
- pqueue_data *head, *tail;
- };
- static void plist_free(plist *pl) {
- if (!pl) { return; }
- plist_free(pl->next), free(pl);
- }
- static void person_free(person *p) {
- if (!p) { return; }
- plist_free(p->friends), free(p->name), free(p);
- }
- static int plist_contains(plist *pl, person *p) {
- if (!pl) { return 0; }
- if (pl->data == p) { return 1; }
- return plist_contains(pl->next, p);
- }
- static pqueue *pqueue_alloc(void) {
- pqueue *new = calloc(sizeof(*new), 1);
- new->head = new->tail = NULL;
- return new;
- }
- static pqueue_data *pqueue_data_alloc(person *p, int hop) {
- pqueue_data *new = calloc(sizeof(*new), 1);
- new->person = p, new->hop = hop, new->next = NULL;
- return new;
- }
- static void pqueue_data_free(pqueue_data *p) {
- if (!p) { return; }
- pqueue_data_free(p->next), free(p);
- }
- static void pqueue_free(pqueue *q) {
- if (!q) { return; }
- pqueue_data_free(q->head), free(q);
- }
- static void pqueue_put(pqueue *q, person *p, int n) {
- pqueue_data *new = pqueue_data_alloc(p, n);
- if (!q->head) {
- q->head = q->tail = new;
- return;
- }
- q->tail->next = new, q->tail = new;
- }
- static int pqueue_get(pqueue *q, person **pp, int *np) {
- if (!q->head) { return 0; }
- *pp = q->head->person, *np = q->head->hop;
- if (q->head == q->tail) {
- pqueue_data_free(q->head), q->head = q->tail = NULL;
- } else {
- pqueue_data *p = q->head;
- q->head = p->next, p->next = NULL, pqueue_data_free(p);
- }
- return 1;
- }
- static int access_ok1(person *p1, person *p2, plist **visited, pqueue *q,
- int maxhop) {
- person *p;
- int hop;
- pqueue_put(q, p1, 0);
- while (pqueue_get(q, &p, &hop)) {
- plist_add(visited, p);
- if (maxhop < hop) { return 0; }
- if (plist_contains(p2->friends, p)) { return 1; }
- for (plist *pl = p->friends; pl; pl = pl->next) {
- person *f = pl->data;
- if (!plist_contains(*visited, f)) { pqueue_put(q, f, hop + 1); }
- }
- }
- return 0;
- }
- static int access_ok(person *p1, person *p2, int maxhop) {
- plist *visited = NULL;
- pqueue *q = pqueue_alloc();
- int result = access_ok1(p1, p2, &visited, q, maxhop);
- pqueue_free(q), plist_free(visited);
- return result;
- }
- int main(void) {
- person *alice = person_alloc("Alice"), *bob = person_alloc("Bob"),
- *carol = person_alloc("Carol"), *dave = person_alloc("Dave"),
- *ellen = person_alloc("Ellen"), *frank = person_alloc("Frank");
- become_friends(alice, bob), become_friends(alice, carol),
- become_friends(bob, dave), become_friends(carol, dave),
- become_friends(carol, ellen), become_friends(carol, frank),
- become_friends(dave, ellen), become_friends(ellen, frank);
- person *person_array[] = {alice, bob, carol, dave, ellen, frank};
- size_t size = sizeof(person_array) / sizeof(person_array[0]);
- { print_person(alice), print_person(bob), print_person(frank); }
- { print_common_friends(alice, frank); }
- {
- int c = 0;
- for (size_t hop = 0; hop < size; ++hop, c = 0) {
- printf("!%zd hop friend\n", hop);
- for (size_t i = 0; i < size; ++i) {
- for (size_t j = 0; j < size; ++j) {
- if (i == j) { continue; }
- if (access_ok(person_array[i], person_array[j], hop)) {
- printf(" %s --> %s\n", person_array[i]->name,
- person_array[j]->name);
- ++c;
- }
- }
- }
- if ((int)size * ((int)size - 1) <= c) { break; }
- }
- }
- {
- for (size_t i = 0; i < size; ++i) { person_free(person_array[i]); }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement