Skip to content
Snippets Groups Projects
Verified Commit 4fcdee9e authored by mirabilos's avatar mirabilos Committed by mirabilos
Browse files

it now passes all tests but still too high for prod

parent 13f110e9
No related branches found
No related tags found
No related merge requests found
#include <err.h> #include <err.h>
#include <limits.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
...@@ -6,11 +7,15 @@ ...@@ -6,11 +7,15 @@
#include "inputs.h" #include "inputs.h"
static unsigned char FF[H][W]; static unsigned char FF[H][W];
static unsigned char FF2[H][W];
#define F(y,x) FF[y][x] #define F(y,x) FF[y][x]
#define F2w(y,x) FF2[y][x]
#define F2(y,x) (FF2[y][x] & 0x7FU)
static unsigned long long total = 0; static unsigned long long total = 0;
static void getfield(int y, int x); static void getfield(int y, int x);
static unsigned int getfield2(int y, int x, unsigned char xc2);
int int
main(void) main(void)
...@@ -60,10 +65,17 @@ recurse(int y, int x) ...@@ -60,10 +65,17 @@ recurse(int y, int x)
static void static void
getfield(int y, int x) getfield(int y, int x)
{ {
int y0, x0; int y0, x0, yl, xl;
int extent[H][2];
unsigned char xc2;
for (yl = 0; yl < H; ++yl) {
extent[yl][0] = INT_MAX;
extent[yl][1] = -1;
}
oc = F(y, x); oc = F(y, x);
xc = oc | 0x80U; xc = oc | 0x80U;
xc2 = xc & 0x7FU;
area = 0; area = 0;
printf("BEGIN '%c' @ (%d, %d)\n", oc, y, x); printf("BEGIN '%c' @ (%d, %d)\n", oc, y, x);
reclvl = 0; reclvl = 0;
...@@ -88,6 +100,10 @@ getfield(int y, int x) ...@@ -88,6 +100,10 @@ getfield(int y, int x)
x0 = x; x0 = x;
sides = 1; sides = 1;
walk_north: walk_north:
if (x < extent[y][0])
extent[y][0] = x;
if (x > extent[y][1])
extent[y][1] = x;
printf("│↑(%d, %d) ", y, x); printf("│↑(%d, %d) ", y, x);
if (F(y - 1, x) != xc) { if (F(y - 1, x) != xc) {
/* west side ended, north side begins */ /* west side ended, north side begins */
...@@ -117,6 +133,10 @@ getfield(int y, int x) ...@@ -117,6 +133,10 @@ getfield(int y, int x)
printf("↑\n"); printf("↑\n");
goto walk_north; goto walk_north;
walk_east: walk_east:
if (x < extent[y][0])
extent[y][0] = x;
if (x > extent[y][1])
extent[y][1] = x;
printf("│→(%d, %d) ", y, x); printf("│→(%d, %d) ", y, x);
if (F(y, x + 1) != xc) { if (F(y, x + 1) != xc) {
/* north side ended, east side begins */ /* north side ended, east side begins */
...@@ -142,6 +162,10 @@ getfield(int y, int x) ...@@ -142,6 +162,10 @@ getfield(int y, int x)
printf("→\n"); printf("→\n");
goto walk_east; goto walk_east;
walk_south: walk_south:
if (x < extent[y][0])
extent[y][0] = x;
if (x > extent[y][1])
extent[y][1] = x;
printf("│↓(%d, %d) ", y, x); printf("│↓(%d, %d) ", y, x);
if (F(y + 1, x) != xc) { if (F(y + 1, x) != xc) {
/* east side ended, south side begins */ /* east side ended, south side begins */
...@@ -167,6 +191,10 @@ getfield(int y, int x) ...@@ -167,6 +191,10 @@ getfield(int y, int x)
printf("↓\n"); printf("↓\n");
goto walk_south; goto walk_south;
walk_west: walk_west:
if (x < extent[y][0])
extent[y][0] = x;
if (x > extent[y][1])
extent[y][1] = x;
printf("│←(%d, %d) ", y, x); printf("│←(%d, %d) ", y, x);
if (F(y, x - 1) != xc) { if (F(y, x - 1) != xc) {
if (y == y0 && x == x0) { if (y == y0 && x == x0) {
...@@ -198,5 +226,193 @@ getfield(int y, int x) ...@@ -198,5 +226,193 @@ getfield(int y, int x)
walk_finished: walk_finished:
printf("└─END '%c' @ (%d, %d) → area %llu, sides %llu\n", printf("└─END '%c' @ (%d, %d) → area %llu, sides %llu\n",
oc, y, x, area, sides); oc, y, x, area, sides);
memcpy(FF2, FF, sizeof(FF));
for (yl = 0; yl < H; ++yl) {
if (!(extent[yl][0] < extent[yl][1]))
continue;
for (xl = extent[yl][0]; xl <= extent[yl][1]; ++xl)
if (F2(yl,xl) != xc2 && !(F2(yl,xl) & 0x20U))
sides += getfield2(yl, xl, xc2);
}
printf("→ area %llu, sides %llu\n", area, sides);
total += area * sides; total += area * sides;
} }
static unsigned long long area2;
static unsigned long long sides2;
static int
recurse2(int y, int x, unsigned char xc2)
{
unsigned char c;
++reclvl;
F2w(y, x) |= 0x20U;
++area2;
#undef try
#define try(Y,X,dir) do { \
if ((c = F2(Y, X)) == oc) { \
printf("\t│%*s" dir " recursing @ (%d, %d)\n", \
reclvl, "", Y, X); \
if (recurse2(Y, X, xc2)) \
return (1); \
} else if (c != xc2) \
return (1); \
} while (/* CONSTCOND */ 0)
try(y - 1, x, "up");
try(y, x + 1, "right");
try(y + 1, x, "down");
try(y, x - 1, "left");
--reclvl;
return (0);
}
static unsigned int
getfield2(int y, int x, unsigned char xc2)
{
int y0, x0;
oc = F2(y, x);
xc = oc | 0x20U;
area2 = 0;
printf("\tBEGIN '%c' @ (%d, %d)\n", oc, y, x);
reclvl = 0;
if (recurse2(y, x, xc2)) {
printf("\tNOPE\n");
return (0);
}
if (area2 == 1) {
/* this uncomplicates the loop below */
sides2 = 4;
goto walk_finished;
}
fll: /* find a lower left corner */
if (F2(y + 1, x) == xc) {
++y;
goto fll;
}
if (F2(y, x - 1) == xc) {
--x;
goto fll;
}
/* now we know a side begins at our left (west) */
y0 = y;
x0 = x;
sides2 = 1;
walk_north:
printf("\t│↑(%d, %d) ", y, x);
if (F2(y - 1, x) != xc) {
/* west side ended, north side begins */
printf("┌→\n");
++sides2;
goto walk_east;
}
--y;
// if (y == y0 && x == x0) {
// printf("---> (%d, %d) fin\n", y, x);
// goto walk_finished;
// }
if (F2(y, x - 1) == xc) {
/* west side ended */
/* turn left, go forward (W), south side begins */
printf("\033[1m←┐\033[0m\n");
--x;
// if (y == y0 && x == x0)
// goto walk_finished;
++sides2;
goto walk_west;
}
if (y == y0 && x == x0) {
printf("---> (%d, %d) fin\n", y, x);
goto walk_finished;
}
printf("↑\n");
goto walk_north;
walk_east:
printf("\t│→(%d, %d) ", y, x);
if (F2(y, x + 1) != xc) {
/* north side ended, east side begins */
printf("─┐̬\n");
++sides2;
goto walk_south;
}
++x;
// if (y == y0 && x == x0) {
// printf("---> (%d, %d) fin\n", y, x);
// goto walk_finished;
// }
if (F2(y - 1, x) == xc) {
/* north side ended */
/* turn left, go forward (N), west side begins */
printf("\033[1m─┘̂\033[0m\n");
--y;
if (y == y0 && x == x0)
goto walk_finished;
++sides2;
goto walk_north;
}
printf("→\n");
goto walk_east;
walk_south:
printf("\t│↓(%d, %d) ", y, x);
if (F2(y + 1, x) != xc) {
/* east side ended, south side begins */
printf("←┘\n");
++sides2;
goto walk_west;
}
++y;
// if (y == y0 && x == x0) {
// printf("---> (%d, %d) fin\n", y, x);
// goto walk_finished;
// }
if (F2(y, x + 1) == xc) {
/* east side ended */
/* turn left, go forward (E), north side begins */
printf("\033[1m└→\033[0m\n");
++x;
// if (y == y0 && x == x0)
// goto walk_finished;
++sides2;
goto walk_east;
}
printf("↓\n");
goto walk_south;
walk_west:
printf("\t│←(%d, %d) ", y, x);
if (F2(y, x - 1) != xc) {
if (y == y0 && x == x0) {
printf("---> (%d, %d) fin\n", y, x);
goto walk_finished;
}
/* south side ended, west side begins */
printf("└̂─\n");
++sides2;
goto walk_north;
}
--x;
// if (y == y0 && x == x0) {
// printf("---> (%d, %d) fin\n", y, x);
// goto walk_finished;
// }
if (F2(y + 1, x) == xc) {
/* south side ended */
/* turn left, go forward (S), east side begins */
printf("\033[1m┌̬─\033[0m\n");
++y;
// if (y == y0 && x == x0)
// goto walk_finished;
++sides2;
goto walk_south;
}
printf("←\n");
goto walk_west;
walk_finished:
printf("\t└─END '%c' @ (%d, %d) → area %llu, sides %llu\n",
oc, y, x, area2, sides2);
return (sides2);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment