diff --git a/c/2022/5/supply_stacks.c b/c/2022/5/supply_stacks.c new file mode 100644 index 0000000..902f479 --- /dev/null +++ b/c/2022/5/supply_stacks.c @@ -0,0 +1,146 @@ +#include +#include +#include + +#include "../../lib/aoc.h" + +#define NUM_STACKS 9 +#define INITIAL_STACK_HEIGHT 8 +#define MAX_STACK_HEIGHT 60 + +typedef struct Stack { + char crates[MAX_STACK_HEIGHT]; + int height; +} Stack; + +enum ParseStage { CRATES, COLUMNS, MOVES }; + +void print_stack(Stack *stack) { + for (int i = 0; i < stack->height; i++) { + printf("%c", stack->crates[i]); + } + printf(":%d\n", stack->height); +} + +void print_stack_head(Stack *stack) { + printf("%c", stack->crates[stack->height - 1]); +} + +char pop(Stack *stack) { + stack->height--; + return stack->crates[stack->height]; +} + +void push(char crate, Stack *stack) { + stack->crates[stack->height] = crate; + stack->height++; +} + +void move(int count, Stack *from, Stack *to) { + for (int i = 0; i < count; i++) { + push(pop(from), to); + } +} + +void move2(int count, Stack *from, Stack *to) { + char crates[count]; + int index = 0; + for (int i = 0; i < count; i++) { + crates[index++] = pop(from); + } + for (int i = 0; i < count; i++) { + push(crates[(index--) - 1], to); + } +} + +int main() { + enum ParseStage p = CRATES; + + char *line; + int stack_height = INITIAL_STACK_HEIGHT - 1; + + Stack stacks[NUM_STACKS + 1]; + for (int i = 1; i <= NUM_STACKS; i++) { + for (int j = 0; j < MAX_STACK_HEIGHT; j++) { + stacks[i].crates[j] = '\0'; + } + stacks[i].height = -1; + } + + while ((line = aoc_read_line()) != NULL) { + switch(p) { + case CRATES: + if (line[1] == '1') { + p = COLUMNS; + break; + } + for (int i = 1; i <= NUM_STACKS; i++) { + stacks[i].crates[stack_height] = line[(i * 4) - 3]; + if (stacks[i].crates[stack_height] != ' ' && stacks[i].height == -1) { + stacks[i].height = stack_height + 1; + } + } + stack_height--; + break; + case COLUMNS: + p = MOVES; + break; + case MOVES: + int count, from, to; + sscanf(line, "move %d from %d to %d", &count, &from, &to); + move(count, &(stacks[from]), &(stacks[to])); + break; + } + } + + printf("Part 1: "); + for (int i = 1; i < NUM_STACKS + 1; i++) { + print_stack_head(&(stacks[i])); + } + printf("\nPart 2: "); + + for (int i = 1; i <= NUM_STACKS; i++) { + for (int j = 0; j < MAX_STACK_HEIGHT; j++) { + stacks[i].crates[j] = '\0'; + } + stacks[i].height = -1; + } + + aoc_reset_read_line(); + p = CRATES; + stack_height = INITIAL_STACK_HEIGHT - 1; + + while ((line = aoc_read_line()) != NULL) { + switch(p) { + case CRATES: + if (line[1] == '1') { + p = COLUMNS; + break; + } + + for (int i = 1; i <= NUM_STACKS; i++) { + stacks[i].crates[stack_height] = line[(i * 4) - 3]; + if (stacks[i].crates[stack_height] != ' ' && stacks[i].height == -1) { + stacks[i].height = stack_height + 1; + } + } + stack_height--; + break; + case COLUMNS: + p = MOVES; + break; + case MOVES: + int count, from, to; + sscanf(line, "move %d from %d to %d", &count, &from, &to); + move2(count, &(stacks[from]), &(stacks[to])); + break; + } + } + for (int i = 1; i < NUM_STACKS + 1; i++) { + print_stack_head(&(stacks[i])); + } + printf("\n"); + + aoc_free(); + return 0; +}