Change C programs to accept input from STDIN

This commit is contained in:
Bill Rossi 2024-11-19 20:04:10 -05:00
parent 949dfdcea0
commit e0fcee5a17
7 changed files with 262 additions and 43 deletions

View File

@ -1,26 +1,31 @@
#include <stdio.h>
#include "../../lib/aoc.h"
int main() {
FILE* input = fopen("../data/2015/1/input.txt", "r");
char c;
char *input = aoc_read_input();
int floor = 0;
while (fread(&c, 1, 1, input) > 0) {
if (c == '(') floor++;
else if(c == ')') floor--;
int index = 0;
while (input[index] > 0) {
if (input[index] == '(') floor++;
else if(input[index] == ')') floor--;
index++;
}
printf("Part 1: %d\n", floor);
floor = 0;
int steps = 0;
rewind(input);
index = 0;
while (fread(&c, 1, 1, input) > 0) {
if (c == '(') floor++;
else if(c == ')') floor--;
while (input[index] > 0) {
if (input[index] == '(') floor++;
else if(input[index] == ')') floor--;
steps++;
if (floor < 0) break;
index++;
}
printf("Part 2: %d\n", steps);
free(input);
}

48
c/2015/2/problem.c Normal file
View File

@ -0,0 +1,48 @@
#include <stdio.h>
#include <string.h>
#include "../../lib/aoc.h"
int volume(int length, int width, int height) {
return length * width * height;
}
int ribbon_length(int length, int width, int height) {
int first_perimeter = (length + width) * 2;
int second_perimeter = (length + height) * 2;
int third_perimeter = (height + width) * 2;
int smallest_perimeter = first_perimeter;
if (second_perimeter < smallest_perimeter) smallest_perimeter = second_perimeter;
if (third_perimeter < smallest_perimeter) smallest_perimeter = third_perimeter;
return smallest_perimeter + volume(length, width, height);
}
int surface_area(int length, int width, int height) {
int first_side = length * width * 2;
int second_side = length * height * 2;
int third_side = height * width * 2;
int smallest_side = first_side;
if (second_side < smallest_side) smallest_side = second_side;
if (third_side < smallest_side) smallest_side = third_side;
return first_side + second_side + third_side + (smallest_side / 2);
}
int main() {
char *input = aoc_read_input();
int paper = 0;
int ribbon = 0;
char *tok = strtok(input, "x");
while (tok != NULL) {
int l = atoi(tok);
tok = strtok(NULL, "x");
int w = atoi(tok);
tok = strtok(NULL, "\n");
int h = atoi(tok);
paper += surface_area(l, w, h);
ribbon += ribbon_length(l, w, h);
tok = strtok(NULL, "x");
}
printf("Part 1: %d\n", paper);
printf("Part 1: %d\n", ribbon);
free(input);
}

72
c/2015/3/problem.c Normal file
View File

@ -0,0 +1,72 @@
#include <stdio.h>
#include <string.h>
#include "../../lib/aoc.h"
int compare(const void *a, const void *b) {
return *(int*)a - *(int*)b;
}
int visited_houses(char *input, int num_santas) {
int moves_count = strlen(input);
int *positions = calloc(moves_count + 1, sizeof(int)); // +1 for the starting position
int **santa_positions = calloc(num_santas, sizeof(int*));
for (int i = 0; i < num_santas; i++) {
santa_positions[i] = calloc(2, sizeof(int));
santa_positions[i][0] = 0;
santa_positions[i][1] = 0;
}
int santa_index = 0;
int *santa_position = santa_positions[0];
positions[0] = 0;
int index = 0;
while (input[index] > 10) {
switch(input[index++]) {
case '^':
santa_position[1] += 1;
break;
case 'v':
santa_position[1] -= 1;
break;
case '>':
santa_position[0] += 1;
break;
case '<':
santa_position[0] -= 1;
break;
}
positions[index] = (santa_position[0] * moves_count) + santa_position[1];
santa_index = (santa_index + 1) % num_santas;
santa_position = santa_positions[santa_index];
}
qsort(positions, moves_count, sizeof(int), compare);
int last_position = positions[0];
int num_visited_houses = 0;
for (int i = 0; i < moves_count + 1; i++) {
if (positions[i] != last_position) {
num_visited_houses++;
last_position = positions[i];
}
}
free(positions);
for (int i = 0; i < num_santas; i++) {
free(santa_positions[i]);
}
free(santa_positions);
return num_visited_houses;
}
int main() {
char *input = aoc_read_input();
printf("Part 1: %d\n", visited_houses(input, 1));
printf("Part 2: %d\n", visited_houses(input, 2));
free(input);
}

View File

@ -1,43 +1,35 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../../lib/aoc.h"
int main() {
FILE* input = fopen("../data/2017/1/input.txt", "r");
char c1, c2, first_char;
long total;
char *input = aoc_read_input();
int length = strlen(input) - 1;
int sum = 0;
fread(&first_char, 1, 1, input);
c2 = first_char;
while (fread(&c1, 1, 1, input) > 0 && c1 != '\n') {
if (c1 == c2) {
total += c1 - '0';
}
c2 = c1;
}
if (c2 == first_char) {
total += c2 - '0';
}
printf("Part 1: %d\n", total);
int num_chars = ftell(input);
rewind(input);
total = 0;
char *buffer = malloc(num_chars);
fread(buffer, 1, num_chars, input);
for(int i = 0; i < num_chars / 2; i++) {
c1 = buffer[i];
c2 = buffer[i + (num_chars / 2)];
if (c1 == c2) {
total += c1 - '0';
for (int i = 0; i < length - 1; i++) {
if (input[i] == input[i + 1]) {
sum += input[i] - '0';
}
}
total <<= 1;
if (input[0] == input[length - 1]) {
sum += input[0] - '0';
}
printf("Part 2: %d\n", total);
printf("Part 1: %d\n", sum);
sum = 0;
for (int i = 0; i < length; i++) {
if (input[i] == input[(i + (length / 2)) % length]) {
sum += input[i] - '0';
}
}
printf("Part 2: %d\n", sum);
free(input);
}

79
c/2017/2/problem.c Normal file
View File

@ -0,0 +1,79 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include "../../lib/aoc.h"
int line_checksum_1(char *line) {
char **saveptr = malloc(sizeof(char*));
char *token = strtok_r(line, "\t", saveptr);
int min = INT_MAX;
int max = INT_MIN;
while (token != NULL) {
int value = atoi(token);
if (value < min) min = value;
if (value > max) max = value;
token = strtok_r(NULL, "\t", saveptr);
}
free(saveptr);
return max - min;
}
int line_checksum_2(char *line) {
int tokens[20];
char **saveptr = malloc(sizeof(char*));
char *token = strtok_r(line, "\t", saveptr);
int index = 0;
while (token != NULL) {
tokens[index++] = atoi(token);
token = strtok_r(NULL, "\t", saveptr);
}
for (int i = 0; i < index; i++) {
for (int j = 0; j < index; j++) {
if (tokens[i] != tokens[j] && (tokens[i] % tokens[j] == 0)) {
free(saveptr);
return tokens[i] / tokens[j];
}
}
}
for (int i = 0; i < index; i++) {
printf("%d ", tokens[i]);
}
printf("ERROR! No checksum found\n");
return 0;
}
int main() {
char *input = aoc_read_input();
char **line_saveptr = malloc(sizeof(char*));
char *line = strtok_r(input, "\n", line_saveptr);
int checksum_sum_1 = 0;
int checksum_sum_2 = 0;
while (line != NULL) {
char *line_copy = malloc(strlen(line) + 1);
strcpy(line_copy, line);
checksum_sum_1 += line_checksum_1(line);
checksum_sum_2 += line_checksum_2(line_copy);
line = strtok_r(NULL, "\n", line_saveptr);
free(line_copy);
}
printf("Part 1: %d\n", checksum_sum_1);
printf("Part 2: %d\n", checksum_sum_2);
free(line_saveptr);
free(line);
free(input);
}

View File

@ -3,4 +3,5 @@
year=$1
day=$2
gcc -o $year/$day/problem $year/$day/problem.c && time ./$year/$day/problem
gcc -o $year/$day/problem $year/$day/problem.c
time (cat ../data/$year/$day/input.txt | ./$year/$day/problem)

22
c/lib/aoc.h Normal file
View File

@ -0,0 +1,22 @@
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#define INITIAL_BUFFER_SIZE 2
char *aoc_read_input(void) {
int buffer_size = INITIAL_BUFFER_SIZE;
char *input_buffer = malloc(buffer_size);
int chars_read = read(STDIN_FILENO, input_buffer, buffer_size);
char *buffer_position = &input_buffer[chars_read];
while (chars_read == buffer_size) {
buffer_size *= 2;
input_buffer = realloc(input_buffer, buffer_size);
buffer_position = &input_buffer[chars_read];
chars_read += read(STDIN_FILENO, buffer_position, buffer_size / 2);
}
input_buffer[chars_read] = 0;
return input_buffer;
}