aoc_omni/c/2022/5/supply_stacks.c
2024-11-30 23:25:56 -05:00

147 lines
3.1 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}