Procházet zdrojové kódy

[C] Adding solution for problem 0003

Vinicius Teshima před 1 rokem
rodič
revize
c522f50d32
4 změnil soubory, kde provedl 116 přidání a 4 odebrání
  1. 2 1
      c/.gitignore
  2. 100 0
      c/0003.c
  3. 8 3
      c/Makefile
  4. 6 0
      c/Project.ede

+ 2 - 1
c/.gitignore

@@ -3,4 +3,5 @@
 
 # Executables
 0001
-0002
+0002
+0003

+ 100 - 0
c/0003.c

@@ -0,0 +1,100 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+struct primes_da {
+	uint64_t *data;
+	uint64_t size;
+	uint64_t cap;
+};
+
+
+bool isprime(struct primes_da *primes, uint64_t n);
+void primes_fill(struct primes_da *primes);
+
+int
+main(int argc, const char **argv)
+{
+	uint64_t res = 0;
+	uint64_t i = 0;
+	uint64_t target = 600851475143;
+	uint64_t prime = 0;
+	ldiv_t dm = {0};
+	struct primes_da primes = {0};
+
+	primes.cap = 256;
+	primes.data = calloc(primes.cap, sizeof(uint64_t));
+	primes.size = 0;
+
+	primes_fill(&primes);
+
+	while ( i < target ) {
+		if ( i >= primes.size ) {
+			primes.cap = primes.cap * 2;
+			primes.data = realloc(primes.data,
+					      primes.cap * sizeof(uint64_t));
+			primes_fill(&primes);
+		}
+		prime = primes.data[i];
+		dm = ldiv((int64_t)target, (int64_t)prime);
+		if ( isprime(&primes, (uint64_t)dm.quot) ) {
+			if ( prime > res ) {
+				res = prime;
+			}
+		}
+		if ( dm.rem != 0 ) {
+			++i;
+			continue;
+		}
+		if ( prime > res ) {
+			res = prime;
+		}
+		target = (uint64_t)dm.quot;
+	}
+
+	printf("Result = %ld!\n", res);
+	(void) argc; (void) argv;
+	return 0;
+}
+
+bool
+isprime(struct primes_da *primes, uint64_t n)
+{
+	uint64_t i = 0;
+	if ( (n & 1) == 0 ) {
+		return false;
+	}
+
+	if ( primes != NULL ) {
+		if ( n < primes->data[primes->size-1] ) {
+			for ( i = 0; i < primes->size; ++i ) {
+				if ( n == primes->data[i] ) {
+					return true;
+				}
+			}
+			return false;
+		}
+	}
+
+	for ( i = 2; i < n; ++i ) {
+		if ( (n % i) == 0 ) {
+			return false;
+		}
+	}
+	return true;
+}
+
+void
+primes_fill(struct primes_da *primes)
+{
+	uint64_t i = primes->size;
+	if ( i == 0 ) {
+		i = 2;
+	}
+	for ( ; primes->size < primes->cap; ++i ) {
+		if ( isprime(NULL, i) ) {
+			primes->data[primes->size++] = i;
+		}
+	}
+}

+ 8 - 3
c/Makefile

@@ -19,13 +19,15 @@ C_DEPENDENCIES=-Wp,-MD,.deps/$(*F).P
 C_LINK=$(CC) $(CFLAGS) $(LDFLAGS) -L.
 0002_SOURCES=0002.c
 0002_OBJ= 0002.o
+0003_SOURCES=0003.c
+0003_OBJ= 0003.o
 VERSION=1.0
 DISTDIR=$(top)ProjectEuler_C-$(VERSION)
 top_builddir = 
 
-DEP_FILES=.deps/0001.P .deps/0002.P
+DEP_FILES=.deps/0001.P .deps/0002.P .deps/0003.P
 
-all: 0001 0002
+all: 0001 0002 0003
 
 DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
 -include $(DEP_FILES)
@@ -40,6 +42,9 @@ DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
 0002: $(0002_OBJ)
 	$(C_LINK) -o $@ $^ $(LDDEPS)
 
+0003: $(0003_OBJ)
+	$(C_LINK) -o $@ $^ $(LDDEPS)
+
 tags: 
 
 
@@ -50,7 +55,7 @@ clean:
 
 dist:
 	mkdir $(DISTDIR)
-	cp $(0001_SOURCES) $(0002_SOURCES) $(ede_FILES) $(DISTDIR)
+	cp $(0001_SOURCES) $(0002_SOURCES) $(0003_SOURCES) $(ede_FILES) $(DISTDIR)
 
 Makefile: Project.ede
 	@echo Makefile is out of date!  It needs to be regenerated by EDE.

+ 6 - 0
c/Project.ede

@@ -16,6 +16,12 @@
       :name "0002"
       :path ""
       :source '("0002.c")
+      :configuration-variables '("debug" ("CFLAGS" . "-g") ("LDFLAGS" . "-g")))
+    (ede-proj-target-makefile-program "0003"
+      :object-name "0003"
+      :name "0003"
+      :path ""
+      :source '("0003.c")
       :configuration-variables '("debug" ("CFLAGS" . "-g") ("LDFLAGS" . "-g"))))
   :configurations '("debug" "release")
   :object-name "ProjectEuler_C"