Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdbool.h>//definition of bool type and true/false
- #define MAX_FILE_SIZE 10000//change to ork with bigger files
- typedef struct s_date
- {
- unsigned int day;
- unsigned int month;
- unsigned int year;
- } t_date;
- typedef struct s_bridge
- {
- t_date date;
- unsigned int island_id;//id of the island that is connected with the bridge
- unsigned int island2_id;//if of the second island that ...
- } t_bridge;
- typedef struct s_data
- {
- unsigned int n;//number of islands
- unsigned int k;//number of bridges
- } t_data;
- static void static_value(const char *buff, unsigned int *i, unsigned int *value)
- {
- while (buff[*i] == ' ' || buff[*i] == '\n' || buff[*i] == '/')//skip delimiters
- ++(*i);
- *value = atoi(&(buff[*i]));//parse value
- while (buff[*i] >= '0' && buff[*i] <= '9')//skip the value
- ++(*i);
- }
- static bool static_parse_bridges(t_data *data, t_bridge *bridges,
- const char *buff, unsigned int *i)
- {
- for (unsigned int b = 0; b < data->k; ++b)
- {
- static_value(buff, i, &bridges[b].island_id);
- if (bridges[b].island_id == 0 || bridges[b].island_id > data->n)
- return (false);
- static_value(buff, i, &bridges[b].island2_id);
- if (bridges[b].island2_id == 0 || bridges[b].island2_id > data->n)
- return (false);
- static_value(buff, i, &bridges[b].date.day);
- if (bridges[b].date.day > 32 || bridges[b].date.day == 0)
- return (false);
- static_value(buff, i, &bridges[b].date.month);
- if (bridges[b].date.month == 0 || bridges[b].date.month > 12)
- return (false);
- static_value(buff, i, &bridges[b].date.year);
- }
- return (true);
- }
- static bool static_parse(t_data *data, t_bridge **bridges, const char *input_file)
- {
- FILE *input;//input file
- int ret;//n of bytes read from the input file
- char buff[MAX_FILE_SIZE + 1];//buffer to read to
- unsigned int i = 0;//iterator for buff
- if (!(input = fopen(input_file, "r")))
- {
- printf("Error: Can't open file \"%s\"\n", input_file);
- system("pause");
- return (false);
- }
- if (!(ret = fread(buff, 1, MAX_FILE_SIZE + 1, input)))
- {
- printf("Error: Can't read from \"%s\"\n", input_file);
- system("pause");
- return (false);
- }
- if (ret == MAX_FILE_SIZE + 1)
- {
- printf("Error: File \"%s\" is way too large\n", input_file);
- system("pause");
- return (false);
- }
- static_value(buff, &i, &data->n);//parse n
- if (data->n < 2 || data->n > 1000)//check n
- {
- printf("Error: Invalid value of n (%u)\n", data->n);
- system("pause");
- return (false);
- }
- static_value(buff, &i, &data->k);//parse k
- if (data->k == 0 || data->k > 10000)//check k
- {
- printf("Error: Invalid value of k (%u)\n", data->k);
- system("pause");
- return (false);
- }
- *bridges = malloc(sizeof(t_bridge)* data->k);//allocate array of bridges
- if (!static_parse_bridges(data, *bridges, buff, &i))
- {
- printf("Error: Invalid value in the bridge description\n");
- system("pause");
- return (false);
- }
- return (true);
- }
- //check if connected
- static bool static_done(const bool *connected, unsigned int size)
- {
- while (size-- > 0)
- if (!connected[size])
- return (false);
- return (true);
- }
- //compare dates
- static bool static_infuture(t_date date, t_date curr_date)
- {
- if (curr_date.year >= date.year
- && curr_date.month >= date.month
- && curr_date.day >= date.day)
- return (false);
- return (true);
- }
- //check if one of the islands connected by the bridge is connected to the other islands
- static bool static_connected(unsigned int *cnctd_list, unsigned int *n_cnctd,
- t_bridge *bridge)
- {
- unsigned char n = 0;
- unsigned int id = 0;
- for (unsigned int i = 0; i < *n_cnctd; ++i)
- {
- if (cnctd_list[i] == bridge->island_id
- || cnctd_list[i] == bridge->island2_id)
- {
- if (cnctd_list[i] == bridge->island_id)
- id = bridge->island2_id;
- else
- id = bridge->island_id;
- ++n;
- }
- }
- if (n == 1)
- {
- cnctd_list[*n_cnctd] = id;
- ++(*n_cnctd);
- }
- return (n == 1 ? true : false);
- }
- static void static_connect(t_bridge *bridges, bool *connected, t_data *data,
- t_date curr_date, unsigned int *cnctd_list, unsigned int n_cnctd)
- {
- //connects if possible
- for (unsigned int i = 0; i < data->k; ++i)
- {
- if (!static_infuture(bridges[i].date, curr_date)
- && static_connected(cnctd_list, &n_cnctd, &bridges[i]))
- {
- connected[bridges[i].island_id - 1] = true;
- connected[bridges[i].island2_id - 1] = true;
- i = 0;
- }
- }
- }
- static t_date static_solve(t_data *data, t_bridge *bridges)
- {
- t_date curr_date = { 1, 1, 1 };
- bool *connected;//list of islands connected to the first island
- unsigned int *cnctd_list;
- unsigned int n_cnctd = 1;//number of connected islands
- connected = malloc(sizeof(bool)* data->n);
- cnctd_list = malloc(sizeof(unsigned int)* data->n);
- cnctd_list[0] = 1;//the island to start check connections from
- connected[0] = true;//connected to itself
- for (unsigned int i = 1; i < data->n; ++i)
- connected[i] = false;
- //calculation based on that there are 32 days in each month
- while (!static_done(connected, data->n))//check if all are connected
- {
- //update curr date
- if (curr_date.day < 32)
- curr_date.day++;
- else if (curr_date.month < 12)
- {
- curr_date.day = 1;
- curr_date.month++;
- }
- else
- {
- curr_date.day = 1;
- curr_date.month = 1;
- curr_date.year++;
- }
- static_connect(bridges, connected, data, curr_date, cnctd_list, n_cnctd);//connect islands
- }
- free(connected);
- free(cnctd_list);
- return (curr_date);
- }
- int main()
- {
- t_data data;
- t_bridge *bridges;
- static char *input_file = "map.txt";
- //static char *output_file = "result.txt";
- //FILE *output;
- t_date result;
- if (!static_parse(&data, &bridges, input_file))
- system("pause");
- return (false);
- //if (!(output = fopen(output_file, "w")))
- //{
- // printf("Error: Can't open file \"%s\"\n", output_file);
- // system("pause");
- // return (false);
- //}
- result = static_solve(&data, bridges);
- printf("%u/%u/%u\n", result.day, result.month, result.year);//console output
- //fprintf(output, "%u/%u/%u\n", result.day, result.month, result.year);//file output
- system("pause");
- return (true);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement