Committing days 1-4
This commit is contained in:
133
01/01-part2.c
Normal file
133
01/01-part2.c
Normal file
@@ -0,0 +1,133 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
// How much memory to allocate for each line
|
||||
#define MAX_LINE_LEN 200
|
||||
|
||||
#define DEFAULT_FILE "input.txt"
|
||||
|
||||
// Returns 0 if a string is not a number (e.g. 'two')
|
||||
// Otherwise, returns the equivilant ascii character digit.
|
||||
// Only works for single digits.
|
||||
// Only accepts lower case.
|
||||
char parse_num(char *str)
|
||||
{
|
||||
const char *num_strings[10] = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };
|
||||
|
||||
// The lengths of the strings above,
|
||||
const uint8_t num_string_lens[10] = { 4, 3, 3, 5, 4, 4, 3, 5, 5, 4 };
|
||||
|
||||
bool possible_nums[10] = { [0 ... 9] = true };
|
||||
uint8_t num_idx = 0;
|
||||
uint8_t char_incriment = 0;
|
||||
char current;
|
||||
bool result_still_possible = false;
|
||||
|
||||
for (char_incriment = 0; char_incriment < 6; char_incriment++)
|
||||
{
|
||||
// Grab out next character in the string
|
||||
current = *(str + char_incriment);
|
||||
|
||||
for (num_idx = 0; num_idx < 10; num_idx++)
|
||||
{
|
||||
if (!possible_nums[num_idx]) continue;
|
||||
|
||||
// If we have passed the end of our number string and every character has matched,
|
||||
// then we return our valid character.
|
||||
if (char_incriment == num_string_lens[num_idx] && possible_nums[num_idx]) return (num_idx + '0');
|
||||
|
||||
// If the character is not the letter it should be, disqualify this number.
|
||||
// e.g. if num_idx == 1 and char_incriment == 2, current should equal 'e'
|
||||
// because 'e' is the 3rd number in the word 'one.'
|
||||
if (current != num_strings[num_idx][char_incriment]) possible_nums[num_idx] = false;
|
||||
else result_still_possible = true;
|
||||
}
|
||||
if (!result_still_possible) return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Returns a string of the next line.
|
||||
// Remember to free() this after you're finished.
|
||||
// Limited by MAX_LINE_LEN (I'm lazy.)
|
||||
char *next_line(FILE *file)
|
||||
{
|
||||
char *strbuf = malloc(sizeof(char) * MAX_LINE_LEN);
|
||||
uint8_t idx = 0;
|
||||
char current = 0;
|
||||
|
||||
while (current != '\n' && current != EOF)
|
||||
{
|
||||
current = fgetc(file);
|
||||
strbuf[idx] = current;
|
||||
idx++;
|
||||
}
|
||||
|
||||
return strbuf;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
// Get filename as an argument
|
||||
char *path = (argc > 1) ? argv[1] : DEFAULT_FILE;
|
||||
|
||||
if (!path)
|
||||
{
|
||||
printf("Requires input file.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
FILE *file = fopen(path, "r");
|
||||
|
||||
if (!file)
|
||||
{
|
||||
printf("Could not find file.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int8_t firstdigit = -1;
|
||||
int8_t lastdigit = -1;
|
||||
int8_t parsed_num = -1;
|
||||
uint32_t sum = 0;
|
||||
char current = 0;
|
||||
char *strbuf = next_line(file);
|
||||
uint8_t strbuf_idx = 0;
|
||||
|
||||
while (current != EOF)
|
||||
{
|
||||
parsed_num = parse_num(strbuf + strbuf_idx);
|
||||
current = strbuf[strbuf_idx++];
|
||||
|
||||
if (current == '\n')
|
||||
{
|
||||
if (lastdigit == -1) lastdigit = firstdigit;
|
||||
sum += (firstdigit * 10) + lastdigit;
|
||||
firstdigit = -1;
|
||||
lastdigit = -1;
|
||||
strbuf_idx = 0;
|
||||
free(strbuf);
|
||||
strbuf = next_line(file);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (parsed_num != 0) current = parsed_num;
|
||||
|
||||
if (current < '0' || current > '9') continue;
|
||||
|
||||
if (firstdigit == -1)
|
||||
{
|
||||
firstdigit = current - '0';
|
||||
}
|
||||
else
|
||||
{
|
||||
lastdigit = current - '0';
|
||||
}
|
||||
}
|
||||
|
||||
printf("Sum: %d\n", sum);
|
||||
|
||||
return 0;
|
||||
}
|
||||
57
01/01.c
Normal file
57
01/01.c
Normal file
@@ -0,0 +1,57 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
// Get filename as an argument, defaults to "input.txt"
|
||||
char *path = (argc > 1) ? argv[1] : "input.txt";
|
||||
|
||||
if (!path)
|
||||
{
|
||||
printf("Requires input file.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
FILE *file = fopen(path, "r");
|
||||
|
||||
if (!file)
|
||||
{
|
||||
printf("Could not find file.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int8_t firstdigit = -1;
|
||||
int8_t lastdigit = -1;
|
||||
uint32_t sum = 0;
|
||||
char current = 0;
|
||||
|
||||
while (current != EOF)
|
||||
{
|
||||
current = fgetc(file);
|
||||
|
||||
if (current == '\n')
|
||||
{
|
||||
if (lastdigit == -1) lastdigit = firstdigit;
|
||||
sum += (firstdigit * 10) + lastdigit;
|
||||
firstdigit = -1;
|
||||
lastdigit = -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (current < '0' || current > '9') continue;
|
||||
|
||||
if (firstdigit == -1)
|
||||
{
|
||||
firstdigit = current - '0';
|
||||
}
|
||||
else
|
||||
{
|
||||
lastdigit = current - '0';
|
||||
}
|
||||
}
|
||||
|
||||
printf("Sum: %d\n", sum);
|
||||
|
||||
return 0;
|
||||
}
|
||||
60
01/01test.c
Normal file
60
01/01test.c
Normal file
@@ -0,0 +1,60 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
// Returns -1 if a string is not a number (e.g. 'two')
|
||||
// Otherwise, returns the number.
|
||||
// Only works for single digits.
|
||||
// Only accepts lower case.
|
||||
int8_t parse_num(char *str)
|
||||
{
|
||||
const char *num_strings[10] = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };
|
||||
|
||||
// The lengths of the strings above,
|
||||
const uint8_t num_string_lens[10] = { 4, 3, 3, 5, 4, 4, 3, 5, 5, 4 };
|
||||
|
||||
bool possible_nums[10] = { [0 ... 9] = true };
|
||||
uint8_t num_idx = 0;
|
||||
uint8_t char_incriment = 0;
|
||||
char current;
|
||||
bool result_still_possible = false;
|
||||
|
||||
for (char_incriment = 0; char_incriment < 6; char_incriment++)
|
||||
{
|
||||
// Grab out next character in the string
|
||||
current = *(str + char_incriment);
|
||||
|
||||
for (num_idx = 0; num_idx < 10; num_idx++)
|
||||
{
|
||||
if (!possible_nums[num_idx]) continue;
|
||||
|
||||
// If we have passed the end of our number string and every character has matched,
|
||||
// then we return our valid character.
|
||||
if (char_incriment == num_string_lens[num_idx] && possible_nums[num_idx]) return num_idx;
|
||||
|
||||
// If the character is not the letter it should be, disqualify this number.
|
||||
// e.g. if num_idx == 1 and char_incriment == 2, current should equal 'e'
|
||||
// because 'e' is the 3rd number in the word 'one.'
|
||||
if (current != num_strings[num_idx][char_incriment]) possible_nums[num_idx] = false;
|
||||
else result_still_possible = true;
|
||||
}
|
||||
if (!result_still_possible) return -1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
const char *num_strings[10] = { "zerorr", "oneqw", "twoqw", "threere", "fourer", "fiveer", "sixer", "sevener", "eighter", "nineer" };
|
||||
|
||||
uint8_t i = 0;
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
printf("%d\n", parse_num(num_strings[i]));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
1000
01/input.txt
Normal file
1000
01/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
4
01/input2.txt
Normal file
4
01/input2.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
zero1
|
||||
1zero
|
||||
asdfone
|
||||
asdfoneasdfoneasdf
|
||||
Reference in New Issue
Block a user