217 lines
4.6 KiB
C
217 lines
4.6 KiB
C
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include <ctype.h>
|
|
#include <string.h>
|
|
#include <sys/mman.h>
|
|
#include <sys/stat.h>
|
|
|
|
int ID_OFFSET;
|
|
|
|
struct Round
|
|
{
|
|
int red;
|
|
int green;
|
|
int blue;
|
|
};
|
|
|
|
struct Game
|
|
{
|
|
struct Round rounds[10];
|
|
int iterator;
|
|
int id;
|
|
};
|
|
|
|
struct Games
|
|
{
|
|
struct Game games[100];
|
|
int iterator;
|
|
};
|
|
|
|
int str_to_int(char *str)
|
|
{
|
|
int result;
|
|
char *tmp;
|
|
result = strtol(str, &tmp, 10);
|
|
return result;
|
|
}
|
|
|
|
char *parse_cube(char *line, int *cube_num)
|
|
{
|
|
const char delim[2] = " ";
|
|
char *save_ptr;
|
|
char *token;
|
|
token = strtok_r(line, delim, &save_ptr);
|
|
*cube_num = str_to_int(token);
|
|
token = strtok_r(NULL, delim, &save_ptr);
|
|
return token; // Cube colour
|
|
}
|
|
|
|
struct Round parse_round(char *line, struct Game game)
|
|
{
|
|
const char delim[2] = ",";
|
|
char *save_ptr;
|
|
char *token;
|
|
int cube_num;
|
|
struct Round round = {0, 0, 0};
|
|
|
|
token = strtok_r(line, delim, &save_ptr);
|
|
while (token != NULL)
|
|
{
|
|
char *colour = parse_cube(token, &cube_num);
|
|
if (!strcmp(colour, "red"))
|
|
{
|
|
round.red = cube_num;
|
|
}
|
|
else if (!strcmp(colour, "blue"))
|
|
{
|
|
round.blue = cube_num;
|
|
}
|
|
else if (!strcmp(colour, "green"))
|
|
{
|
|
round.green = cube_num;
|
|
}
|
|
token = strtok_r(NULL, delim, &save_ptr);
|
|
game.rounds[game.iterator] = round;
|
|
}
|
|
|
|
return round;
|
|
}
|
|
|
|
struct Game parse_game_data(char *line, struct Game game, int id)
|
|
{
|
|
// printf("%s\n", line);
|
|
// https://www.tutorialspoint.com/c_standard_library/c_function_strtok.htm
|
|
// https://www.tutorialspoint.com/data_structures_algorithms/hash_table_program_in_c.htm
|
|
char *token;
|
|
char *save_ptr;
|
|
const char delim[2] = ";";
|
|
|
|
game.id = id;
|
|
token = strtok_r(line, delim, &save_ptr);
|
|
while (token != NULL)
|
|
{
|
|
game.rounds[game.iterator++] = parse_round(token, game);
|
|
token = strtok_r(NULL, delim, &save_ptr);
|
|
}
|
|
|
|
return game;
|
|
}
|
|
|
|
int get_id(char *ptr)
|
|
{
|
|
int id;
|
|
char *_id = (char *)malloc(4);
|
|
for (int i = 0; i <= 4; i++)
|
|
{
|
|
if (ptr[i] != ':')
|
|
{
|
|
_id[i] = ptr[i];
|
|
}
|
|
else
|
|
{
|
|
ID_OFFSET = i;
|
|
break;
|
|
}
|
|
}
|
|
id = str_to_int(_id);
|
|
return id;
|
|
}
|
|
|
|
int main()
|
|
{
|
|
struct Games games;
|
|
games.iterator = 0;
|
|
int MAX_RED = 12;
|
|
int MAX_GREEN = 13;
|
|
int MAX_BLUE = 14;
|
|
|
|
int GAME_OFFSET = 5; // Skip the word Game and start on the ID number
|
|
|
|
const char *inputFile = "input";
|
|
int fd = open(inputFile, O_RDONLY);
|
|
|
|
if (fd < 0)
|
|
{
|
|
printf("\n\"%s \" could not open\n");
|
|
exit(1);
|
|
}
|
|
|
|
struct stat statbuf;
|
|
int err = fstat(fd, &statbuf);
|
|
if (err < 0)
|
|
{
|
|
printf("\n\"%s \" could not open\n", inputFile);
|
|
exit(2);
|
|
}
|
|
|
|
char *ptr = mmap(NULL, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0);
|
|
if (ptr == MAP_FAILED)
|
|
{
|
|
printf("Mapping failed");
|
|
return 1;
|
|
}
|
|
|
|
int inLine = 0;
|
|
for (int i = 0; i < statbuf.st_size; i++)
|
|
{
|
|
int id;
|
|
char *tmpLine = (char *)malloc(255);
|
|
for (int j = 0; j < __INT64_MAX__; j++)
|
|
{
|
|
if (inLine == 0)
|
|
{
|
|
inLine = 1;
|
|
i += GAME_OFFSET;
|
|
id = get_id(&ptr[i]);
|
|
i += ID_OFFSET + 1;
|
|
continue;
|
|
}
|
|
if (ptr[i + j] == '\n')
|
|
{
|
|
memcpy(tmpLine, &ptr[i], j);
|
|
// printf("ID: %i |", id);
|
|
struct Game game = {-1, -1};
|
|
games.games[games.iterator++] = parse_game_data(tmpLine, game, id);
|
|
i += j;
|
|
break;
|
|
}
|
|
|
|
tmpLine[j] = ptr[i + j];
|
|
}
|
|
|
|
inLine = 0;
|
|
}
|
|
|
|
int total = 0;
|
|
for (int i = 0; i < games.iterator; i++) // Iterate through the games
|
|
{
|
|
int failed = 0;
|
|
for (int j = 0; j < games.iterator; j++) // Iterate thrugh the rounds
|
|
{
|
|
if (games.games[i].rounds[j].red > 12 || games.games[i].rounds[j].blue > 14 || games.games[i].rounds[j].green > 13)
|
|
{
|
|
failed = 1;
|
|
}
|
|
if (j == games.games[i].iterator)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
if (failed == 0)
|
|
{
|
|
total += games.games[i].id;
|
|
}
|
|
}
|
|
printf("\nThe total is: %i\n\n", total);
|
|
err = munmap(ptr, statbuf.st_size);
|
|
if (err != 0)
|
|
{
|
|
printf("Unmapping failed");
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|