Browse Source

day6p1

master
mid-kid 6 years ago
parent
commit
dd5bf987e4
  1. 12
      day6p1/Makefile
  2. 50
      day6p1/input
  3. 151
      day6p1/main.c

12
day6p1/Makefile

@ -0,0 +1,12 @@
CFLAGS := -Wall -Wextra -std=c17 -D_GNU_SOURCE
LIBS := glib-2.0
CFLAGS += $(shell pkg-config --cflags $(LIBS))
LDLIBS := $(shell pkg-config --libs $(LIBS))
.PHONY: all
all: main
.PHONY: clean
clean:
rm -f main

50
day6p1/input

@ -0,0 +1,50 @@
63, 142
190, 296
132, 194
135, 197
327, 292
144, 174
103, 173
141, 317
265, 58
344, 50
184, 238
119, 61
329, 106
70, 242
272, 346
312, 166
283, 351
286, 206
57, 225
347, 125
152, 186
131, 162
45, 299
142, 102
61, 100
111, 218
73, 266
350, 173
306, 221
42, 284
150, 122
322, 286
346, 273
75, 354
68, 124
194, 52
92, 44
77, 98
77, 107
141, 283
87, 306
184, 110
318, 343
330, 196
303, 353
268, 245
180, 220
342, 337
127, 107
203, 127

151
day6p1/main.c

@ -0,0 +1,151 @@
#include <stdio.h>
#include <glib.h>
struct coord {
int x;
int y;
};
struct rect {
int x;
int y;
int w;
int h;
};
struct coord *parse_coords(const char *fname, unsigned *len)
{
FILE *f = fopen(fname, "r");
if (!f) {
perror(fname);
return NULL;
}
GArray *array = g_array_new(FALSE, FALSE, sizeof(struct coord));
*len = 0;
char *line = NULL;
size_t line_len = 0;
while (getline(&line, &line_len, f) != -1) {
struct coord coord = {0};
if (sscanf(line, "%d, %d", &coord.x, &coord.y) != 2) continue;
g_array_append_val(array, coord);
(*len)++;
}
free(line);
fclose(f);
struct coord *res = (struct coord *)g_array_free(array, FALSE);
return res;
}
struct rect find_limit(struct coord *coords, unsigned len)
{
struct rect rect = {0};
if (!len) return rect;
int xmax = rect.x = coords->x;
int ymax = rect.y = coords->y;
for (struct coord *coord = coords + 1; coord < coords + len; coord++) {
if (coord->x < rect.x) rect.x = coord->x;
if (coord->y < rect.y) rect.y = coord->y;
if (coord->x > xmax) xmax = coord->x;
if (coord->y > ymax) ymax = coord->y;
}
rect.w = xmax - rect.x + 1;
rect.h = ymax - rect.y + 1;
return rect;
}
unsigned *count_influence(struct coord *coords, unsigned coords_len, struct rect area)
{
unsigned *tally = g_new0(unsigned, coords_len);
for (int y = area.y; y < area.y + area.h; y++) {
for (int x = area.x; x < area.x + area.w; x++) {
unsigned tile = 0;
unsigned shortest = area.h * area.w;
// Find the point with the shortest distance
for (unsigned i = 0; i < coords_len && shortest; i++) {
unsigned dist = abs(coords[i].x - x) + abs(coords[i].y - y);
if (dist < shortest) {
shortest = dist;
tile = i + 1;
}
}
if (!tile) continue;
// Look for another point with the same distance
for (unsigned i = 0; i < coords_len && shortest; i++) {
unsigned dist = abs(coords[i].x - x) + abs(coords[i].y - y);
if (tile - 1 == i) continue;
if (dist == shortest) {
tile = 0;
break;
}
}
//printf("%c", tile ? 'a' + tile - 1 : '.');
if (!tile) continue;
if (tally[tile - 1] < UINT_MAX) tally[tile - 1]++;
}
//printf("\n");
}
return tally;
}
int main()
{
unsigned coords_len;
struct coord *coords = parse_coords("input", &coords_len);
if (!coords) return 1;
/*
* NOTE: This method I'm using to figure our the biggest non-infinite
* influence range for a coordinate is suboptimal and won't work for all inputs.
* I could try to figure out how to calcluate it properly or a better algorithm
* than checking literally each tile in a defined area, but I'm too lazy.
* If it works for my input it's fine ;)
*/
struct rect limit = find_limit(coords, coords_len);
printf("%d,%d\n%d,%d\n",
limit.x, limit.y,
limit.x + limit.w - 1, limit.y + limit.h - 1);
unsigned *tally = count_influence(coords, coords_len, limit);
// Disqualify any coords that don't compete with anything.
for (unsigned a = 0; a < coords_len; a++) {
int north = 0;
int south = 0;
int east = 0;
int west = 0;
for (unsigned b = 0; b < coords_len; b++) {
if (coords[b].y < coords[a].y) north = 1;
if (coords[b].y > coords[a].y) south = 1;
if (coords[b].x > coords[a].x) east = 1;
if (coords[b].x < coords[a].x) west = 1;
}
if (!north || !south || !east || !west) tally[a] = 0;
}
// Find the largest
unsigned largest = 0;
for (unsigned *i = tally; i < tally + coords_len; i++) {
if (*i > largest) largest = *i;
}
printf("Largest: %u\n", largest);
g_free(tally);
g_free(coords);
return 0;
}
Loading…
Cancel
Save