Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <memory.h>
- #undef uint
- #define uint unsigned int
- static inline void zero_buf(uint **buf, uint w, uint h) {
- for(uint i=0; i<h; i++)
- memset(buf[i], '\0', w * sizeof(**buf));
- }
- static inline void free_buf(void *_buf, uint h) {
- char **buf = (char **)_buf;
- if(!buf) return;
- for(uint i=0; i<h; i++)
- free(buf[i]);
- free(buf);
- }
- static inline void *alloc_zero_buf(uint w, uint h, uint elem_len) {
- char **buf;
- buf = malloc(h * sizeof(void *));
- if(!buf) return NULL;
- for(uint i=0; i<h; i++) {
- buf[i] = malloc(w * elem_len);
- if(!buf[i]) goto fail_free;
- memset(buf[i], '\0', w * elem_len);
- }
- return buf;
- fail_free:
- for(uint i=0; buf[i] && i<h; i++)
- free(buf[i]);
- free(buf);
- return NULL;
- }
- static inline char **read_input_buf(uint w, uint h) {
- char **buf;
- buf = alloc_zero_buf(w+2, h, sizeof(**buf)); /* w+2 for "\n\0" */
- if(!buf) {
- fprintf(stderr, "E: Alloc input buffer.\n");
- return NULL;
- }
- for(uint i=0; i<h; i++) {
- if(feof(stdin) || ferror(stdin)) {
- fprintf(stderr, "E: Incomplete buffer.\n");
- goto fail_free;
- }
- fgets(buf[i], w+2, stdin);
- if(strlen(buf[i]) != w+1) {
- fprintf(stderr, "E: Incomplete buffer line.\n");
- goto fail_free;
- }
- }
- return buf;
- fail_free:
- free_buf(buf, h);
- return NULL;
- }
- static inline uint draw(char **data_buf, uint **draw_buf, uint **depth_buf, uint y, uint x, uint w, uint h) {
- uint count = 1;
- if(depth_buf[y][x]) return 0;
- zero_buf(draw_buf, w, h);
- while(!depth_buf[y][x]) {
- depth_buf[y][x] = 1;
- draw_buf[y][x] = count++;
- switch(data_buf[y][x]) {
- case '<': x = (!x) ? w-1 : x-1; break;
- case '^': y = (!y) ? h-1 : y-1; break;
- case '>': x = (x == w-1) ? 0 : x+1; break;
- case 'v': y = (y == h-1) ? 0 : y+1; break;
- default:
- depth_buf[y][x] = 0;
- fprintf(stderr, "E: Invalid character at (%u,%u): '%c'.\n", x, y, data_buf[y][x]);
- return -1;
- }
- }
- if(!draw_buf[y][x]) return 0;
- return count-draw_buf[y][x];
- }
- int main(int argc, char **argv)
- {
- int res = -1;
- uint w = 0, h = 0;
- uint max_len = 0;
- char **data_buf = NULL;
- uint **draw_buf = NULL;
- uint **depth_buf = NULL;
- if(fscanf(stdin, "%u %u", &w, &h) != 2 || !w || !h) {
- fprintf(stderr, "E: Invalid size specified.\n");
- return -1;
- }
- fgetc(stdin); /* Trailing \n */
- data_buf = read_input_buf(w, h);
- if(!data_buf) {
- fprintf(stderr, "E: Read input buffer.\n");
- goto free_exit;
- }
- draw_buf = alloc_zero_buf(w, h, sizeof(**draw_buf));
- if(!draw_buf) {
- fprintf(stderr, "E: Alloc draw buffer.\n");
- goto free_exit;
- }
- depth_buf = alloc_zero_buf(w, h, sizeof(**depth_buf));
- if(!depth_buf) {
- fprintf(stderr, "E: Alloc depth buffer.\n");
- goto free_exit;
- }
- for(uint i=0; i<h; i++) {
- for(uint j=0; j<w; j++) {
- uint new_len = 0;
- new_len = draw(data_buf, draw_buf, depth_buf, i, j, w, h);
- if(new_len < 0)
- goto free_exit;
- if(new_len > max_len)
- max_len = new_len;
- }
- }
- fprintf(stdout, "Max loop: %u.\n", max_len);
- res = 0;
- free_exit:
- free_buf(data_buf, h);
- free_buf(draw_buf, h);
- free_buf(depth_buf, h);
- return res;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement