Skip to content
Snippets Groups Projects
Commit aff0e3f9 authored by Manuel Bucher's avatar Manuel Bucher
Browse files

Initial commit

parents
Branches
No related merge requests found
*~
*.swp
loesung
programmierprojekt/
Makefile 0 → 100644
all: loesung
WARNINGS = -Wall -Werror
OPTIONAL = #-Werror -Wpedantic
DEBUG = -ggdb -fno-omit-frame-pointer
OPTIMIZE = -O3 -std=c11
loesung: Makefile loesung.c
$(CC) -o $@ $(WARNINGS) $(OPTIONAL) $(DEBUG) $(OPTIMIZE) loesung.c
clean:
rm -f loesung
# Builder will call this to install the application before running.
install:
#nothing
# Builder uses this target to run your application.
run:
./loesung
loesung.c 0 → 100644
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h> // fixed sized integer
#include <stdbool.h> // booleans
typedef struct Tile {
uint32_t x;
uint32_t y;
} Tile;
typedef enum ReadResult {
RdOk,
RdEof,
RdErrIntegerOverflow,
RdErrNonDigitCharacter,
RdErrTooFewNumbers,
RdErrTooManyNumbers,
} ReadResult;
typedef struct Field {
Tile t_min;
Tile t_max;
uint32_t num_tiles;
} Field;
/** Parsen einer Kachel(Tile) aus einer Zeile von StdIn
*
* Die Zahlen werden in das uebergebene Struct pKachel geschrieben, sind aber
* nur gueltig, wenn der Rueckgabewert `Ok` ist.
*/
ReadResult read_line(Tile* p_tile){
int c = getchar();
if (c == EOF) {
return RdEof;
}
int num_numbers = 0;
bool cur_whitespace = true;
while(1) {
c = getchar();
if ('0' <= c && c <= '9') {
if (cur_whitespace) {
num_numbers++;
cur_whitespace = false;
}
uint32_t *p_cur;
switch(num_numbers) {
case 1:
p_cur = &p_tile->x;
break;
case 2:
p_cur = &p_tile->y;
break;
default:
return RdErrTooManyNumbers;
}
// 429496730 = 2^32 / 10, daher wenn `p_cur` groesser ist, wird ein
// overflow erzeugt
if (*p_cur > 429496729) {
printf("Multiplizieren ueberlauf %u\n", *p_cur);
return RdErrIntegerOverflow;
}
(*p_cur) *= 10;
int digit = c - '0';
if (*p_cur > UINT32_MAX - digit) {
printf("Addieren ueberlauf %u\n", *p_cur);
return RdErrIntegerOverflow;
}
(*p_cur) += digit;
} else if (c == ' ') {
if (cur_whitespace == true) {
cur_whitespace = false;
}
} else if (c == '\n') {
if (num_numbers == 2) {
return RdOk;
} else {
return RdErrTooFewNumbers;
}
} else {
return RdErrNonDigitCharacter;
}
}
return RdOk;
}
/**
*
*/
inline uint32_t min(uint32_t a, uint32_t b) {
return a < b ? a : b;
}
inline uint32_t max(uint32_t a, uint32_t b) {
return a > b ? a : b;
}
/** Liest das Input von StdIn und schreibt das Ergebnis in das uebergebene Feld
*
* Parameter:
* - Field* f pointer auf ein uninitialisiertes Feld, nach dem ausfuehren der
* Funktion ist das Feld initialisiert, wenn es sich um eine gueltige Eingabe
* handelt. `f->num_tiles` Ist im Fehlerfall die Zeile, in dem die Eingabe
* ungueltig ist.
*
* Return:
* - ReadResult:
* RdOk, falls das lesen erfolgreich war
* RdErr..., falls die eingabe ungueltig ist. f ist dann nicht vollstaendig
* initialisiert
*/
ReadResult parse_input(Field *f) {
f->t_min.x = UINT32_MAX;
f->t_min.y = UINT32_MAX;
f->t_max.x = 0;
f->t_max.y = 0;
f->num_tiles = 0;
while (1) {
Tile t;
ReadResult result = read_line(&t);
f->num_tiles++;
switch (result) {
case RdOk:
// Reichweite des Feldes ermitteln
f->t_min.x = min(f->t_min.x, t.x);
f->t_min.y = min(f->t_min.y, t.y);
f->t_max.x = max(f->t_max.x, t.x);
f->t_max.y = max(f->t_max.x, t.y);
break;
case RdEof:
if (f->num_tiles == 1) {
return RdEof;
} else {
return RdOk;
}
default: // error
return result;
}
}
}
int main (int argc,
char *argv[])
{
Field f;
ReadResult result = parse_input(&f);
switch (result) {
case RdOk:
printf("Valider Input");
printf("Anzahl: %d", f.num_tiles);
printf("Range(%d, %d), (%d, %d)",
f.t_min.x, f.t_min.y,
f.t_max.x, f.t_max.y);
printf("Range x: %d, %d",
f.t_max.x - f.t_min.x,
f.t_max.y - f.t_min.y);
break;
case RdEof:
// bei leerer Eingabe nichts ausgeben
return EXIT_SUCCESS;
case RdErrIntegerOverflow:
fprintf(stderr, "Error in line %d: too big integer\n", f.num_tiles);
return EXIT_FAILURE;
case RdErrNonDigitCharacter:
fprintf(stderr, "Error in line %d: invalid character\n", f.num_tiles);
return EXIT_FAILURE;
case RdErrTooFewNumbers:
fprintf(stderr, "Error in line %d: Too few numbers, expected exactly 2\n",
f.num_tiles);
return EXIT_FAILURE;
case RdErrTooManyNumbers:
fprintf(stderr, "Error in line %d: Too much numbers, expected exactly 2\n",
f.num_tiles);
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment