File: netconnections.c - Tab length: 1 2 4 8 - Lines: on off - No wrap: on off

01: #include <stdio.h>
02: #include <stdlib.h>
03: 
04: struct  Config { unsigned int machine, network, next, size; };
05: 
06: #define setMachine(m, n, x) ({ struct Config* p = (m); p->network = (n); p->next = (x); })
07: #define setNetwork(n, m, s) ({ struct Config* p = (n); p->machine = (m); p->size = (s); })
08: 
09: void    exec_command (struct Config* configs, unsigned int m1, unsigned int m2, unsigned int* unique)
10: {
11:     struct Config*  machine;
12:     unsigned int    n1 = configs[m1 - 1].network, n2 = configs[m2 - 1].network;
13: 
14:     if (n1 == 0)
15:     {
16:         if (n2 != 0)
17:         {
18:             setMachine (&configs[m1 - 1], n2, configs[n2 - 1].machine);
19:             setNetwork (&configs[n2 - 1], m1, configs[n2 - 1].size + 1);
20:         }
21:         else if (m1 != m2)
22:         {
23:             setMachine (&configs[m1 - 1], (n1 = ++(*unique)), m2);
24:             setMachine (&configs[m2 - 1], n1, 0);
25:             setNetwork (&configs[n1 - 1], m1, 2);
26:         }
27:     }
28:     else if (n2 == 0)
29:     {
30:         setMachine (&configs[m2 - 1], n1, configs[n1 - 1].machine);
31:         setNetwork (&configs[n1 - 1], m2, configs[n1 - 1].size + 1);
32:     }
33:     else if (n1 != n2)
34:     {
35:         if (configs[n1 - 1].size > configs[n2 - 1].size)
36:             n1 ^= n2 ^= n1 ^= n2;
37: 
38:         for (machine = &configs[configs[n1 - 1].machine - 1]; machine->next; machine = &configs[machine->next - 1])
39:             machine->network = n2;
40: 
41:         setMachine (machine, n2, configs[n2 - 1].machine);
42:         setNetwork (&configs[n2 - 1], configs[n1 - 1].machine, configs[n2 - 1].size + configs[n1 - 1].size);
43:     }
44: }
45: 
46: int exec_query (const struct Config* configs, unsigned int m1, unsigned int m2)
47: {
48:     return configs[m1 - 1].network == 0 ? m1 == m2 : configs[m1 - 1].network == configs[m2 - 1].network;
49: }
50: 
51: char    read_char (char* buffer, unsigned int length, unsigned int* offset)
52: {
53:     while (*offset < length && buffer[*offset] <= ' ')
54:         ++(*offset);
55: 
56:     return *offset < length ? buffer[(*offset)++] : '\0';
57: }
58: 
59: unsigned int    read_uint (char* buffer, unsigned int length, unsigned int* offset)
60: {
61:     unsigned int    value = 0;
62: 
63:     for (; *offset < length && ((value == 0 && buffer[*offset] <= ' ') || (buffer[*offset] >= '0' && buffer[*offset] <= '9')); ++(*offset))
64:         value = (buffer[*offset] <= ' ') ? value : (value * 10 + buffer[*offset] - '0');
65: 
66:     return value;
67: }
68: 
69: int main (int argc, char* argv[])
70: {
71:     struct Config*  configs;
72:     FILE*           file = fopen (argv[1], "r");
73:     unsigned int    length, m1, offset = 0, unique = 0, query[2] = {0, 0};
74:     char*           buffer, type;
75: 
76:     length = !fseek (file, 0, SEEK_END) ? ftell (file) : 0;
77:     buffer = (char*)malloc (length * sizeof (*buffer));
78:     fseek (file, 0, SEEK_SET);
79:     fread (buffer, sizeof (*buffer), length, file);
80: 
81:     for (configs = (struct Config*)calloc (read_uint (buffer, length, &offset), sizeof (*configs)); (type = read_char (buffer, length, &offset)) != '\0'; )
82:     {
83:         m1 = read_uint (buffer, length, &offset);
84: 
85:         if (type == 'c')
86:             exec_command (configs, m1, read_uint (buffer, length, &offset), &unique);
87:         else
88:             ++query[!exec_query (configs, m1, read_uint (buffer, length, &offset))];
89:     }
90: 
91:     printf ("%u,%u\n", query[0], query[1]);
92: 
93:     return 0;
94: }