commit afed0e51bab7ba3f48e4bb0245639a0643c7debc Author: jacekpoz Date: Fri Mar 8 12:01:33 2024 +0100 z1 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e28cc9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*/.ccls-cache/ +*/target/ diff --git a/z1/.ccls b/z1/.ccls new file mode 100644 index 0000000..c02a542 --- /dev/null +++ b/z1/.ccls @@ -0,0 +1,20 @@ +gcc +%c -std=c99 +%h +-Wall +-Wextra +-Wpedantic +-Wstrict-aliasing +-Wfloat-equal +-Wundef +-Wshadow +-Wpointer-arith +-Wcast-align +-Wstrict-prototypes +-Wstrict-overflow=5 +-Wwrite-strings +-Wcast-qual +-Wswitch-default +-Wswitch-enum +-Wconversion +-Wunreachable-code diff --git a/z1/Makefile b/z1/Makefile new file mode 100644 index 0000000..d112c46 --- /dev/null +++ b/z1/Makefile @@ -0,0 +1,46 @@ +CC = gcc +CFLAGS = -std=c99 -O3 -Wall -Wextra -Wpedantic -Wstrict-aliasing +CFLAGS += -Wfloat-equal -Wundef -Wshadow -Wpointer-arith -Wcast-align +CFLAGS += -Wstrict-prototypes -Wstrict-overflow=5 -Wwrite-strings +CFLAGS += -Wcast-qual -Wswitch-default -Wswitch-enum +CFLAGS += -Wconversion -Wunreachable-code +CFLAGS += -Iinclude +LDFLAGS = + +NAME = z1 + +SRC = src +BIN = target + +_PROG = main.c +PROG = $(addprefix $(SRC)/, $(_PROG)) + +_LIB_ITER = mod_iter.c +LIB_ITER = $(addprefix $(SRC)/, $(_LIB_ITER)) + +_LIB_REC = mod_rec.c +LIB_REC = $(addprefix $(SRC)/, $(_LIB_REC)) + +OBJ = $(_PROG:.c=.o) +OBJ_ITER = $(_LIB_ITER:.c=.o) +OBJ_REC = $(_LIB_REC:.c=.o) + +.PHONY: all clean + +all: dirs iter rec + +dirs: + mkdir -p $(BIN) + +iter: $(OBJ) $(OBJ_ITER) + $(CC) $(addprefix $(BIN)/, $^) $(LDFLAGS) -o $(BIN)/$(NAME)_$@ + +rec: $(OBJ) $(OBJ_REC) + $(CC) $(addprefix $(BIN)/, $^) $(LDFLAGS) -o $(BIN)/$(NAME)_$@ + +%.o: src/%.c + $(CC) -c $< $(CFLAGS) -o $(BIN)/$@ + +clean: clean_modules + rm -rf $(addprefix $(BIN)/, $(OBJ)) + rm -rf $(BIN)/$(NAME) diff --git a/z1/include/mod.h b/z1/include/mod.h new file mode 100644 index 0000000..f8a651a --- /dev/null +++ b/z1/include/mod.h @@ -0,0 +1,17 @@ +#ifndef _JPP_L1_Z1_MOD_H +#define _JPP_L1_Z1_MOD_H + +#include + +uint64_t factorial(uint64_t n); + +uint64_t gcd(uint64_t a, uint64_t b); + +typedef struct { + int64_t n; + int64_t m; +} Result; + +Result *diophantine(int64_t a, int64_t b, int64_t c); + +#endif // _JPP_L1_Z1_MOD_H diff --git a/z1/src/main.c b/z1/src/main.c new file mode 100644 index 0000000..26a7673 --- /dev/null +++ b/z1/src/main.c @@ -0,0 +1,20 @@ +#include "mod.h" + +#include +#include + +int main(int argc, char *argv[]) { + if (argc != 4) { + fprintf(stderr, "usage: %s \n", argv[0]); + exit(EXIT_FAILURE); + } + printf("gcd(a, b): %lu\n", gcd(atol(argv[1]), atol(argv[2]))); + printf("factorial(a): %lu\n", factorial(atol(argv[1]))); + Result *r = diophantine(atol(argv[1]), atol(argv[2]), atol(argv[3])); + if (r == NULL) + printf("dupa\n"); + else + printf("diophantine(a, b, c): %ld, %ld\n", r->n, r->m); + + return 0; +} diff --git a/z1/src/mod_iter.c b/z1/src/mod_iter.c new file mode 100644 index 0000000..731d446 --- /dev/null +++ b/z1/src/mod_iter.c @@ -0,0 +1,75 @@ +#include "mod.h" + +#include +#include + +uint64_t factorial(uint64_t n) { + uint64_t result = 1; + + for (size_t i = 1; i <= n; ++i) { + result *= i; + } + + return result; +} + +uint64_t gcd(uint64_t a, uint64_t b) { + if (a == 0) return b; + + size_t r; + + while (b > 0) { + r = a % b; + + a = b; + b = r; + } + + return a; +} + +inline int64_t extended_gcd(int64_t a, int64_t b, int64_t *x, int64_t *y) { + *x = 1; + *y = 0; + int64_t x1 = 0; + int64_t y1 = 1; + int64_t q; + int64_t temp_x, temp_y, temp_b; + while (b != 0) { + q = a / b; + + temp_x = *x - q * x1; + temp_y = *y - q * y1; + *x = x1; + *y = y1; + x1 = temp_x; + y1 = temp_y; + + temp_b = a - q * b; + a = b; + b = temp_b; + } + + return a; +} + +Result *diophantine(int64_t a, int64_t b, int64_t c) { + if (a == 0 && b == 0) + return NULL; + int64_t x0 = 0; + int64_t y0 = 0; + int64_t g = extended_gcd(labs(a), labs(b), &x0, &y0); + + if (c % g) + return NULL; + + x0 *= c / g; + y0 *= c / g; + if (a < 0) x0 = -x0; + if (b < 0) y0 = -y0; + Result *r = malloc(sizeof(Result)); + r->n = x0; + r->m = y0; + + return r; +} diff --git a/z1/src/mod_rec.c b/z1/src/mod_rec.c new file mode 100644 index 0000000..34914f1 --- /dev/null +++ b/z1/src/mod_rec.c @@ -0,0 +1,56 @@ +#include "mod.h" + +#include +#include +#include +#include + +uint64_t factorial(uint64_t n) { + if (n == 0 || n == 1) { + return 1; + } + + return n * factorial(n - 1); +} + +uint64_t gcd(uint64_t a, uint64_t b) { + if (b == 0) { + return a; + } + + return gcd(b, a % b); +} + +inline int64_t extended_gcd(int64_t a, int64_t b, int64_t *x, int64_t *y) { + if (b == 0) { + *x = 1; + *y = 0; + return a; + } + int64_t x1, y1; + int64_t d = extended_gcd(b, a % b, &x1, &y1); + *x = y1; + *y = x1 - y1 * (a / b); + return d; +} + +Result *diophantine(int64_t a, int64_t b, int64_t c) { + if (a == 0 && b == 0) + return NULL; + int64_t x0 = 0; + int64_t y0 = 0; + int64_t g = extended_gcd(labs(a), labs(b), &x0, &y0); + + if (c % g) + return NULL; + + x0 *= c / g; + y0 *= c / g; + if (a < 0) x0 = -x0; + if (b < 0) y0 = -y0; + Result *r = malloc(sizeof(Result)); + r->n = x0; + r->m = y0; + + return r; +}