summaryrefslogtreecommitdiff
path: root/2020/10
diff options
context:
space:
mode:
Diffstat (limited to '2020/10')
-rw-r--r--2020/10/part1.c70
-rw-r--r--2020/10/part2.c87
-rw-r--r--2020/10/possible_seq.asm30
3 files changed, 187 insertions, 0 deletions
diff --git a/2020/10/part1.c b/2020/10/part1.c
new file mode 100644
index 0000000..f5a700e
--- /dev/null
+++ b/2020/10/part1.c
@@ -0,0 +1,70 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <malloc.h>
+#include <string.h>
+
+#define MAX_INPUT_LEN 128
+
+void insert_value_sorted(int *list, size_t *size, int value)
+{
+ long long low = 0, high = *size;
+ while (low < high) {
+ int m = low + (high - low) / 2;
+ if (list[m] < value) {
+ low = m + 1;
+ }
+ else if (list[m] > value) {
+ high = m;
+ }
+ else {
+ // Value already exists in the list
+ return;
+ }
+ }
+
+ for (long long i = *size - 1; i >= low; i--) {
+ list[i + 1] = list[i];
+ }
+
+ (*size)++;
+ list[low] = value;
+}
+
+int solve(const char *filename)
+{
+ FILE *file = fopen(filename, "r");
+
+ // Include space for newline and string terminator
+ char buffer[128] = { 0 };
+
+ int input[MAX_INPUT_LEN] = { 0 };
+ size_t input_size = 1; // 0 is our start value
+
+ while (fgets(buffer, 128, file)) {
+ insert_value_sorted(input, &input_size, atoi(buffer));
+ }
+
+ fclose(file);
+
+ int diff1 = 0;
+ int diff3 = 1; // Diff with adapter
+
+ for (size_t i = 1; i < input_size; i++)
+ {
+ int diff = input[i] - input[i - 1];
+ if (diff == 1) {
+ diff1++;
+ }
+ else if (diff == 3) {
+ diff3++;
+ }
+ }
+
+ return diff1 * diff3;
+}
+
+int main(int argc, char *argv[])
+{
+ printf("%i\n", solve(argv[argc - 1]));
+}
diff --git a/2020/10/part2.c b/2020/10/part2.c
new file mode 100644
index 0000000..5e766d4
--- /dev/null
+++ b/2020/10/part2.c
@@ -0,0 +1,87 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <malloc.h>
+#include <string.h>
+
+#include "../utils.h"
+
+#define MAX_INPUT_LEN 128
+
+void insert_value_sorted(int *list, size_t *size, int value)
+{
+ long long low = 0, high = *size;
+ while (low < high) {
+ int m = low + (high - low) / 2;
+ if (list[m] < value) {
+ low = m + 1;
+ }
+ else if (list[m] > value) {
+ high = m;
+ }
+ else {
+ // Value already exists in the list
+ return;
+ }
+ }
+
+ for (long long i = *size - 1; i >= low; i--) {
+ list[i + 1] = list[i];
+ }
+
+ (*size)++;
+ list[low] = value;
+}
+
+#ifdef USE_ASM
+uint64_t possible_seq(const int *input, size_t input_size);
+#else
+uint64_t possible_seq(const int *input, size_t input_size)
+{
+ // Use char to optimize for size
+ const static char TRIB[] = { 1, 1, 2, 4, 7 };
+ int con = 0;
+ uint64_t res = 1;
+ const int *prev = input;
+ const int *cur = input + 1;
+ do {
+ if (likely(*cur - *prev == 1)) {
+ con++;
+ }
+ else {
+ res *= TRIB[con];
+ con = 0;
+ }
+ } while (++prev && ++cur < input + input_size);
+
+ return res;
+}
+#endif
+
+uint64_t solve(const char *filename)
+{
+ FILE *file = fopen(filename, "r");
+
+ // Include space for newline and string terminator
+ char buffer[16] = { 0 };
+
+ int input[MAX_INPUT_LEN] = { 0 };
+ size_t input_size = 1; // 0 is our start value
+
+ while (fgets(buffer, 16, file)) {
+ insert_value_sorted(input, &input_size, atoi(buffer));
+ }
+
+ // Add our device's built-in joltage adapter
+ input[input_size] = input[input_size - 1] + 3;
+ input_size++;
+
+ fclose(file);
+
+ return possible_seq(input, input_size);
+}
+
+int main(int argc, char *argv[])
+{
+ printf("%lu\n", solve(argv[argc - 1]));
+}
diff --git a/2020/10/possible_seq.asm b/2020/10/possible_seq.asm
new file mode 100644
index 0000000..b737d13
--- /dev/null
+++ b/2020/10/possible_seq.asm
@@ -0,0 +1,30 @@
+global possible_seq
+
+section .rodata
+ TRIB: dq 1, 1, 2, 4, 7 ; tribonacci sequence (without first 2 zeroes)
+
+section .text
+
+possible_seq:
+ mov eax, 1 ; set up return value
+ xor ecx, ecx ; # of connected elements counter
+ lea rdx, [rdi + 4 * rsi - 4] ; pointer to the last element
+ lea r8, [rel TRIB]
+ jmp .loop
+.ncon:
+ imul rax, qword [r8 + 8 * rcx]
+ xor ecx, ecx
+ add rdi, 4
+ cmp rdi, rdx
+ jae .return
+.loop:
+ mov esi, dword [rdi + 4]
+ sub esi, dword [rdi]
+ cmp esi, 1
+ jne .ncon
+ inc ecx
+ add rdi, 4
+ cmp rdi, rdx
+ jb .loop
+.return:
+ ret