Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- struct block {
- unsigned start;
- unsigned count;
- struct block * next;
- };
- unsigned get_number(void);
- char ** get_lines(unsigned);
- char * get_line(void);
- char * check_line(char *, unsigned, unsigned);
- struct block parse_column(char **, unsigned, unsigned);
- char ** generate_result(struct block *, unsigned);
- void free_lines_array(char **, unsigned);
- int main (void) {
- unsigned size = get_number();
- if (!size) {
- fprintf(stderr, "Invalid amount of lines entered\n");
- return 1;
- }
- char ** lines = get_lines(size);
- unsigned line;
- for (line = 0; line < size; line ++) lines[line] = check_line(lines[line], size, line + 1);
- struct block * columns = malloc(sizeof(struct block) * size);
- for (line = 0; line < size; line ++) columns[line] = parse_column(lines, size, line);
- free_lines_array(lines, size);
- lines = generate_result(columns, size);
- for (line = 0; line < size; line ++) {
- struct block * current = columns[line].next;
- struct block * previous = NULL;
- while (current) {
- previous = current;
- current = current -> next;
- free(previous);
- }
- printf("%s\n", lines[line]);
- }
- free(columns);
- free_lines_array(lines, size);
- return 0;
- }
- unsigned get_number (void) {
- char * line = get_line();
- if (!*line) {
- free(line);
- return 0;
- }
- char * end;
- unsigned number = strtoul(line, &end, 10);
- if (*end) number = 0;
- free(line);
- return number;
- }
- char ** get_lines (unsigned lines) {
- char ** result = malloc(sizeof(char *) * lines);
- unsigned line;
- for (line = 0; line < lines; line ++) result[line] = get_line();
- return result;
- }
- char * get_line (void) {
- char * line = NULL;
- unsigned length = 0;
- char newchar;
- for (newchar = getchar(); (newchar != EOF) && (newchar != '\n'); newchar = getchar()) {
- line = realloc(line, ++ length);
- line[length - 1] = newchar;
- }
- line = realloc(line, length + 1);
- line[length] = 0;
- return line;
- }
- char * check_line (char * line, unsigned size, unsigned line_number) {
- unsigned length = strlen(line);
- unsigned pos;
- if (length > size) {
- fprintf(stderr, "Line %u is %u characters long (expected: %u), truncating\n", line_number, length, size);
- line = realloc(line, size + 1);
- line[size] = 0;
- } else if (length < size) {
- fprintf(stderr, "Line %u is %u characters long (expected: %u), padding with spaces\n", line_number, length, size);
- line = realloc(line, size + 1);
- memset(line + length, ' ', size - length);
- line[size] = 0;
- }
- for (pos = 0; pos < size; pos ++) {
- if ((line[pos] == ' ') || (line[pos] == '#') || (line[pos] == '.')) continue;
- fprintf(stderr, "Line %u: spurious character 0x%02x at column %u, inserting space\n", line_number, (int) (line[pos]), pos + 1);
- line[pos] = ' ';
- }
- return line;
- }
- struct block parse_column (char ** lines, unsigned size, unsigned column) {
- struct block result = {.start = 0, .count = 0, .next = NULL};
- struct block * current = &result;
- unsigned line;
- for (line = 0; line < size; line ++)
- switch (lines[size - 1 - line][column]) {
- case '.':
- (current -> count) ++;
- break;
- case '#':
- current = (current -> next = malloc(sizeof(struct block)));
- current -> start = line + 1;
- current -> count = 0;
- current -> next = NULL;
- }
- return result;
- }
- char ** generate_result (struct block * columns, unsigned size) {
- char ** result = malloc(sizeof(char *) * size);
- unsigned line, pos;
- struct block * current_block;
- for (line = 0; line < size; line ++) {
- result[line] = malloc(size + 1);
- memset(result[line], ' ', size);
- result[line][size] = 0;
- }
- for (line = 0; line < size; line ++)
- for (current_block = columns + line; current_block; current_block = current_block -> next) {
- if (current_block -> start) result[size - current_block -> start][line] = '#';
- for (pos = 1; pos <= (current_block -> count); pos ++)
- result[size - (current_block -> start + pos)][line] = '.';
- }
- return result;
- }
- void free_lines_array (char ** lines, unsigned size) {
- unsigned line;
- for (line = 0; line < size; line ++) free(lines[line]);
- free(lines);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement