#include #include #include "suma.h" enum { NTHREADS = 8 }; typedef struct { int *a; int n; Set start; Set end; Set found; } BuscarArgs; static Set total_combinaciones(int n) { if (n >= (int)(sizeof(Set) * CHAR_BIT)) return ~(Set)0; return ((Set)1 << n) - 1; } static Set buscar_rango(int a[], int n, Set start, Set end) { if (start == 0 || start > end) return 0; Set k = start; while (1) { long long sum = 0; for (int i = 0; i < n; i++) { if (k & ((Set)1 << i)) sum += a[i]; } if (sum == 0) return k; if (k == end) break; k++; } return 0; } static void *buscar_thread(void *ptr) { BuscarArgs *args = ptr; args->found = buscar_rango(args->a, args->n, args->start, args->end); return NULL; } Set buscar(int a[], int n) { Set comb = total_combinaciones(n); Set base = comb / NTHREADS; Set extra = comb % NTHREADS; Set next = 1; pthread_t tids[NTHREADS]; BuscarArgs args[NTHREADS]; int created = 0; for (int t = 0; t < NTHREADS; t++) { Set len = base + (Set)(t < (int)extra); args[t].a = a; args[t].n = n; args[t].start = next; args[t].end = (len == 0) ? next - 1 : (t == NTHREADS - 1 ? comb : next + len - 1); args[t].found = 0; if (len != 0) next = args[t].end + 1; if (pthread_create(&tids[t], NULL, buscar_thread, &args[t]) != 0) { for (int i = 0; i < created; i++) pthread_join(tids[i], NULL); return buscar_rango(a, n, 1, comb); } created++; } Set best = 0; for (int t = 0; t < NTHREADS; t++) { pthread_join(tids[t], NULL); if (args[t].found != 0 && (best == 0 || args[t].found < best)) best = args[t].found; } return best; }