Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- static const char *SLOPES = "\\_/";
- static char *error_message = NULL;
- typedef struct
- {
- int width, height;
- char data[];
- } Panorama;
- int check_source(char *source)
- {
- ssize_t total_length, slope_length;
- total_length = strlen(source);
- slope_length = strspn(source, SLOPES);
- return (total_length == slope_length) ? total_length : -1;
- }
- int slope_to_delta(char slope)
- {
- return strchr(SLOPES, slope) - SLOPES - 1;
- }
- uint* calculate_heights(uint width, char *source, int *max_height)
- {
- uint i;
- int current_height, delta;
- uint *heights;
- heights = malloc(width * sizeof(heights));
- *max_height = 0;
- for (current_height = i = 0; i < width; ++i) {
- heights[i] = current_height;
- delta = slope_to_delta(source[i]);
- current_height += delta;
- if (current_height < 0) {
- free(heights);
- error_message = "panorama drops below baseline";
- return NULL;
- }
- if (delta == -1) heights[i] = current_height;
- if (current_height > *max_height) *max_height = current_height;
- }
- ++*max_height;
- return heights;
- }
- Panorama* Panorama_new(int width, int height, char *source, uint *heights)
- {
- Panorama *result;
- int data_size;
- int i;
- data_size = width * height;
- result = malloc(sizeof(*result) + data_size);
- result->width = width;
- result->height = height;
- memset(result->data, ' ', data_size);
- for (i = 0; i < width; ++i) {
- result->data[width * (height - heights[i] - 1) + i] = source[i];
- }
- return result;
- }
- Panorama* Panorama_from_string(char *source)
- {
- int width, height;
- uint *heights;
- Panorama *result = NULL;
- width = check_source(source);
- if (width == -1) {
- error_message = "illegal characters in argument";
- return NULL;
- }
- heights = calculate_heights(width, source, &height);
- if (heights) {
- result = Panorama_new(width, height, source, heights);
- free(heights);
- }
- return result;
- }
- void Panorama_print(Panorama *panorama)
- {
- int i, j;
- char *ptr;
- ptr = panorama->data;
- for (i = 0; i < panorama->height; ++i) {
- for (j = 0; j < panorama->width; ++j) {
- putchar(*ptr++);
- }
- putchar('\n');
- }
- }
- void Panorama_free(Panorama *panorama)
- {
- if (panorama) {
- panorama->width = panorama->height = 0;
- free(panorama);
- }
- }
- int main(int argc, char **argv)
- {
- Panorama *panorama;
- if (argc < 2) {
- printf("usage: %s panoramastring\n", argv[0]);
- return 1;
- }
- panorama = Panorama_from_string(argv[1]);
- if (panorama) {
- Panorama_print(panorama);
- Panorama_free(panorama);
- } else {
- puts(error_message);
- return 2;
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement