Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
michaeladler committed Dec 4, 2023
1 parent 472132b commit 4d26b82
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 28 deletions.
31 changes: 29 additions & 2 deletions include/aoc/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,33 @@
* @return The parsed positive integer on success, or a negative number on
* error.
*/
int parse_positive_integer(const char *buf, size_t *pos);
int aoc_parse_positive(const char *buf, size_t *pos);

void skip_ws(const char *buf, size_t *pos);
/**
* Skips over any whitespace characters in the buffer starting from the position
* pointed by pos.
*
* @param buf The buffer to parse for whitespace characters.
* @param pos Pointer to the size_t variable that holds the starting position
* for skipping whitespace and is updated to the position after the skipped
* whitespace.
*
* @note The function updates *pos to the position immediately following the
* last whitespace character encountered. If there are no whitespace characters,
* *pos remains unchanged.
*/
void aoc_parse_skip_ws(const char *buf, size_t *pos);

/**
* Searches for the first occurrence of the specified character (needle) in the
* buffer starting from the position pointed by pos.
*
* @param buf The buffer in which to search for the character.
* @param pos Pointer to the size_t variable that holds the starting position
* for the search and is updated to the position of the found character.
* @param needle The character to search for in the buffer.
*
* @note The function updates *pos to the position of the first occurrence of
* needle. If the needle is not found, *pos is set to the length of the buffer.
*/
void aoc_parse_seek(const char *buf, size_t *pos, char needle);
16 changes: 12 additions & 4 deletions lib/aoc/parser.c
Original file line number Diff line number Diff line change
@@ -1,27 +1,35 @@
#include <assert.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>

#include "aoc/parser.h"

int parse_positive_integer(const char *buf, size_t *pos) {
int aoc_parse_positive(const char *buf, size_t *pos) {
int result = 0;
size_t i = *pos;
while (buf[i] >= '0' && buf[i] <= '9') {
result = (result * 10) + (buf[i] - '0');
i++;
}
if (i == *pos) {
// error, nothing parsed
if (i == *pos) { // error, nothing parsed
return -1;
}
*pos = i;
return result;
}

void skip_ws(const char *buf, size_t *pos) {
void aoc_parse_skip_ws(const char *buf, size_t *pos) {
int i = *pos;
while (buf[i] == ' ') i++;
*pos = i;
assert(buf[*pos] != ' ');
}

void aoc_parse_seek(const char *buf, size_t *pos, char needle) {
int i = *pos;
while (buf[i] != needle) i++;
*pos = i;
assert(buf[*pos] == needle);
}
6 changes: 3 additions & 3 deletions src/day02/solve.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ void solve(const char *buf, size_t buf_size, Solution *result) {
long red_min = 0, green_min = 0, blue_min = 0;
while (pos < buf_size && buf[pos] != ':') pos++;
while (true) {
skip_ws(buf, &pos);
int amount = parse_positive_integer(buf, &pos);
skip_ws(buf, &pos);
aoc_parse_skip_ws(buf, &pos);
int amount = aoc_parse_positive(buf, &pos);
aoc_parse_skip_ws(buf, &pos);
if (buf[pos] == 'r') {
log_debug("red %d", amount);
red_min = MAX(red_min, amount);
Expand Down
28 changes: 9 additions & 19 deletions src/day04/solve.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,50 +14,40 @@ void solve(const char *buf, size_t buf_size, Solution *result) {
int mine_cards[32];
int mine_cards_idx = 0;

// seek past ':'
while (buf[pos] != ':') pos++;
aoc_parse_seek(buf, &pos, ':');
pos++;

while (true) {
skip_ws(buf, &pos);
int value = parse_positive_integer(buf, &pos);
aoc_parse_skip_ws(buf, &pos);
int value = aoc_parse_positive(buf, &pos);
if (value <= 0) break;
winning_cards[winning_cards_idx++] = value;
}

// seek past '|'
while (buf[pos] != '|') pos++;
aoc_parse_seek(buf, &pos, '|');
pos++;

while (true) {
skip_ws(buf, &pos);
int value = parse_positive_integer(buf, &pos);
aoc_parse_skip_ws(buf, &pos);
int value = aoc_parse_positive(buf, &pos);
if (value <= 0) break;
mine_cards[mine_cards_idx++] = value;
}
pos++; // newline

int_tim_sort(winning_cards, winning_cards_idx);
int_tim_sort(mine_cards, mine_cards_idx);
int i = 0, j = 0;
int count = 0;
while (i < winning_cards_idx && j < mine_cards_idx) {
log_debug("comparing %d and %d", winning_cards[i], mine_cards[j]);
for (int i = 0, j = 0; i < winning_cards_idx && j < mine_cards_idx;) {
if (winning_cards[i] == mine_cards[j]) {
count++;
i++;
j++;
count++, i++, j++;
} else if (winning_cards[i] < mine_cards[j]) {
i++;
} else {
j++;
}
}
if (count > 0) {
int score = 1 << (count - 1);
log_debug("count: %d, score: %d", count, score);
part1 += score;
}
if (count > 0) { part1 += 1 << (count - 1); }
}
stbsp_snprintf(result->part1, sizeof(result->part1), "%d", part1);
stbsp_snprintf(result->part2, sizeof(result->part2), "%d", part2);
Expand Down

0 comments on commit 4d26b82

Please sign in to comment.