Created
December 4, 2024 17:21
-
-
Save willkill07/ea3234c33edda64258727e0dd9a705f0 to your computer and use it in GitHub Desktop.
Advent of Code 2024 Day 3 in C (custom parser)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <assert.h> | |
#include <stdbool.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <fcntl.h> | |
#include <sys/mman.h> | |
#include <sys/stat.h> | |
#include <unistd.h> | |
enum state_type { | |
Skip, SawM, SawU, SAW_L, SawD, SawO, SawN, SawT, | |
SawComma, SawQuote, | |
SawDigitA, SawDigitB, | |
SawParenMul, SawParenDo, SawParenDont | |
}; | |
int main(int argc, char* argv[]) { | |
if (argc == 1) { | |
exit(1); | |
} | |
int fd = open(argv[1], O_RDONLY); | |
if (fd == -1) { | |
exit(1); | |
} | |
struct stat s; | |
if (fstat(fd, &s) == -1) { | |
exit(1); | |
} | |
char const* addr = (char const*)mmap(nullptr, (size_t)s.st_size, PROT_READ, MAP_PRIVATE | MAP_FILE, fd, 0); | |
if (addr == nullptr) { | |
exit(1); | |
} | |
char const* end = addr + s.st_size; | |
int a = 0, b = 0, part1 = 0, part2 = 0, valid = 1; | |
enum state_type state = Skip; | |
for (char const* c = addr; c != end; ++c) { | |
switch(*c) { | |
case 'm': state = SawM; continue; | |
case 'u': if (state == SawM) state = SawU; continue; | |
case 'l': if (state == SawU) state = SAW_L; continue; | |
case 'd': state = SawD; continue; | |
case 'o': if (state == SawD) state = SawO; continue; | |
case 'n': if (state == SawO) state = SawN; continue; | |
case '\'': if (state == SawN) state = SawQuote; continue; | |
case 't': if (state == SawQuote) state = SawT; continue; | |
case ',': if (state == SawDigitA) state = SawComma; continue; | |
case '(': | |
switch (state) { | |
case SAW_L: state = SawParenMul; a = 0; b = 0; continue; | |
case SawO: state = SawParenDo; continue; | |
case SawT: state = SawParenDont; continue; | |
default: break; | |
} | |
break; | |
case ')': | |
switch (state) { | |
case SawDigitB: part1 += a * b; if (valid) part2 += a * b; break; | |
case SawParenDo: valid = true; break; | |
case SawParenDont: valid = false; break; | |
default: break; | |
} | |
break; | |
default: | |
if ('0' <= *c && *c <= '9') { | |
switch (state) { | |
case SawParenMul: state = SawDigitA; [[fallthrough]]; | |
case SawDigitA: a = a * 10 + (*c - '0'); continue; | |
case SawComma: state = SawDigitB; [[fallthrough]]; | |
case SawDigitB: b = b * 10 + (*c - '0'); continue; | |
default: break; | |
} | |
} | |
} | |
state = Skip; | |
} | |
munmap((void*)addr, (size_t)s.st_size); | |
close(fd); | |
char buffer[256]; | |
write(0, buffer, (size_t)snprintf(buffer, 255, "%d %d\n", part1, part2)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment