#include #include #include #include #include #define MAX_LINE 512 #define NUM_LINES 512 #define NUM_STACKS 9 struct Stack { int top; char items[MAX_LINE]; }; typedef struct Stack stack; // Push onto a stack void push(stack *st, char crate) { if (st->top == MAX_LINE) { fprintf(stderr, "Stack is full\n"); } else { st->top++; st->items[st->top] = crate; } } // Pop from a stack char pop(stack *st) { char c = '\0'; if (st->top == -1) { fprintf(stderr, "Stack is empty\n"); return -1; } else { c = st->items[st->top]; st->items[st->top] = '\0'; st->top--; return c; } } // Prints top index, top item, and each stack void print_crates(stack **crates) { for (size_t i = 0; i < NUM_STACKS; i++) { printf("\nStack %lu - Top: %d" "\n Top Crate: %c" "\n Crates: %s\n", i + 1, crates[i]->top, crates[i]->items[crates[i]->top], crates[i]->items); fflush(stdout); } } // Allocate memeory and initialize stacks of crates with their initial order stack **crates_init() { stack **crates = calloc(NUM_STACKS, sizeof(stack *)); if (crates == NULL) { return NULL; } for (int i = 0; i < NUM_STACKS; i++) { crates[i] = (stack *)malloc(sizeof(stack)); if (crates[i] == NULL) { return NULL; } crates[i]->top = -1; memset(crates[i]->items, 0, MAX_LINE); } crates[0]->top = 7; strcpy(crates[0]->items, "PFMQWGRT"); crates[1]->top = 2; strcpy(crates[1]->items, "HFR"); crates[2]->top = 7; strcpy(crates[2]->items, "PZRVGHSD"); crates[3]->top = 6; strcpy(crates[3]->items, "QHPBFWG"); crates[4]->top = 4; strcpy(crates[4]->items, "PSMJH"); crates[5]->top = 7; strcpy(crates[5]->items, "MZTHSRPL"); crates[6]->top = 5; strcpy(crates[6]->items, "PTHNML"); crates[7]->top = 3; strcpy(crates[7]->items, "FDQR"); crates[8]->top = 6; strcpy(crates[8]->items, "DSCNLPH"); return crates; } // Parses moves from input file and stores in an array void parse_moves(FILE *file, int moves[NUM_LINES][3], size_t *line_num) { int idx = 0; char line[MAX_LINE] = {0}; while (fgets(line, MAX_LINE, file) != NULL) { if (line[0] != 'm') { memset(line, 0, MAX_LINE); continue; } for (size_t i = 0; i < strlen(line); i++) { if (isdigit(line[i])) { if (isdigit(line[i + 1])) { char temp[2]; temp[0] = line[i]; temp[1] = line[i + 1]; moves[*line_num][idx] = atoi(temp); i++; } else { moves[*line_num][idx] = atoi(&line[i]); } idx++; if (idx > 2) { *line_num += 1; idx = 0; } } } memset(line, 0, MAX_LINE); } } // Part 1 - Processes each move stored in the moves array one crate at a time void part1_moves(stack **crates, int moves[NUM_LINES][3], size_t move_count) { size_t idx = 0; while (idx <= move_count) { for (int i = 0; i < moves[idx][0]; i++) { char c = pop(crates[moves[idx][1] - 1]); if (c == -1) { fprintf(stderr, "part1_moves: move num: %lu", idx); continue; } push(crates[moves[idx][2] - 1], c); } idx++; } } void crates_free(stack **crates) { for (size_t i = 0; i < NUM_STACKS; i++) { free(crates[i]); } free(crates); } // Part 2 - Processes the moves array multiple crates at a time void part2_moves(stack **crates, int moves[NUM_LINES][3], size_t move_count) { size_t idx = 0; while (idx <= move_count) { char c_arr[moves[idx][0]]; memset(c_arr, 0, moves[idx][0]); for (int i = 0; i < moves[idx][0]; i++) { c_arr[i] = pop(crates[moves[idx][1] - 1]); if (c_arr[i] == -1) { fprintf(stderr, "part2_moves: move num: %lu", idx); continue; } } for (int j = moves[idx][0] - 1; j >= 0; j--) { push(crates[moves[idx][2] - 1], c_arr[j]); } idx++; } } int main(int argc, char *argv[]) { if (argc != 2) { fprintf(stderr, "USAGE: %s input_file\n", argv[0]); return 1; } FILE *file = fopen(argv[1], "r"); if (!file) { perror("fopen"); return 1; } size_t move_count = 0; int moves[NUM_LINES][3] = {0}; stack **crates = crates_init(); if (crates == NULL) { fprintf(stderr, "Part 2: unable to allocate memory for crates\n"); fclose(file); return 1; } printf("\n--- PART 1 ---\n"); parse_moves(file, moves, &move_count); part1_moves(crates, moves, move_count); print_crates(crates); printf("\n--- PART 2 ---\n"); crates_free(crates); crates = crates_init(); if (crates == NULL) { fprintf(stderr, "Part 2: unable to allocate memory for crates\n"); fclose(file); return 1; } part2_moves(crates, moves, move_count); print_crates(crates); crates_free(crates); fclose(file); return 0; }