Skip to content

Commit

Permalink
dijkstra complete.
Browse files Browse the repository at this point in the history
  • Loading branch information
Xorcerer committed Dec 17, 2013
1 parent 3735a96 commit e96ce05
Showing 1 changed file with 82 additions and 14 deletions.
96 changes: 82 additions & 14 deletions cities-messaging/imperial-messengers.c
Expand Up @@ -25,10 +25,11 @@ Problem: Imperial Messengers
*
*/
const int MAX_CITY_COUNT = 100;

const unsigned int INT_MASK = 0xFFFFFFFF;
const int INT_MAX = 0x8FFFFFFF;
const int CHAR_BITS_COUNT = 8;
// Container for route connecting two cities DIRECTLY.
typedef int AdjacencyMatrix[5][5];
typedef int AdjacencyMatrix[MAX_CITY_COUNT + 1][MAX_CITY_COUNT + 1];

// Set, actually a bit array for integers.
// CPU is fast enough for a small array.
Expand All @@ -52,7 +53,7 @@ int set_init(IntSet* set, int max_int_value) {
// Return 0 for added, otherwise failure or already existed.
int set_add(IntSet set, int value) {
int byte_position = value >> CHAR_BITS_COUNT;
int bit_position = value & (0xFFFFFFFF >> (32 - CHAR_BITS_COUNT));
int bit_position = value & (INT_MASK >> (32 - CHAR_BITS_COUNT));
if (value / CHAR_BITS_COUNT >= set.size)
return -1;

Expand All @@ -65,14 +66,18 @@ int set_add(IntSet set, int value) {
// Return 1 for yes, 0 for no, otherwise error.
int set_has(IntSet set, int value) {
int byte_position = value >> CHAR_BITS_COUNT;
int bit_position = value & (0xFFFFFFFF >> (32 - CHAR_BITS_COUNT));
int bit_position = value & (INT_MASK >> (32 - CHAR_BITS_COUNT));
if (value / CHAR_BITS_COUNT >= set.size)
return -1;

// printf("set_has(%d) %x, %x, %x\n", value, byte_position, bit_position, set.bit_array[byte_position] & (1 << bit_position));
return !!(set.bit_array[byte_position] & (1 << bit_position));
}

void set_free(IntSet set) {
free(set.bit_array);
}

#ifdef UNIT_TEST

int main(int argc, char* argv[]) {
Expand All @@ -98,28 +103,91 @@ int main(int argc, char* argv[]) {

#endif

typedef struct LinkedNode {
int value;
struct LinkedNode *next;
} LinkedNode;

/*
*
* 2. Dijkstra.
*
*/
int max_timespan(int timespans[], count) {
int max = 0;
for (int i = 1; i <= count; ++city)
max = timespans[i] > max ? timespans[i] : max;
return max;
}


// dijkstra algo to all cities.
int minimum_time_to_farthest_city(AdjacencyMatrix matrix, size_t cities_count) {
int min_times[MAX_CITY_COUNT];
IntSet cities_visited;
set_init(&cities_visited, cities_count);


return 0;
// Apply dijkstra algo to all cities.
int minimum_timespan_to_farthest_city(AdjacencyMatrix matrix, size_t cities_count) {
const int capital_city = 1;

int min_timespans[MAX_CITY_COUNT + 1];
memset(min_timespans, 0xFF, MAX_CITY_COUNT + 1);

min_timespans[1] = 0;

LinkedNode *cities_visited_head = malloc(sizeof(LinkedNode));
cities_visited_head->value = capital_city;
cities_visited_head->next = NULL;
LinkedNode *cities_visited_tail = cities_visited_head;

LinkedNode *cities_to_visit_head = malloc(sizeof(LinkedNode));
cities_to_visit_head->value = 0;
cities_to_visit_head->next = NULL;

LinkedNode *current_city_node = cities_to_visit_head;
for (int city = 2; city <= cities_count; ++city) {
LinkedNode *new_node = malloc(sizeof(LinkedNode));
new_node->value = city;
new_node->next = NULL;
current_city_node->next = new_node;
current_city_node = new_node;
}

while (1) {
struct MinTimespan {
int city; int timespan; LinkedNode *prev;
} min_timespan_this_loop = {0, INT_MAX, NULL};

current_city_node = &cities_visited_head;

while (current_city_node != NULL) {
int current_city = visited_city_node->value;
LinkedNode *city_to_visit_node = cities_to_visit_head->next;
if (city_to_visit_node == NULL) // All the cities are visited, exit.
return max_timespan(min_timespans, cities_count);

LinkedNode *prev_city_to_visit_node = cities_to_visit_head;
while (city_to_visit_node != NULL) {
int city_to_visit = city_to_visit_node->value;
int timespan = matrix[current_city][city_to_visit] + min_timespans[current_city];
if (timespan < min_timespan_this_loop.timespan) {
min_timespan_this_loop.city = city_to_visit;
min_timespan_this_loop.timespan = timespan;
min_timespan_this_loop.prev = prev_city_to_visit_node;
}
prev_city_to_visit_node = city_to_visit_node;
city_to_visit_node = city_to_visit_node->next;
}

current_city_node = current_city_node->next;
}

min_timespans[min_timespan_this_loop.city] = min_timespan_this_loop.timespan;
cities_visited_tail->next = min_timespan_this_loop.prev->next;
cities_visited_tail = cities_visited_tail->next;
min_timespan_this_loop.prev->next = min_timespan_this_loop->next->next;
}
return -1;
}

#ifndef UNIT_TEST

int main(int argc, char* argv[]) {


}

#endif

0 comments on commit e96ce05

Please sign in to comment.