From 595837a4ac15c3ed9683dcaeb128fd407820d9f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20=C5=A0tefka?= Date: Sun, 10 Dec 2023 00:49:37 +0100 Subject: [PATCH] feat(2023): remove code for new year --- 01/.vimspector.json | 39 ------ 01/Makefile | 90 ------------ 01/src/main.c | 246 --------------------------------- 01/tests/calories_test.dat | 14 -- 02/.vimspector.json | 39 ------ 02/Makefile | 91 ------------- 02/src/main.c | 271 ------------------------------------- 02/tests/guide.dat | 4 - 03/.vimspector.json | 39 ------ 03/Makefile | 91 ------------- 03/src/main.c | 271 ------------------------------------- 03/tests/rucksacks.dat | 6 - README.md | 4 + 13 files changed, 4 insertions(+), 1201 deletions(-) delete mode 100644 01/.vimspector.json delete mode 100644 01/Makefile delete mode 100644 01/src/main.c delete mode 100644 01/tests/calories_test.dat delete mode 100644 02/.vimspector.json delete mode 100644 02/Makefile delete mode 100644 02/src/main.c delete mode 100644 02/tests/guide.dat delete mode 100644 03/.vimspector.json delete mode 100644 03/Makefile delete mode 100644 03/src/main.c delete mode 100644 03/tests/rucksacks.dat diff --git a/01/.vimspector.json b/01/.vimspector.json deleted file mode 100644 index c8baba7..0000000 --- a/01/.vimspector.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "configurations": { - "Launch": { - "adapter": "vscode-cpptools", - "filetypes": [ "cpp", "c", "objc", "rust" ], // optional - "configuration": { - "request": "launch", - "program": "${workspaceRoot}/output/main", - "args": [ "${workspaceRoot}/tests/calories_test.dat"], - "cwd": "${workspaceRoot}/output", - //"environment": [ ... ], - "externalConsole": true, - "MIMode": "gdb" - } - }, - "Attach": { - "adapter": "vscode-cpptools", - "filetypes": [ "cpp", "c", "objc", "rust" ], // optional - "configuration": { - "request": "attach", - "program": "${workspaceRoot}/output/main", - "MIMode": "gdb" - } - }, - "Launch prod": { - "adapter": "vscode-cpptools", - "filetypes": [ "cpp", "c", "objc", "rust" ], // optional - "configuration": { - "request": "launch", - "program": "${workspaceRoot}/output/main", - "args": [ "calories.dat"], - "cwd": "${workspaceRoot}/output", - //"environment": [ ... ], - "externalConsole": true, - "MIMode": "gdb" - } - } - } -} diff --git a/01/Makefile b/01/Makefile deleted file mode 100644 index 3fb8222..0000000 --- a/01/Makefile +++ /dev/null @@ -1,90 +0,0 @@ -# -# 'make' build executable file 'main' -# 'make clean' removes all .o and executable files -# - -# define the C compiler to use CC = gcc - -# define any compile-time flags -CFLAGS := -std=c99 -Wall -Wextra -g - -# define library paths in addition to /usr/lib -# if I wanted to include libraries not in /usr/lib I'd specify -# their path using -Lpath, something like: -LFLAGS = - -# define output directory -OUTPUT := output - -# define source directory -SRC := src - -# define include directory -INCLUDE := include - -# define lib directory -LIB := lib - -ifeq ($(OS),Windows_NT) -MAIN := main.exe -SOURCEDIRS := $(SRC) -INCLUDEDIRS := $(INCLUDE) -LIBDIRS := $(LIB) -FIXPATH = $(subst /,\,$1) -RM := del /q /f -MD := mkdir -else -MAIN := main -SOURCEDIRS := $(shell find $(SRC) -type d) -INCLUDEDIRS := $(shell find $(INCLUDE) -type d) -LIBDIRS := $(shell find $(LIB) -type d) -FIXPATH = $1 -RM = rm -f -MD := mkdir -p -endif - -# define any directories containing header files other than /usr/include -INCLUDES := $(patsubst %,-I%, $(INCLUDEDIRS:%/=%)) - -# define the C libs -LIBS := $(patsubst %,-L%, $(LIBDIRS:%/=%)) - -# define the C source files -SOURCES := $(wildcard $(patsubst %,%/*.c, $(SOURCEDIRS))) - -# define the C object files -OBJECTS := $(SOURCES:.c=.o) - -# -# The following part of the makefile is generic; it can be used to -# build any executable just by changing the definitions above and by -# deleting dependencies appended to the file from 'make depend' -# - -OUTPUTMAIN := $(call FIXPATH,$(OUTPUT)/$(MAIN)) - -all: $(OUTPUT) $(MAIN) - @echo Executing 'all' complete! - -$(OUTPUT): - $(MD) $(OUTPUT) - -$(MAIN): $(OBJECTS) - $(CC) $(INCLUDES) $(OBJECTS) $(LFLAGS) $(LIBS) -o $(OUTPUTMAIN) $(CFLAGS) - -# this is a suffix replacement rule for building .o's from .c's -# it uses automatic variables $<: the name of the prerequisite of -# the rule(a .c file) and $@: the name of the target of the rule (a .o file) -# (see the gnu make manual section about automatic variables) -.c.o: - $(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@ - -.PHONY: clean -clean: - $(RM) $(OUTPUTMAIN) - $(RM) $(call FIXPATH,$(OBJECTS)) - @echo Cleanup complete! - -run: all - ./$(OUTPUTMAIN) - @echo Executing 'run: all' complete! diff --git a/01/src/main.c b/01/src/main.c deleted file mode 100644 index 2cfd480..0000000 --- a/01/src/main.c +++ /dev/null @@ -1,246 +0,0 @@ -#include -#include -#include -#include - -struct elf { - int size; - int *calories; -}; - -// Gets the number of elves in the input file. -int get_num_of_elves(const char *fileName) { - // Max line length - char line[300]; - // Stores the number of empty lines (elves) - int emptyLine = 0; - // Open the file - FILE *fp = fopen(fileName, "r"); - - // Check if the file opened successfully - if (fp == NULL) { - printf("Error: Could not open specified file!\n"); - return -1; - } - - // Read the file and count blank lines - while (fgets(line, 300, fp)) { - int i = 0; - int len = strlen(line); - emptyLine++; - for (i = 0; i < len; i++) { - if (line[i] != '\n' && line[i] != '\t' && line[i] != ' ') { - emptyLine--; - break; - } - } - } - // Check if the last line in the file is empty - if (line[0] == '\n') { - emptyLine--; - } - - // Close the file - fclose(fp); - - // Return the number of elves (one elf won't be counted if there is a blank line at the end of the file) - return ++emptyLine; -} - -/* - * Loads the elve's carried calories from the input file. - * Params: - * - int num_of_elves: The number of elves in the input file. - * - const char *fileName: The name of the input file. - * - struct elf *elves: The array of elves to store the data in. - */ -void load_data(int num_of_elves, char *filename, struct elf **arr) { - // Open the file - FILE *fp = fopen(filename, "r"); - - // Check if the file opened successfully - if (fp == NULL) { - printf("Error: Could not open specified file!\n"); - return; - } - - // Go through each elf - for (int i = 0; i < num_of_elves; i++) { - // Count number of lines until blank line - int num_of_lines = 0; - // Stores the current line (max length 300) - char line[300]; - /* - * NOTE: The code below is used to get the number of items does the elf have - * so that the memory can be allocated corretly. But then wee need to go back - * to the start of the elve's data and we need the number of characters we read - * to do that - */ - // Counts the number of characters - int char_count = 0; - - // Go through the elve's data - while (fgets(line, 300, fp)) { - // Length of the current line - int len = strlen(line); - // Update character count - char_count += len; - - // Go through the line until a new line character is found - for (int i = 0; i < len; i++) { - if (line[i] != '\n' && line[i] != '\t' && line[i] != ' ') { - num_of_lines++; - break; - } - } - // Check if the line is empty - if (line[0] == '\n') { - break; - } - } - - // Check for blank line at EOF (or you'll get an infinit loop if the last line is blank LOL) - if (line[0] == EOF) { - break; - } - - // If the line is empty, go back to the start of the next elve - if (num_of_lines == 0) { - i--; - continue; - } - - // Go back to start of current elf's data - fseek(fp, -char_count, SEEK_CUR); - - // Reference the array - struct elf *data = *arr; - // Allocate memory for array - data[i].calories = malloc(num_of_lines * sizeof(int)); - // Remember how many calories are stored - data[i].size = num_of_lines; - - // Load the data - for (int j = 0; j < num_of_lines; j++) { - // Read the line ans add the calories to the correct elf in the array - int res = fscanf(fp, "%d", &data[i].calories[j]); - // Check if the line has the correct formatting - if (res != 1) { - printf("Error, bad file format!"); - return; - } - } - } - - // Close the file - fclose(fp); -} - -// Count all the calories each elf has -// Params: -// - int num_of_elves: The number of elves in the input file. -// - struct elf *elves: The array with the data. -void count_elf_calories(struct elf **arr, int num_of_elves) { - // Reference the array - struct elf *data = *arr; - - // Go through each elf - for (int i = 0; i < num_of_elves; i++) { - // Sum of the callories for the current elf - int sum = 0; - - // Go through the elve's calories - for (int j = 0; j < data[i].size; j++) { - // Add the calories to the sum - sum += data[i].calories[j]; - // Remove the callories and decrease the stored calories number - data[i].calories[j] = 0; - } - // Set the sum to indes 0 - data[i].calories[0] = sum; - data[i].size = 1; - } -} - -// Argument parser -char *argv_parser(int argc, char *argv[]) { - // This program has only one argument - if (argc != 2) { - fprintf(stderr, "Usage: %s \n", argv[0]); - return NULL; - } - - // Return the argument as pos 1 (the filename) - return argv[1]; -} - -int main(int argc, char *argv[]) { - // The array of elves - struct elf *arr; - // Get the filename - char *filename = argv_parser(argc, argv); - - // Get the number of elves in the file - int num_of_elves = get_num_of_elves(filename); - // Check if the operation was successful - if (num_of_elves == -1) { - return 1; - } - - // Alocate the memory for the array - arr = malloc(num_of_elves * sizeof(struct elf)); - - // Load all the elve's calorias - load_data(num_of_elves, filename, &arr); - - // Count all the calories each elf has - count_elf_calories(&arr, num_of_elves); - - // Get 3 elves with the most calories - int first_elf_cal = 0; - int first_elf_idx = 0; - int second_elf_cal = 0; - int second_elf_idx = 0; - int third_elf_cal = 0; - int third_elf_idx = 0; - for (int i = 0; i < num_of_elves; i++) { - // If the elf has more calories than others, move the other elves down - if (arr[i].calories[0] > first_elf_cal) { - third_elf_cal = second_elf_cal; - third_elf_idx = second_elf_idx; - second_elf_cal = first_elf_cal; - second_elf_idx = first_elf_idx; - first_elf_cal = arr[i].calories[0]; - first_elf_idx = i; - } else if (arr[i].calories[0] > second_elf_cal) { - third_elf_cal = second_elf_cal; - third_elf_idx = second_elf_idx; - second_elf_cal = arr[i].calories[0]; - second_elf_idx = i; - } else if (arr[i].calories[0] > third_elf_cal) { - third_elf_cal = arr[i].calories[0]; - third_elf_idx = i; - } - } - - // Print out the 3 elves with the most calories - printf("Elf %d carries the most calories at %d calories\n", first_elf_idx, - first_elf_cal); - printf("Elf %d carries the second most calories at %d calories\n", - second_elf_idx, second_elf_cal); - printf("Elf %d carries the third most calories at %d calories\n", - third_elf_idx, third_elf_cal); - - // Print the top 3 elves with the most calories - printf("The top 3 elves carry %d calories\n", - first_elf_cal + second_elf_cal + third_elf_cal); - - // Free memory - for (int i = 0; i < num_of_elves; i++) { - free(arr[i].calories); - } - // Free the array - free(arr); - - return 0; -} diff --git a/01/tests/calories_test.dat b/01/tests/calories_test.dat deleted file mode 100644 index 2094f91..0000000 --- a/01/tests/calories_test.dat +++ /dev/null @@ -1,14 +0,0 @@ -1000 -2000 -3000 - -4000 - -5000 -6000 - -7000 -8000 -9000 - -10000 diff --git a/02/.vimspector.json b/02/.vimspector.json deleted file mode 100644 index 740d8c3..0000000 --- a/02/.vimspector.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "configurations": { - "Launch": { - "adapter": "vscode-cpptools", - "filetypes": [ "cpp", "c", "objc", "rust" ], // optional - "configuration": { - "request": "launch", - "program": "${workspaceRoot}/output/main", - "args": [ "${workspaceRoot}/tests/guide.dat", "2" ], - "cwd": "${workspaceRoot}/output", - //"environment": [ ... ], - "externalConsole": true, - "MIMode": "gdb" - } - }, - "Attach": { - "adapter": "vscode-cpptools", - "filetypes": [ "cpp", "c", "objc", "rust" ], // optional - "configuration": { - "request": "attach", - "program": "${workspaceRoot}/output/main", - "MIMode": "gdb" - } - }, - "Launch prod": { - "adapter": "vscode-cpptools", - "filetypes": [ "cpp", "c", "objc", "rust" ], // optional - "configuration": { - "request": "launch", - "program": "${workspaceRoot}/output/main", - "args": [ "guide.dat", "2" ], - "cwd": "${workspaceRoot}/output", - //"environment": [ ... ], - "externalConsole": true, - "MIMode": "gdb" - } - } - } -} diff --git a/02/Makefile b/02/Makefile deleted file mode 100644 index 3f27a58..0000000 --- a/02/Makefile +++ /dev/null @@ -1,91 +0,0 @@ -# -# 'make' build executable file 'main' -# 'make clean' removes all .o and executable files -# - -# define the C compiler to use CC = gcc - -# define any compile-time flags -# CFLAGS := -std=c99 -Wall -Wextra -g -lm -CFLAGS := -std=c99 -Wall -Wextra -g - -# define library paths in addition to /usr/lib -# if I wanted to include libraries not in /usr/lib I'd specify -# their path using -Lpath, something like: -LFLAGS = - -# define output directory -OUTPUT := output - -# define source directory -SRC := src - -# define include directory -INCLUDE := include - -# define lib directory -LIB := lib - -ifeq ($(OS),Windows_NT) -MAIN := main.exe -SOURCEDIRS := $(SRC) -INCLUDEDIRS := $(INCLUDE) -LIBDIRS := $(LIB) -FIXPATH = $(subst /,\,$1) -RM := del /q /f -MD := mkdir -else -MAIN := main -SOURCEDIRS := $(shell find $(SRC) -type d) -INCLUDEDIRS := $(shell find $(INCLUDE) -type d) -LIBDIRS := $(shell find $(LIB) -type d) -FIXPATH = $1 -RM = rm -f -MD := mkdir -p -endif - -# define any directories containing header files other than /usr/include -INCLUDES := $(patsubst %,-I%, $(INCLUDEDIRS:%/=%)) - -# define the C libs -LIBS := $(patsubst %,-L%, $(LIBDIRS:%/=%)) - -# define the C source files -SOURCES := $(wildcard $(patsubst %,%/*.c, $(SOURCEDIRS))) - -# define the C object files -OBJECTS := $(SOURCES:.c=.o) - -# -# The following part of the makefile is generic; it can be used to -# build any executable just by changing the definitions above and by -# deleting dependencies appended to the file from 'make depend' -# - -OUTPUTMAIN := $(call FIXPATH,$(OUTPUT)/$(MAIN)) - -all: $(OUTPUT) $(MAIN) - @echo Executing 'all' complete! - -$(OUTPUT): - $(MD) $(OUTPUT) - -$(MAIN): $(OBJECTS) - $(CC) $(INCLUDES) $(OBJECTS) $(LFLAGS) $(LIBS) -o $(OUTPUTMAIN) $(CFLAGS) - -# this is a suffix replacement rule for building .o's from .c's -# it uses automatic variables $<: the name of the prerequisite of -# the rule(a .c file) and $@: the name of the target of the rule (a .o file) -# (see the gnu make manual section about automatic variables) -.c.o: - $(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@ - -.PHONY: clean -clean: - $(RM) $(OUTPUTMAIN) - $(RM) $(call FIXPATH,$(OBJECTS)) - @echo Cleanup complete! - -run: all - ./$(OUTPUTMAIN) - @echo Executing 'run: all' complete! diff --git a/02/src/main.c b/02/src/main.c deleted file mode 100644 index cdb039f..0000000 --- a/02/src/main.c +++ /dev/null @@ -1,271 +0,0 @@ -#include -#include - -/* Error codes: - * 0 - no error - * 1 - invalid number of arguments - * 2 - invalid file - * 3 - invalid file format - * 4 - invalid solution part - */ - -/* NOTE: info to remember: - * The aliases for rock, paper, scissors are: - * - A = X = rock - * - B = Y = paper - * - C = Z = scissors - * ------------------------------------------ - * Scores: - * - Shape - * - Rock: 1 - * - Paper: 2 - * - Scissors: 3 - * - Outcome - * - Win: 6 - * - Draw: 3 - * - Loss: 0 - */ - -int arg_parser(int argc, char *argv[], char **file_name, int *solution_part) { - if (argc != 3) { - printf("Usage: %s \n", argv[0]); - return 1; - } - // Check if the file exists - FILE *file = fopen(argv[1], "r"); - if (file == NULL) { - printf("Error: File does not exist.\n"); - return 2; - } - fclose(file); - - // Check if the solution part is a valid number - if (atoi(argv[2]) != 1 && atoi(argv[2]) != 2) { - printf("Error: Invalid solution part.\nValid values are [1, 2]\n"); - return 4; - } - - *file_name = argv[1]; - *solution_part = atoi(argv[2]); - - return 0; -} - -// Returns the score of the given shape -// 1 = rock, 2 = paper, 3 = scissors -int score_shapes(char shape) { - switch (shape) { - case 'A': - case 'X': - return 1; - case 'B': - case 'Y': - return 2; - case 'C': - case 'Z': - return 3; - default: - return -1; - } -} - -/* Returns my score for the round - * - * Parameters: - * - opponents_shape - * - A = rock - * - B = paper - * - C = scissors - * - my_shape - * - X = rock - * - Y = paper - * - Z = scissors - */ -int round_score(char opponents_shape, char my_shape) { - // Checks if the shapes are valid and get their scores - int opponents_score = score_shapes(opponents_shape); - int shape_score = score_shapes(my_shape); - if (opponents_score == -1 || shape_score == -1) { - printf("Error: Invalid shape.\n"); - return -1; - } - - // Draw - if (opponents_shape == 'A' && my_shape == 'X') { - return 3 + shape_score; - } else if (opponents_shape == 'B' && my_shape == 'Y') { - return 3 + shape_score; - } else if (opponents_shape == 'C' && my_shape == 'Z') { - return 3 + shape_score; - } - - // Rock win - else if (my_shape == 'X' && opponents_shape == 'C') { - return 6 + shape_score; - } - // Paper win - else if (my_shape == 'Y' && opponents_shape == 'A') { - return 6 + shape_score; - } // Scissors win - else if (my_shape == 'Z' && opponents_shape == 'B') { - return 6 + shape_score; - } else { - return shape_score; - } -} - -int score_file(char **file_name) { - FILE *file = fopen(*file_name, "r"); - if (file == NULL) { - printf("Error opening the file.\n"); - return -2; - } - - int my_score = 0; - - // Read the file - while (!feof(file)) { - char opponent[1]; - char me[1]; - int res = fscanf(file, "%s %s", opponent, me); - - if (res == EOF) { - break; - } - // Check for blank line at the end of the file - else if (res == 1 && opponent[0] == '\n') { - continue; - } else if (res != 2) { - printf("Error: Bad file format.\n"); - return -3; - } - - my_score += round_score(*opponent, *me); - } - fclose(file); - - return my_score; -} - -/* NOTE: - * ------------------------------------------------------------ - * PART 2 OF THE SOLUTION - * ------------------------------------------------------------ - */ - -char *get_win_shape_part2(char *opponents_shape) { - switch (*opponents_shape) { - case 'A': - return "B"; - case 'B': - return "C"; - case 'C': - return "A"; - default: - return "0"; - } -} - -// Returns the shape that looses against the given shape -// -// Parameters: -// - opponents_shape -// - A = rock -// - B = paper -// - C = scissors -char *get_loss_shape_part2(char *opponents_shape) { - switch (*opponents_shape) { - case 'A': - return "C"; - case 'B': - return "A"; - case 'C': - return "B"; - default: - return "0"; - } -} - -/* Returns the score for a given round - * - * Parameters: - * - opponents_shape - * - A = rock - * - B = paper - * - C = scissors - * - round_result - * - X = loss - * - Y = draw - * - Z = win - */ -int score_round_part_2(char *opponents_shape, char *round_result) { - if (*round_result == 'X') { - char *loss_shape = get_loss_shape_part2(opponents_shape); - return score_shapes(*loss_shape); - } else if (*round_result == 'Y') { - // I have the same shape as the opponent - return 3 + score_shapes(*opponents_shape); - } else if (*round_result == 'Z') { - char *win_shape = get_win_shape_part2(opponents_shape); - return 6 + score_shapes(*win_shape); - } else { - return -1; - } -} - -// score_part2 -int score_file_part2(char **file_name, int *score) { - FILE *file = fopen(*file_name, "r"); - if (file == NULL) { - printf("Error opening the file.\n"); - return 2; - } - - // int score = 0; - - // Read the file - while (!feof(file)) { - char opponent; - char round_res; - int res = fscanf(file, "%s %s", &opponent, &round_res); - - if (res == EOF) { - break; - } - // Check for blank line at the end of the file - else if (res == 1 && opponent == '\n') { - continue; - } else if (res != 2) { - printf("Error: Bad file format.\n"); - return 3; - } - - *score += score_round_part_2(&opponent, &round_res); - } - fclose(file); - - // return score; - return 0; -} - -int main(int argc, char *argv[]) { - char *file_name; - int solution_part; - int score = 0; - - int res = arg_parser(argc, argv, &file_name, &solution_part); - if (res != 0) { - return res; - } - if (solution_part == 1) { - printf("My score: %d\n", score_file(&file_name)); - } else { - int res = score_file_part2(&file_name, &score); - if (res != 0) { - return res; - } - printf("My score: %d\n", score); - } - - return 0; -} diff --git a/02/tests/guide.dat b/02/tests/guide.dat deleted file mode 100644 index eef2e99..0000000 --- a/02/tests/guide.dat +++ /dev/null @@ -1,4 +0,0 @@ -A Y -B X -C Z - diff --git a/03/.vimspector.json b/03/.vimspector.json deleted file mode 100644 index 6dbb25c..0000000 --- a/03/.vimspector.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "configurations": { - "Launch": { - "adapter": "vscode-cpptools", - "filetypes": [ "cpp", "c", "objc", "rust" ], // optional - "configuration": { - "request": "launch", - "program": "${workspaceRoot}/output/main", - "args": [ "../tests/rucksacks.dat", "2" ], - "cwd": "${workspaceRoot}/output", - //"environment": [ ... ], - "externalConsole": true, - "MIMode": "gdb" - } - }, - "Attach": { - "adapter": "vscode-cpptools", - "filetypes": [ "cpp", "c", "objc", "rust" ], // optional - "configuration": { - "request": "attach", - "program": "${workspaceRoot}/output/main", - "MIMode": "gdb" - } - }, - "Launch prod": { - "adapter": "vscode-cpptools", - "filetypes": [ "cpp", "c", "objc", "rust" ], // optional - "configuration": { - "request": "launch", - "program": "${workspaceRoot}/output/main", - "args": [ "rucksacks.dat", "2" ], - "cwd": "${workspaceRoot}/output", - //"environment": [ ... ], - "externalConsole": true, - "MIMode": "gdb" - } - } - } -} diff --git a/03/Makefile b/03/Makefile deleted file mode 100644 index 3f27a58..0000000 --- a/03/Makefile +++ /dev/null @@ -1,91 +0,0 @@ -# -# 'make' build executable file 'main' -# 'make clean' removes all .o and executable files -# - -# define the C compiler to use CC = gcc - -# define any compile-time flags -# CFLAGS := -std=c99 -Wall -Wextra -g -lm -CFLAGS := -std=c99 -Wall -Wextra -g - -# define library paths in addition to /usr/lib -# if I wanted to include libraries not in /usr/lib I'd specify -# their path using -Lpath, something like: -LFLAGS = - -# define output directory -OUTPUT := output - -# define source directory -SRC := src - -# define include directory -INCLUDE := include - -# define lib directory -LIB := lib - -ifeq ($(OS),Windows_NT) -MAIN := main.exe -SOURCEDIRS := $(SRC) -INCLUDEDIRS := $(INCLUDE) -LIBDIRS := $(LIB) -FIXPATH = $(subst /,\,$1) -RM := del /q /f -MD := mkdir -else -MAIN := main -SOURCEDIRS := $(shell find $(SRC) -type d) -INCLUDEDIRS := $(shell find $(INCLUDE) -type d) -LIBDIRS := $(shell find $(LIB) -type d) -FIXPATH = $1 -RM = rm -f -MD := mkdir -p -endif - -# define any directories containing header files other than /usr/include -INCLUDES := $(patsubst %,-I%, $(INCLUDEDIRS:%/=%)) - -# define the C libs -LIBS := $(patsubst %,-L%, $(LIBDIRS:%/=%)) - -# define the C source files -SOURCES := $(wildcard $(patsubst %,%/*.c, $(SOURCEDIRS))) - -# define the C object files -OBJECTS := $(SOURCES:.c=.o) - -# -# The following part of the makefile is generic; it can be used to -# build any executable just by changing the definitions above and by -# deleting dependencies appended to the file from 'make depend' -# - -OUTPUTMAIN := $(call FIXPATH,$(OUTPUT)/$(MAIN)) - -all: $(OUTPUT) $(MAIN) - @echo Executing 'all' complete! - -$(OUTPUT): - $(MD) $(OUTPUT) - -$(MAIN): $(OBJECTS) - $(CC) $(INCLUDES) $(OBJECTS) $(LFLAGS) $(LIBS) -o $(OUTPUTMAIN) $(CFLAGS) - -# this is a suffix replacement rule for building .o's from .c's -# it uses automatic variables $<: the name of the prerequisite of -# the rule(a .c file) and $@: the name of the target of the rule (a .o file) -# (see the gnu make manual section about automatic variables) -.c.o: - $(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@ - -.PHONY: clean -clean: - $(RM) $(OUTPUTMAIN) - $(RM) $(call FIXPATH,$(OBJECTS)) - @echo Cleanup complete! - -run: all - ./$(OUTPUTMAIN) - @echo Executing 'run: all' complete! diff --git a/03/src/main.c b/03/src/main.c deleted file mode 100644 index bfb69b2..0000000 --- a/03/src/main.c +++ /dev/null @@ -1,271 +0,0 @@ -#include -#include -#include - -/* - * Error codes: - * 0 - no error - * 1 - invalid arguments - * 2 - memory allocation error - * 3 - invalid file - * 4 - invalid file format - */ - -/* - * Finds duplicate character in a given rucksack - * It finds the duplicates between the first and second compartments - * (first compartment is the first half of the rucksack, second compartment - * is the second half of the rucksack) - * - * Parameters: - * - char *str - * - The input string - * - * Returns: - * - char - * - The duplicate character - */ -char find_dup_char(char *str) { - int i, j; - int len = strlen(str); - char *first_compartment = (char *)malloc(len / 2); - char *second_compartment = (char *)malloc(len / 2); - char dup_char; - - // Copy the first half of the rucksack to the first compartment - // Copy the second half of the rucksack to the second compartment - for (i = 0; i < len; i++) { - if (i < len / 2) { - first_compartment[i] = str[i]; - } else { - second_compartment[i - len / 2] = str[i]; - } - } - - // Find the duplicate character - for (i = 0; i < len / 2; i++) { - for (j = 0; j < len / 2; j++) { - if (first_compartment[i] == second_compartment[j]) { - dup_char = first_compartment[i]; - - // Free the memory - free(first_compartment); - free(second_compartment); - - return dup_char; - } - } - } - - return '\0'; -} - -// Returns the score for a given character -int score_char(char c) { - // If the character is a capital letter - if (64 < c && c < 91) { - return c - 38; - } - // If the character is a lower case letter - else if (96 < c && c < 123) { - return c - 96; - } else { - return -1; - } -} - -int score_file(char **filename, int *score) { - FILE *fp = fopen(*filename, "r"); - if (fp == NULL) { - fprintf(stderr, "Error opening file `%s!\n", *filename); - return 3; - } - - // Count the number of rucksacks - // One rucksack per line - // Ignore the empty lines - int num_rucksacks = 0; - - // Get the number of rucksacks - // Number of lines in the file (without last empty line) - char line[300]; - - while (fgets(line, 100, fp) != NULL) { - if (strcmp(line, "\n") != 0) - num_rucksacks++; - } - rewind(fp); - - // Alocate memory for the temporary rucksack - char *rucksack = malloc(100 * sizeof(char)); - if (rucksack == NULL) { - fprintf(stderr, "Error allocating memory for rucksack\n"); - return 2; - } - - for (int i = 0; i < num_rucksacks; i++) { - // Get the rucksack - int res = fscanf(fp, "%s", rucksack); - - if (res == EOF) { - break; - } - // Check for blank line at the end of the file - else if (res == 1 && strcmp(rucksack, "\n") == 0) { - i--; - continue; - } else if (res != 1) { - printf("Error: Bad file format.\n"); - // Free the memory - free(rucksack); - fclose(fp); - return 4; - } - - // Find the duplicate character and score it - *score += score_char(find_dup_char(rucksack)); - } - // Free the memory - fclose(fp); - free(rucksack); - - return 0; -} - -/* - * NOTE: Part 2 - * ------------------------------------------------------ - */ - -/* Find badge character - * - * Parameters: - * - char *rucksack 1 - * - char *rucksack 2 - * - char *rucksack 3 - * Returns: - * - char - * - The badge character - */ -char find_badge(char *rucksack1, char *rucksack2, char *rucksack3) { - for (size_t i = 0; i < strlen(rucksack1); i++) { - for (size_t j = 0; j < strlen(rucksack2); j++) { - if (rucksack1[i] == rucksack2[j]) { - for (size_t k = 0; k < strlen(rucksack3); k++) { - if (rucksack1[i] == rucksack3[k]) { - return rucksack1[i]; - } - } - } - } - } - return '\0'; -} - -/* Score badges in a file - * - * Parameters: - * - char **filename - * - The name of the file - * - The file must have one rucksack per line - * - 3 rucksacks are separated by a blank line - * - int *score - * - The score of the badges in the file - * Returns: - * - int - * - Error code - */ -int score_badges_file(char **filename, int *score) { - FILE *fp = fopen(*filename, "r"); - if (fp == NULL) { - fprintf(stderr, "Error opening file `%s!\n", *filename); - return 3; - } - - // Allocate memory for the rucksacks - char *rucksack1 = malloc(100 * sizeof(char)); - char *rucksack2 = malloc(100 * sizeof(char)); - char *rucksack3 = malloc(100 * sizeof(char)); - - // Iterate over the file - int res = fscanf(fp, "%s\n%s\n%s\n\n", rucksack1, rucksack2, rucksack3); - - while (res != EOF) { - if (res != 3) { - fprintf(stderr, "Error: Bad file format.\n"); - // Free the memory - free(rucksack1); - free(rucksack2); - free(rucksack3); - fclose(fp); - return 4; - } - - // Find the badge character - char badge = find_badge(rucksack1, rucksack2, rucksack3); - - // Score the badge - *score += score_char(badge); - - res = fscanf(fp, "%s\n%s\n%s\n\n", rucksack1, rucksack2, rucksack3); - } - - // Free the memory - free(rucksack1); - free(rucksack2); - free(rucksack3); - fclose(fp); - - return 0; -} - -int arg_parser(int argc, char *argv[], char **filename, int *part) { - if (argc != 3) { - printf("Usage: %s \n", argv[0]); - return 1; - } - - // Check if the file exists - FILE *fp = fopen(argv[1], "r"); - if (fp == NULL) { - fprintf(stderr, "File %s does not exist\n", argv[1]); - return 3; - } - fclose(fp); - - *filename = argv[1]; - // Check if the part is valid - if (strcmp(argv[2], "1") != 0 && strcmp(argv[2], "2") != 0) { - fprintf(stderr, "Invalid part number: %s\n", argv[2]); - return 1; - } - *part = atoi(argv[2]); - return 0; -} - -int main(int argc, char *argv[]) { - char *filename; - int part; - int score = 0; - - int res = arg_parser(argc, argv, &filename, &part); - if (res != 0) { - return res; - } - - if (part == 1) { - res = score_file(&filename, &score); - if (res != 0) { - return res; - } - } else { - res = score_badges_file(&filename, &score); - if (res != 0) { - return res; - } - } - - printf("Score: %d\n", score); - - return 0; -} diff --git a/03/tests/rucksacks.dat b/03/tests/rucksacks.dat deleted file mode 100644 index f17e726..0000000 --- a/03/tests/rucksacks.dat +++ /dev/null @@ -1,6 +0,0 @@ -vJrwpWtwJgWrhcsFMMfFFhFp -jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL -PmmdzqPrVvPwwTWBwg -wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn -ttgJtRGJQctTZtZT -CrZsJsPPZsGzwwsLwLmpwMDw diff --git a/README.md b/README.md index 83c6d65..f995b66 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,6 @@ # AdventOfCode This repository contains all my code I've made for [`Advent of code`](https://adventofcode.com)! + +## Previous years + +- [2022](https://gitea.stefka.eu/jiriks74/AdventOfCode/src/branch/2022)