Complete Day 5 Part 1
This commit is contained in:
285
05/05.c
285
05/05.c
@@ -1,28 +1,258 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "llist.h"
|
|
||||||
|
|
||||||
#define DEFAULT_FILE "input.txt"
|
#define DEFAULT_FILE "input.txt"
|
||||||
#define STRBUF_LEN 200
|
#define STRBUF_LEN 300
|
||||||
#define ISDIGIT(X) (X >= '0' && X <= '9')
|
#define ISDIGIT(X) (X >= '0' && X <= '9')
|
||||||
|
|
||||||
uint64_t parse_digit(char *str);
|
#define ADVENT_MAP_PRINT(X) do {printf("Dest: %d Src: %d Len: %d\n", X.dest, X.src, X.len);} while (0);
|
||||||
|
|
||||||
|
#define ADVENT_MAP_EQ(X,Y) (X.dest == Y.dest && X.src == Y.src && X.len == Y.len)
|
||||||
|
|
||||||
|
/********************************************************/
|
||||||
|
// Linked List Functions
|
||||||
|
/********************************************************/
|
||||||
|
|
||||||
|
// Node structure
|
||||||
|
typedef struct ll_node {
|
||||||
|
void *data;
|
||||||
|
struct ll_node *next;
|
||||||
|
} ll_node;
|
||||||
|
|
||||||
|
// Linked list structure
|
||||||
|
typedef struct linked_list {
|
||||||
|
ll_node* head;
|
||||||
|
} linked_list;
|
||||||
|
|
||||||
|
void ll_init(linked_list* list) {
|
||||||
|
list->head = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to create a new node
|
||||||
|
ll_node* ll_create_node(void *data) {
|
||||||
|
ll_node* new_node = (ll_node*)malloc(sizeof(ll_node));
|
||||||
|
if (new_node != NULL) {
|
||||||
|
new_node->data = data;
|
||||||
|
new_node->next = NULL;
|
||||||
|
}
|
||||||
|
return new_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to add a node to the beginning of the list
|
||||||
|
void ll_prepend(linked_list* list, void *data) {
|
||||||
|
ll_node* new_node = ll_create_node(data);
|
||||||
|
if (new_node != NULL) {
|
||||||
|
new_node->next = list->head;
|
||||||
|
list->head = new_node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to add a node to the end of the list
|
||||||
|
void ll_append(linked_list* list, void *data) {
|
||||||
|
ll_node* newNode = ll_create_node(data);
|
||||||
|
if (newNode != NULL) {
|
||||||
|
if (list->head == NULL) {
|
||||||
|
list->head = newNode;
|
||||||
|
} else {
|
||||||
|
ll_node* current = list->head;
|
||||||
|
while (current->next != NULL) {
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
current->next = newNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to remove a node with a given value
|
||||||
|
void ll_remove(linked_list* list, void *data, bool (*compare_function)(void *, void*)) {
|
||||||
|
ll_node* current = list->head;
|
||||||
|
ll_node* prev = NULL;
|
||||||
|
|
||||||
|
while (current != NULL && !compare_function(current->data, data)) {
|
||||||
|
prev = current;
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current != NULL) {
|
||||||
|
if (prev != NULL) {
|
||||||
|
prev->next = current->next;
|
||||||
|
} else {
|
||||||
|
list->head = current->next;
|
||||||
|
}
|
||||||
|
free(current);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to free the memory used by the linked list
|
||||||
|
void ll_free(linked_list* list) {
|
||||||
|
ll_node* current = list->head;
|
||||||
|
ll_node* next;
|
||||||
|
|
||||||
|
while (current != NULL) {
|
||||||
|
next = current->next;
|
||||||
|
free(current->data);
|
||||||
|
free(current);
|
||||||
|
current = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
list->head = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t ll_len(linked_list* list)
|
||||||
|
{
|
||||||
|
uint64_t len = 0;
|
||||||
|
ll_node *current = list->head;
|
||||||
|
while (current != NULL)
|
||||||
|
{
|
||||||
|
len++;
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************/
|
||||||
|
// Seeds
|
||||||
|
/********************************************************/
|
||||||
|
|
||||||
|
typedef struct advent_map {
|
||||||
|
uint64_t dest;
|
||||||
|
uint64_t src;
|
||||||
|
uint64_t len;
|
||||||
|
} advent_map;
|
||||||
|
|
||||||
|
uint64_t parse_num(char *str)
|
||||||
|
{
|
||||||
|
uint64_t num = 0;
|
||||||
|
while (ISDIGIT(*str))
|
||||||
|
{
|
||||||
|
num = (num * 10) + (*str - '0');
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
linked_list parse_seeds(char *str)
|
linked_list parse_seeds(char *str)
|
||||||
{
|
{
|
||||||
linked_list seeds;
|
linked_list seeds;
|
||||||
ll_init(&seeds);
|
ll_init(&seeds);
|
||||||
|
|
||||||
while (!ISDIGIT(str)) str++;
|
while (!ISDIGIT(*str)) str++;
|
||||||
|
|
||||||
while (*str != '\n')
|
while (ISDIGIT(*str))
|
||||||
{
|
{
|
||||||
uint64_t seed = parse_digit(str);
|
uint64_t *seed = malloc(sizeof(uint64_t));
|
||||||
|
*seed = parse_num(str);
|
||||||
|
ll_append(&seeds, seed);
|
||||||
|
while (ISDIGIT(*str)) str++;
|
||||||
|
if (*str == ' ') str++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return seeds;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_seeds(linked_list *list)
|
||||||
|
{
|
||||||
|
ll_node* current = list->head;
|
||||||
|
while (current != NULL) {
|
||||||
|
printf("Num: %lud\n", *((uint64_t *)(current->data)));
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t seed_min(linked_list *list)
|
||||||
|
{
|
||||||
|
ll_node* current = list->head;
|
||||||
|
if (current == NULL) return 0;
|
||||||
|
|
||||||
|
uint64_t current_val = *(uint64_t *)(current->data);
|
||||||
|
uint64_t min = current_val;
|
||||||
|
|
||||||
|
while (current != NULL) {
|
||||||
|
current_val = *(uint64_t *)(current->data);
|
||||||
|
if (current_val < min) min = current_val;
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************/
|
||||||
|
// Maps
|
||||||
|
/********************************************************/
|
||||||
|
|
||||||
|
void parse_map(linked_list *map, FILE *file)
|
||||||
|
{
|
||||||
|
char *strbuf = malloc(sizeof(char) * STRBUF_LEN);
|
||||||
|
char *str = strbuf;
|
||||||
|
|
||||||
|
fgets(strbuf, STRBUF_LEN, file);
|
||||||
|
|
||||||
|
while (ISDIGIT(*strbuf))
|
||||||
|
{
|
||||||
|
str = strbuf;
|
||||||
|
advent_map *map_node = malloc(sizeof(advent_map));
|
||||||
|
|
||||||
|
map_node->dest = parse_num(str);
|
||||||
|
while (ISDIGIT(*str)) str++;
|
||||||
|
str++;
|
||||||
|
|
||||||
|
map_node->src = parse_num(str);
|
||||||
|
while (ISDIGIT(*str)) str++;
|
||||||
|
str++;
|
||||||
|
|
||||||
|
map_node->len = parse_num(str);
|
||||||
|
|
||||||
|
ll_append(map, map_node);
|
||||||
|
if (!fgets(strbuf, STRBUF_LEN, file)) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void print_map(linked_list *list)
|
||||||
|
{
|
||||||
|
ll_node* current = list->head;
|
||||||
|
advent_map *m;
|
||||||
|
while (current != NULL) {
|
||||||
|
m = (advent_map *)(current->data);
|
||||||
|
printf("dest: %lu src: %lu len: %lu\n", m->dest, m->src, m->len);
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t translate(linked_list *map, uint64_t value)
|
||||||
|
{
|
||||||
|
ll_node *current_node = map->head;
|
||||||
|
while (current_node != NULL)
|
||||||
|
{
|
||||||
|
advent_map *current_map = (advent_map *)current_node->data;
|
||||||
|
if (value - current_map->src < current_map->len)
|
||||||
|
{
|
||||||
|
return current_map->dest + (value - current_map->src);
|
||||||
|
}
|
||||||
|
current_node = current_node->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void translate_all(linked_list *map, linked_list *seeds)
|
||||||
|
{
|
||||||
|
ll_node *current_node = seeds->head;
|
||||||
|
|
||||||
|
while (current_node != NULL)
|
||||||
|
{
|
||||||
|
uint64_t current_int = *((uint64_t *)(current_node->data));
|
||||||
|
uint64_t translated_int = translate(map, current_int);
|
||||||
|
*((uint64_t *)(current_node->data)) = translated_int;
|
||||||
|
current_node = current_node->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
// Get filename as an argument, if there is one
|
// Get filename as an argument, if there is one
|
||||||
@@ -43,12 +273,47 @@ int main(int argc, char **argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
linked_list seeds;
|
||||||
|
|
||||||
while (fgets(strbuf, STRBUF_LEN, file))
|
linked_list seed_to_soil;
|
||||||
|
linked_list soil_to_fertilizer;
|
||||||
|
linked_list fertilizer_to_water;
|
||||||
|
linked_list water_to_light;
|
||||||
|
linked_list light_to_temperature;
|
||||||
|
linked_list temperature_to_humidity;
|
||||||
|
linked_list humidity_to_location;
|
||||||
|
|
||||||
|
linked_list *maps[7] = {&seed_to_soil,
|
||||||
|
&soil_to_fertilizer,
|
||||||
|
&fertilizer_to_water,
|
||||||
|
&water_to_light,
|
||||||
|
&light_to_temperature,
|
||||||
|
&temperature_to_humidity,
|
||||||
|
&humidity_to_location };
|
||||||
|
|
||||||
|
uint64_t i = 0;
|
||||||
|
for (i = 0; i < 7; i++)
|
||||||
{
|
{
|
||||||
// Code goes here
|
ll_init(maps[i]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fgets(strbuf, STRBUF_LEN, file);
|
||||||
|
seeds = parse_seeds(strbuf);
|
||||||
|
fgets(strbuf, STRBUF_LEN, file);
|
||||||
|
|
||||||
|
for (i = 0; i < 7; i++)
|
||||||
|
{
|
||||||
|
fgets(strbuf, STRBUF_LEN, file);
|
||||||
|
printf(strbuf);
|
||||||
|
parse_map(maps[i], file);
|
||||||
|
print_map(maps[i]);
|
||||||
|
translate_all(maps[i], &seeds);
|
||||||
|
}
|
||||||
|
|
||||||
|
print_seeds(&seeds);
|
||||||
|
|
||||||
|
uint64_t min = seed_min(&seeds);
|
||||||
|
printf("Min: %lu\n", min);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
127
05/llist.c
127
05/llist.c
@@ -1,127 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "llist.h"
|
|
||||||
|
|
||||||
void ll_init(linked_list* list) {
|
|
||||||
list->head = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function to create a new node
|
|
||||||
advent_node* ll_create_node(advent_map map) {
|
|
||||||
advent_node* new_node = (advent_node*)malloc(sizeof(advent_node));
|
|
||||||
if (new_node != NULL) {
|
|
||||||
new_node->map = map;
|
|
||||||
new_node->next = NULL;
|
|
||||||
}
|
|
||||||
return new_node;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function to add a node to the beginning of the list
|
|
||||||
void ll_prepend(linked_list* list, advent_map map) {
|
|
||||||
advent_node* new_node = ll_create_node(map);
|
|
||||||
if (new_node != NULL) {
|
|
||||||
new_node->next = list->head;
|
|
||||||
list->head = new_node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function to add a node to the end of the list
|
|
||||||
void ll_append(linked_list* list, advent_map map) {
|
|
||||||
advent_node* newNode = ll_create_node(map);
|
|
||||||
if (newNode != NULL) {
|
|
||||||
if (list->head == NULL) {
|
|
||||||
list->head = newNode;
|
|
||||||
} else {
|
|
||||||
advent_node* current = list->head;
|
|
||||||
while (current->next != NULL) {
|
|
||||||
current = current->next;
|
|
||||||
}
|
|
||||||
current->next = newNode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function to remove a node with a given value
|
|
||||||
void ll_remove(linked_list* list, advent_map map) {
|
|
||||||
advent_node* current = list->head;
|
|
||||||
advent_node* prev = NULL;
|
|
||||||
|
|
||||||
while (current != NULL && !ADVENT_MAP_EQ(current->map, map)) {
|
|
||||||
prev = current;
|
|
||||||
current = current->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (current != NULL) {
|
|
||||||
if (prev != NULL) {
|
|
||||||
prev->next = current->next;
|
|
||||||
} else {
|
|
||||||
list->head = current->next;
|
|
||||||
}
|
|
||||||
free(current);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function to print the linked list
|
|
||||||
void ll_print(linked_list* list) {
|
|
||||||
advent_node* current = list->head;
|
|
||||||
while (current != NULL) {
|
|
||||||
ADVENT_MAP_PRINT(current->map);
|
|
||||||
current = current->next;
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function to free the memory used by the linked list
|
|
||||||
void ll_free(linked_list* list) {
|
|
||||||
advent_node* current = list->head;
|
|
||||||
advent_node* next;
|
|
||||||
|
|
||||||
while (current != NULL) {
|
|
||||||
next = current->next;
|
|
||||||
free(current);
|
|
||||||
current = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
list->head = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
// Example usage
|
|
||||||
int main() {
|
|
||||||
linked_list myList;
|
|
||||||
ll_init(&myList);
|
|
||||||
|
|
||||||
advent_map map1;
|
|
||||||
map1.dest = 1;
|
|
||||||
map1.src = 50;
|
|
||||||
map1.len = 5;
|
|
||||||
|
|
||||||
advent_map map2;
|
|
||||||
map2.dest = 60;
|
|
||||||
map2.src = 500;
|
|
||||||
map2.len = 2;
|
|
||||||
|
|
||||||
advent_map map3;
|
|
||||||
map3.dest = 800;
|
|
||||||
map3.src = 8000;
|
|
||||||
map3.len = 5;
|
|
||||||
|
|
||||||
ll_append(&myList, map1);
|
|
||||||
ll_append(&myList, map2);
|
|
||||||
ll_append(&myList, map3);
|
|
||||||
|
|
||||||
printf("Original List: \n");
|
|
||||||
ll_print(&myList);
|
|
||||||
|
|
||||||
ll_remove(&myList, map2);
|
|
||||||
|
|
||||||
printf("List after removing 2: \n");
|
|
||||||
ll_print(&myList);
|
|
||||||
|
|
||||||
ll_free(&myList);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
35
05/llist.h
35
05/llist.h
@@ -1,35 +0,0 @@
|
|||||||
#ifndef LLIST_H
|
|
||||||
#define LLIST_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#define ADVENT_MAP_PRINT(X) do {printf("Dest: %d Src: %d Len: %d\n", X.dest, X.src, X.len);} while (0);
|
|
||||||
|
|
||||||
#define ADVENT_MAP_EQ(X,Y) (X.dest == Y.dest && X.src == Y.src && X.len == Y.len)
|
|
||||||
|
|
||||||
typedef struct advent_map {
|
|
||||||
uint64_t dest;
|
|
||||||
uint64_t src;
|
|
||||||
uint64_t len;
|
|
||||||
} advent_map;
|
|
||||||
|
|
||||||
// Node structure
|
|
||||||
typedef struct advent_node {
|
|
||||||
advent_map map;
|
|
||||||
struct advent_node *next;
|
|
||||||
} advent_node;
|
|
||||||
|
|
||||||
// Linked list structure
|
|
||||||
typedef struct linked_list {
|
|
||||||
advent_node* head;
|
|
||||||
} linked_list;
|
|
||||||
|
|
||||||
void ll_init(linked_list* list);
|
|
||||||
void ll_prepend(linked_list* list, advent_map map);
|
|
||||||
void ll_append(linked_list* list, advent_map map);
|
|
||||||
void ll_remove(linked_list* list, advent_map map);
|
|
||||||
void ll_print(linked_list* list);
|
|
||||||
void ll_free(linked_list* list);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
Reference in New Issue
Block a user