feat(2023): remove code for new year
This commit is contained in:
parent
25458f02e9
commit
595837a4ac
13 changed files with 4 additions and 1201 deletions
|
@ -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"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
90
01/Makefile
90
01/Makefile
|
@ -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!
|
|
246
01/src/main.c
246
01/src/main.c
|
@ -1,246 +0,0 @@
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
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 <filename>\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;
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
1000
|
|
||||||
2000
|
|
||||||
3000
|
|
||||||
|
|
||||||
4000
|
|
||||||
|
|
||||||
5000
|
|
||||||
6000
|
|
||||||
|
|
||||||
7000
|
|
||||||
8000
|
|
||||||
9000
|
|
||||||
|
|
||||||
10000
|
|
|
@ -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"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
91
02/Makefile
91
02/Makefile
|
@ -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!
|
|
271
02/src/main.c
271
02/src/main.c
|
@ -1,271 +0,0 @@
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
/* 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 <file> <solution_part (1/2)>\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;
|
|
||||||
}
|
|
|
@ -1,4 +0,0 @@
|
||||||
A Y
|
|
||||||
B X
|
|
||||||
C Z
|
|
||||||
|
|
|
@ -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"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
91
03/Makefile
91
03/Makefile
|
@ -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!
|
|
271
03/src/main.c
271
03/src/main.c
|
@ -1,271 +0,0 @@
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 <file> <part (1,2)>\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;
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
vJrwpWtwJgWrhcsFMMfFFhFp
|
|
||||||
jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
|
|
||||||
PmmdzqPrVvPwwTWBwg
|
|
||||||
wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn
|
|
||||||
ttgJtRGJQctTZtZT
|
|
||||||
CrZsJsPPZsGzwwsLwLmpwMDw
|
|
|
@ -1,2 +1,6 @@
|
||||||
# AdventOfCode
|
# AdventOfCode
|
||||||
This repository contains all my code I've made for [`Advent of code`](https://adventofcode.com)!
|
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)
|
||||||
|
|
Loading…
Reference in a new issue