Files
sosito/T1/suma.c
2026-03-24 15:51:42 -03:00

91 lines
1.8 KiB
C

#include <limits.h>
#include <pthread.h>
#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;
}