195 lines
3.9 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 = {-1, -1, -1};
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)
{
// 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] = ";";
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 = {id, -1};
games.games[games.iterator++] = parse_game_data(tmpLine, game);
i += j;
break;
}
tmpLine[j] = ptr[i + j];
}
inLine = 0;
}
err = munmap(ptr, statbuf.st_size);
if (err != 0)
{
printf("Unmapping failed");
return 1;
}
return 0;
}