| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdbool.h>
- #define IMP
- #include "../../file.h"
- #include "../../str.h"
- struct point {
- long x, y;
- };
- int
- main(int argc, char *argv[])
- {
- enum file_err ferr;
- long res = 0;
- size_t i = 0;
- size_t j = 0;
- struct point p = {0};
- struct str str_input = {0};
- char *raw_input = NULL;
- size_t raw_input_size = 0;
- raw_input = (char *) file_read_all("./input.txt",
- &raw_input_size,
- &ferr);
- if ( ferr != FILE_ERR_OK ) {
- fprintf(stderr, "Failed to open file: %s\n",
- file_err_to_cstr(ferr));
- exit(EXIT_FAILURE);
- }
- str_input = str_from_cstr(raw_input, raw_input_size);
- if ( argc == 1 ) {
- struct point *uniqs = NULL;
- size_t uniqs_size = 0;
- struct point *points = NULL;
- size_t points_size = 1;
- points = calloc(str_input.size + 1, sizeof(*points));
- for ( i = 0; i < str_input.size; ++i ) {
- struct point *it = (points + i + 1);
- p = points[i];
- *it = p;
- switch ( str_input.data[i] ) {
- case '>':
- ++it->x;
- break;
- case '^':
- --it->y;
- break;
- case '<':
- --it->x;
- break;
- case 'v':
- ++it->y;
- break;
- }
- ++points_size;
- }
- uniqs = calloc(points_size, sizeof(*uniqs));
- for ( i = 0; i < points_size; ++i ) {
- p = points[i];
- for ( j = 0; j < uniqs_size; ++j ) {
- if ( uniqs[j].x == p.x && uniqs[j].y == p.y ) {
- goto outer_continue_p1;
- }
- }
- uniqs[uniqs_size++] = p;
- outer_continue_p1: ;
- }
- res = (long) uniqs_size;
- free(points);
- free(uniqs);
- } else {
- struct point *uniqs = NULL;
- size_t uniqs_size = 0;
- struct point *rs = NULL;
- size_t rs_size = 0;
- struct point *hs = NULL;
- size_t hs_size = 0;
- /* Need only half of str_points.size, but who cares. */
- rs = calloc(str_input.size, sizeof(*rs));
- hs = calloc(str_input.size, sizeof(*hs));
- for ( i = 0; i < str_input.size; ++i ) {
- struct point *it = NULL;
- if ( (i & 1) == 0 ) {
- p = hs[hs_size];
- it = &hs[(hs_size++) + 1];
- } else {
- p = rs[rs_size];
- it = &rs[(rs_size++) + 1];
- }
- *it = p;
- switch ( str_input.data[i] ) {
- case '>':
- ++it->x;
- break;
- case '^':
- --it->y;
- break;
- case '<':
- --it->x;
- break;
- case 'v':
- ++it->y;
- break;
- }
- }
- uniqs = calloc(rs_size + hs_size, sizeof(*uniqs));
- for ( i = 0; i < str_input.size; ++i ) {
- if ( i < hs_size ) {
- p = hs[i];
- for ( j = 0; j < uniqs_size; ++j ) {
- if ( uniqs[j].x == p.x && uniqs[j].y == p.y ) {
- goto not_uniq_1;
- }
- }
- uniqs[uniqs_size++] = p;
- not_uniq_1: ;
- }
- if ( i < rs_size ) {
- p = rs[i];
- for ( j = 0; j < uniqs_size; ++j ) {
- if ( uniqs[j].x == p.x && uniqs[j].y == p.y ) {
- goto not_uniq_2;
- }
- }
- uniqs[uniqs_size++] = p;
- not_uniq_2: ;
- }
- }
- res = (long) uniqs_size;
- free(hs);
- free(rs);
- free(uniqs);
- }
- printf("Result: %ld\n", res);
- free(raw_input);
- (void) argc; (void) argv;
- return 0;
- }
|