Skip to content

Instantly share code, notes, and snippets.

@Lucretiel
Last active December 5, 2018 16:49
Show Gist options
  • Save Lucretiel/846e0ab217d4342bd0e0dc8de5dc6983 to your computer and use it in GitHub Desktop.
Save Lucretiel/846e0ab217d4342bd0e0dc8de5dc6983 to your computer and use it in GitHub Desktop.
A template for advent of code problems. Write your solution in the `solve` function; the template handles all the i/o
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
/**
* Write a message to stderr, followed by a newline, then exit the program.
* This helper function is provided because C doesn't have throwable exceptions
* or any similarly ergonomic error handling.
*
* Arguments to this function are similar to `fprintf`; see online documentation
* for an example.
*
* # Example:
*
* ```
* int main() {
* const int bad_number = 10;
* const char* bad_string = "Oh No";
*
* failure("Something went wrong, got bad string '%s' and bad int %d", bad_string, bad number);
* }
* ```
*/
static inline void failure(const char* fmt, ...) {
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
fputc('\n', stderr);
fflush(stderr);
exit(1);
}
/**
* Your solution goes here. As input, it is provided the complete input to the
* problem (read from stdin) as a character array, and the number of bytes in
* the input. It should return an integer, which will be printed to stdout. It
* can also call `failure` if an invariant fails and you need to exit early.
*
* input is guarenteed to be null terminated, so C string functions (like strlen
* and strtok) can safely work on it. input_size is the number of characters read
* from stdin, excluding this null terminator.
*/
static inline long solve(char* input, size_t input_size) {
// YOUR SOLUTION CODE GOES HERE
// ↓ DELETE ↓ THIS ↓
fprintf(stdout, "Input:\n%s\n", input);
return input_size;
}
/**
* Main function. Reads all of stdin into a buffer; calls solve(); prints the solution
*/
int main() {
// Start with 64k, which should cover most inputs without reallocating
size_t allocated = 65536;
char* buffer = malloc(allocated);
size_t buffer_size = 0;
// Read stdin, reallocating as necessary, until we reach EOF
while(!feof(stdin)) {
// Note that we use (buffer_size + 1) throughout this function because we
// want to make sure to leave some extra space to append a null byte after
// reading in stdin.
// If necessary, reallocate the buffer. See https://en.wikipedia.org/wiki/Dynamic_array#Growth_factor
// for details of why we multiply by 3/2.
if((buffer_size + 1) >= allocated) {
allocated = (allocated * 3) / 2;
buffer = realloc(buffer, allocated);
}
// Read some more input
const size_t count = fread(buffer + buffer_size, 1, (allocated - (buffer_size + 1)), stdin);
buffer_size += count;
// Check for errors
if(ferror(stdin)) {
perror("Error reading from stdin");
return 1;
}
}
// Append a null byte to make sure that c string functions are safe.
buffer[buffer_size] = 0;
// Solve the puzzle
const long solution = solve(buffer, buffer_size);
// Print the solution to the puzzle
fprintf(stdout, "%ld\n", solution);
fflush(stdout);
// Check for errors
if(ferror(stdout)) {
perror("Error writing solution to stdout");
return 1;
}
// Free the buffer. There's no reason to do this here because we're about to
// exit the program, but we'd prefer the code in here to exhibit good C style.
free(buffer);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment