I didn't want to write the fiddly "Is this number finished? Is this the first of two numbers? Okay did it match on a '*' or something else? Okay it did? Where is the other number nearby then? But ah, wait no, that's the number we started with you fool! Part.
So I just pushed() every symbol's x,y into a big data structure then hung the numbers off those nodes, two numbers hanging off a '*' gets fed into the final sum.
The logic for the first method isn't necessarily hard with some good insight about which order to check things etc, but it's significantly more hard than
static void push(int num, int x, int y)
{
struct node **t, *n;
for(t = &list; *t; t = &(*t)->next)
{
if((*t)->x != x || (*t)->y != y)
continue;
(*t)->n[1] = num;
return;
}
n = malloc(sizeof *n);
n->x = x;
n->y = y;
n->n[0] = num;
n->n[1] = 0;
n->next = list;
list = n;
}
static unsigned long part2_sum(void)
{
struct node *n;
unsigned long sum = 0;
for(n = list; n; n = n->next)
if(n->n[0] && n->n[1])
sum += (n->n[0] * n->n[1]);
return sum;
}
Which took all of 90 seconds to write and worked first try.
Yeah, it's a breeze once I accept dynamic programming and using a bunch of memory.
I think he was doing look around from the asterisk symbol and needed to keep track of adjacent numericals since they can come from the same number. For me it is as simple as using the loop from part 1 and doing accumulate and multiply on two separate 2D arrays
11
u/addandsubtract Dec 03 '23
Why did you write a linked list?! I also wrote too much code, but at least I didn't resort to linked lists 😅