From 97a3c65f0d01281add70ca18da4d4eca7a3558b4 Mon Sep 17 00:00:00 2001 From: Manuel Bucher <manuel.bucher@hu-berlin.de> Date: Mon, 11 Jun 2018 14:57:54 +0200 Subject: [PATCH] added connection betweent tiles & detect duplicated entry --- Makefile | 6 ++-- loesung.c | 97 ++++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 81 insertions(+), 22 deletions(-) diff --git a/Makefile b/Makefile index fd12125..994f140 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,9 @@ all: loesung -WARNINGS = -Wall -Werror +WARNINGS = -Wall #-Werror OPTIONAL = -Wextra -Wpedantic -Wshadow -DEBUG = -ggdb -fno-omit-frame-pointer -OPTIMIZE = -O3 -std=c11 +DEBUG = -g -ggdb -fno-omit-frame-pointer +OPTIMIZE = -O2 -std=c11 loesung: Makefile loesung.c $(CC) -o $@ $(WARNINGS) $(OPTIONAL) $(DEBUG) $(OPTIMIZE) loesung.c diff --git a/loesung.c b/loesung.c index e9ee5c3..22e52f5 100644 --- a/loesung.c +++ b/loesung.c @@ -7,24 +7,26 @@ typedef struct Tile { uint32_t x; uint32_t y; - struct Tile *p_next; - struct Tile *p_prev; + struct Tile *p_n; // north, used for initial list + struct Tile *p_e; // east + struct Tile *p_s; // south + struct Tile *p_w; // west } Tile; int tile_compare(const void *p, const void *q) { const Tile *s = *(const Tile**) p; const Tile *t = *(const Tile**) q; - // als erstes nach x sortieren - if (s->x < t->x) - return -1; - if (s->x > t->x) - return 1; - // danach nach y sortieren + // als erstes nach y sortieren if (s->y < t->y) return -1; if (s->y > t->y) return 1; + // danach nach x sortieren + if (s->x < t->x) + return -1; + if (s->x > t->x) + return 1; return 0; // Elemente sind gleich } @@ -54,24 +56,24 @@ Tile* list_push(List *s) { } p_tile->x = 0; p_tile->y = 0; - p_tile->p_next = s->p_top; - p_tile->p_prev = NULL; + p_tile->p_n = s->p_top; + p_tile->p_e = NULL; + p_tile->p_s = NULL; + p_tile->p_w = NULL; + s->p_top = p_tile; s->size++; - if(p_tile->p_next != NULL) { - p_tile->p_next->p_prev = p_tile; - } return p_tile; } /** Entfernen des obersten Elementes von der Liste und zurueckgeben des Tiles * - * Der List muss mindestens ein Element besitzen TODO: Notwendig? + * Der List muss mindestens ein Element besitzen */ Tile* list_pop(List *s) { Tile *p_tile = s->p_top; - s->p_top->p_next = p_tile->p_next; - s->p_top->p_prev = NULL; + s->p_top = s->p_top->p_n; + s->size--; return p_tile; } @@ -83,7 +85,7 @@ void list_free(List *s) { Tile *p_cur = s->p_top; s->p_top = NULL; while (p_cur != NULL) { - Tile *p_next = p_cur->p_next; + Tile *p_next = p_cur->p_n; free(p_cur); p_cur = p_next; } @@ -104,7 +106,9 @@ typedef struct Field { Tile t_max; List tile_list; Tile* (*tile_array); -} Field; + uint32_t num_tiles; +} Field; // TODO: entfernen dieses Structs und nutzen von kleineren Strukturen: + // list + tile_array /** Parsen einer Kachel(Tile) aus einer Zeile von StdIn * @@ -178,6 +182,7 @@ void field_init(Field *f) { // initialisieren der Liste list_init(&f->tile_list); f->tile_array = 0; + f->num_tiles = 0; } /** Freigeben des im Heap reservierten speichers des fields f */ @@ -252,14 +257,58 @@ MallocResult field_init_tile_array(Field *f) { return MallocFailed; } Tile *cur = f->tile_list.p_top; + f->num_tiles = f->tile_list.size; for (uint32_t i = 0; i < f->tile_list.size; i++) { f->tile_array[i] = cur; - cur = cur->p_next; + cur = cur->p_n; + f->tile_array[i]->p_n = NULL; } return MallocOk; } +/** Gruppieren der Felder, setzen der Pointer (north, east, south, west) vom Feld + * + * Voraussetzung: `field_init_tile_array()` muss ausgefuehrt worden sein + * Rueckgabe: 0 falls alles ok + * 1 falls Dopplungen vorkommen TODO: enum + */ +int field_find_neighbours(Field *f) { + uint32_t i = 0; // vergleich mit oberer Zeile + uint32_t begin_line = 0; + for (uint32_t j = 1; j < f->num_tiles; j++) { + Tile *p_cur = f->tile_array[j]; + Tile *p_east = f->tile_array[j-1]; + // ermitteln der ost/west-Beziehung + if (p_cur->y == p_east->y) { + if (p_cur->x == p_east->x) { + return 1; + } + if (p_cur->x == p_east->x - 1) { + p_cur->p_e = p_east; + p_east->p_w = p_cur; + } + } else { + begin_line = i; + } + // ermitteln der nord/sued-Beziehung + Tile *p_north = f->tile_array[i]; + if (p_north->y < p_cur->y - 1) { + i = begin_line; // Luecke zwischen zeilen + } else if (p_north->y == p_cur->y - 1) { + // finden, ob paar existiert, zurzeit O(n). + // TODO: lohnt sich binaere suche mit O(log n)? + for(;f->tile_array[i]->y < p_cur->y && i < begin_line; i++); + p_north = f->tile_array[i]; + if (p_north->x == p_cur->x) { + p_north->p_s = p_cur; + p_cur->p_n = p_north; + } + } + } + return 0; +} + void field_print(Field *f) { printf("# Array\n"); for (uint32_t i = 0; i < f->tile_list.size; i++) { @@ -308,6 +357,16 @@ int main (void) } qsort(field.tile_array, field.tile_list.size, sizeof(Tile*), tile_compare); + if(field_find_neighbours(&field)) { + fprintf(stderr, "Error: Duplicated entry\n"); + return EXIT_FAILURE; + } + //field_print(&field); + + // TODO: Untertilesets finden + // TODO: Problem fuer die Untertilesets loesen + // TODO: Loesung ausgeben + field_drop(&field); return EXIT_SUCCESS; } -- GitLab