Prechádzať zdrojové kódy

[C][12] Adding solution ultra bruteforce solution

Vinicius Teshima 10 mesiacov pred
rodič
commit
53f7546882
1 zmenil súbory, kde vykonal 92 pridanie a 5 odobranie
  1. 92 5
      c/src/0012.c

+ 92 - 5
c/src/0012.c

@@ -3,17 +3,73 @@
 #include <stdint.h>
 #include <stdbool.h>
 #include <string.h>
+#include <pthread.h>
+
+#define NUM_THREADS 28
 
 uint64_t num_of_div(uint64_t num);
 
+struct check_div {
+	uint64_t *nums;
+	uint64_t size;
+	uint64_t cap;
+};
+struct check_div_ret {
+	uint64_t num;
+	uint64_t div;
+};
+void *check_div_thread(void *data);
+
 int
 main(int argc, const char **argv)
 {
-	uint64_t res = 1;
+	uint64_t res = UINT64_MAX;
+	uint64_t tri_num = 1;
 	uint64_t i = 2;
+	uint64_t j = 0;
+	pthread_t thrds[NUM_THREADS + 1] = {0};
+	uint64_t thrds_size = 0;
+
+	while ( res == UINT64_MAX ) {
+		struct check_div *data = NULL;
+		data = calloc(1, sizeof(*data));
+		data->cap = 100;
+		data->nums = calloc(data->cap + 2, sizeof(uint64_t));
+		data->size = 0;
+
+		while ( data->size < data->cap ) {
+			data->nums[data->size++] = tri_num;
+			tri_num += i++;
+		}
+
+		pthread_create(&thrds[thrds_size++], NULL,
+				check_div_thread, (void *)data);
 
-	while ( num_of_div(res) > 500 ) {
-		res += i++;
+		if ( thrds_size < NUM_THREADS ) {
+			continue;
+		}
+
+		for ( j = 0; j < thrds_size; ++j ) {
+			struct check_div_ret *ret = NULL;
+			/* printf("Waiting for thread index: %ld\n", j); */
+			pthread_join(thrds[j], (void **)&ret);
+			if ( ret == NULL ) {
+				fprintf(stderr, "Thread did not return value");
+				exit(1);
+			}
+			printf("Got Result: %ld divs: %ld\n", ret->num, ret->div);
+			if ( ret->div > 500 ) {
+				if ( ret->num < res ) {
+					res = ret->num;
+				}
+			}
+			free(ret);
+		}
+		
+		thrds_size = 0;
+	}
+	for ( ; j < thrds_size; ++j ) {
+		pthread_cancel(thrds[j]);
 	}
 
 	printf("Result = %ld!\n", res);
@@ -22,15 +78,46 @@ main(int argc, const char **argv)
 	return 0;
 }
 
+void *
+check_div_thread(void *data)
+{
+	struct check_div d = *((struct check_div *)data);
+	struct check_div_ret *ret = NULL;
+	uint64_t num = 0;
+	uint64_t i = 0;
+	uint64_t div = 0;
+	uint64_t max_div = 0;
+
+	for ( i = 0; i < d.size && max_div < 500; ++i ) {
+		num = d.nums[i];
+		div = num_of_div(num);
+		if ( div > max_div ) {
+			max_div = div;
+		}
+	}
+
+	free(((struct check_div *)data)->nums);
+	free(data);
+
+	ret = calloc(1, sizeof(struct check_div_ret));
+
+	ret->num = num;
+	ret->div = div;
+	/* printf("Returning num: %ld, div: %ld\n", num, div); */
+
+	return (void*) ret;
+}
+
 uint64_t
 num_of_div(uint64_t num)
 {
 	uint64_t nod = 0;
-	uint64_t i = 0;
+	uint64_t i = 1;
 
-	for ( i = 0; i < num; ++i ) {
+	for ( i = 1; i < num; ++i ) {
 		nod += (num % i == 0);
 	}
 
 	return nod;
 }
+