1
0

solve day 20

This commit is contained in:
Rokas Puzonas 2023-07-08 00:55:53 +03:00
parent 1a031bf371
commit b914c44ae0
2 changed files with 195 additions and 2 deletions

190
day20.c Normal file
View File

@ -0,0 +1,190 @@
#include <stdio.h>
#include <assert.h>
#include "types.h"
#include "aoc.h"
typedef struct {
i64 *numbers;
u32 count;
} day20_data;
typedef struct day20_node *day20_node_ptr;
struct day20_node {
i64 value;
day20_node_ptr next;
day20_node_ptr prev;
};
static void* day20_parse(char** lines, int line_count)
{
day20_data *data = malloc(sizeof(day20_data));
data->numbers = malloc(sizeof(i64) * line_count);
data->count = line_count;
for (int i = 0; i < line_count; i++) {
data->numbers[i] = strtol(lines[i], NULL, 10);
}
return data;
}
static struct day20_node *day20_list_alloc(i64 *values, u32 count)
{
struct day20_node *start = calloc(1, sizeof(struct day20_node));
start->value = values[0];
start->next = NULL;
struct day20_node *prev = start;
for (int i = 1; i < count; i++) {
struct day20_node *curr = calloc(1, sizeof(struct day20_node));
curr->value = values[i];
curr->prev = prev;
prev->next = curr;
prev = curr;
}
prev->next = start;
start->prev = prev;
return start;
}
static void day20_list_free(struct day20_node *list)
{
struct day20_node *curr = list;
curr->prev->next = NULL;
while (curr) {
struct day20_node *next = curr->next;
curr->next = NULL;
free(curr);
curr = next;
}
}
static struct day20_node *day20_list_get(struct day20_node *list, i64 nth, u32 list_size)
{
struct day20_node *curr = list;
if (nth > 0) {
for (int i = 0; i < nth % list_size; i++) {
curr = curr->next;
}
} else if (nth < 0) {
for (int i = 0; i < (-nth+1) % list_size; i++) {
curr = curr->prev;
}
}
return curr;
}
static struct day20_node *day20_list_find(struct day20_node *list, i64 value)
{
struct day20_node *curr = list;
do {
if (curr->value == value) {
return curr;
}
curr = curr->next;
} while (curr != list);
return NULL;
}
static void day20_node_remove(struct day20_node *node)
{
struct day20_node *prev = node->prev;
struct day20_node *next = node->next;
prev->next = next;
next->prev = prev;
}
static void day20_node_insert_after(struct day20_node *node, struct day20_node *new_node)
{
struct day20_node *next = node->next;
new_node->prev = node;
new_node->next = next;
node->next = new_node;
next->prev = new_node;
}
static void day20_print_list(struct day20_node *list)
{
struct day20_node *curr = list;
do {
printf("%ld ", curr->value);
curr = curr->next;
} while (curr != list);
printf("\n");
}
static void day20_mix_list(struct day20_node **order, u32 count)
{
for (int i = 0; i < count; i++) {
struct day20_node *curr = order[i];
if (curr->value == 0) continue;
day20_node_remove(curr);
struct day20_node *other = day20_list_get(curr, curr->value, count-1);
day20_node_insert_after(other, curr);
}
}
static void day20_part1(void *p)
{
day20_data *data = (day20_data*)p;
struct day20_node *list = day20_list_alloc(data->numbers, data->count);
struct day20_node *order[data->count];
order[0] = list;
for (int i = 1; i < data->count; i++)
{
order[i] = order[i-1]->next;
}
day20_mix_list(order, data->count);
i64 answer = 0;
struct day20_node *zero_node = day20_list_find(list, 0);
answer += day20_list_get(zero_node, 1000, data->count)->value;
answer += day20_list_get(zero_node, 2000, data->count)->value;
answer += day20_list_get(zero_node, 3000, data->count)->value;
printf("%ld\n", answer);
day20_list_free(list);
}
static void day20_part2(void *p)
{
day20_data *data = (day20_data*)p;
i64 decryption_key = 811589153;
for (int i = 0; i < data->count; i++) {
data->numbers[i] *= decryption_key;
}
struct day20_node *list = day20_list_alloc(data->numbers, data->count);
struct day20_node *order[data->count];
order[0] = list;
for (int i = 1; i < data->count; i++)
{
order[i] = order[i-1]->next;
}
for (int i = 0; i < 10; i++) {
day20_mix_list(order, data->count);
}
i64 answer = 0;
struct day20_node *zero_node = day20_list_find(list, 0);
answer += day20_list_get(zero_node, 1000, data->count)->value;
answer += day20_list_get(zero_node, 2000, data->count)->value;
answer += day20_list_get(zero_node, 3000, data->count)->value;
printf("%ld\n", answer);
day20_list_free(list);
}
ADD_SOLUTION(20, day20_parse, day20_part1, day20_part2);

7
main.c
View File

@ -28,6 +28,7 @@
#include "day17.c"
#include "day18.c"
#include "day19.c"
#include "day20.c"
Solution *find_solution(int day)
{
@ -184,12 +185,14 @@ int main(int argc, char** argv) {
printf("part1:\n");
start_time = get_current_time_us();
solution->part1(parsed);
printf("Part 1 took %ldus\n\n", get_current_time_us() - start_time);
u64 part1_duration = get_current_time_us() - start_time;
printf("Part 1 took %ldus (%ldms)\n\n", part1_duration, part1_duration/1000);
printf("part2:\n");
start_time = get_current_time_us();
solution->part2(parsed);
printf("Part 2 took %ldus\n", get_current_time_us() - start_time);
u64 part2_duration = get_current_time_us() - start_time;
printf("Part 2 took %ldus (%ldms)\n", part2_duration, part2_duration/1000);
return 0;
}