147 lines
3.1 KiB
C
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;
|
|
}
|