aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarvin Borner2020-12-14 21:04:02 +0100
committerMarvin Borner2020-12-14 21:06:15 +0100
commit7cb9658e17baba2d43d0e7bc766512951ab4d05a (patch)
treeda7b477b0f8ef36c1c046edd0830aad9feb39920
parentd341d0a80d8b81365cd01613f82a07df1246f064 (diff)
I will improve this soon ARGH
-rw-r--r--2020/14/solve.c55
1 files changed, 47 insertions, 8 deletions
diff --git a/2020/14/solve.c b/2020/14/solve.c
index 4ca91fd..e2233dc 100644
--- a/2020/14/solve.c
+++ b/2020/14/solve.c
@@ -3,7 +3,7 @@
#include <time.h>
struct mem_entry {
- int address;
+ long address;
long value;
struct mem_entry *next;
};
@@ -27,8 +27,12 @@ struct mem_entry *get_entry(struct mem_map *mem_map, int address)
return NULL;
}
-void new_entry(struct mem_map *mem_map, int address, long value)
+void new_entry(struct mem_map *mem_map, long address, long value)
{
+ /* printf("%lu: %lu\n", address, value); */
+ if (!mem_map)
+ return;
+
struct mem_entry *override = NULL;
if ((override = get_entry(mem_map, address))) {
override->value = value;
@@ -68,7 +72,7 @@ long part_one(FILE *fp)
char *line = NULL;
size_t len = 0;
char mask[36] = { 0 };
- struct mem_map mem_map[256] = { 0 };
+ struct mem_map mem_map = { 0 };
while (getline(&line, &len, fp) != -1) {
if (line[0] == 'm' && line[1] == 'a') {
sscanf(line, "mask = %s\n", &mask[0]);
@@ -83,16 +87,51 @@ long part_one(FILE *fp)
else if (*p == '1')
value |= shift;
}
- new_entry(mem_map, address, value);
+ new_entry(&mem_map, address, value);
}
}
- return count_doku(mem_map);
+ return count_doku(&mem_map);
}
-int part_two(FILE *fp)
+long part_two(FILE *fp)
{
- return 0;
+ char *line = NULL;
+ size_t len = 0;
+ char mask[36] = { 0 };
+ int floating_bits[64];
+ struct mem_map mem_map = { 0 };
+ while (getline(&line, &len, fp) != -1) {
+ if (line[0] == 'm' && line[1] == 'a') {
+ sscanf(line, "mask = %s\n", &mask[0]);
+ } else if (line[0] == 'm' && line[1] == 'e') {
+ long address = 0, value = 0;
+ sscanf(line, "mem[%lu] = %lu\n", &address, &value);
+
+ int floating = 0;
+ for (int i = 0; i < 36; i++) {
+ if (mask[i] == '1') {
+ address |= 1L << (36 - i - 1);
+ } else if (mask[i] == 'X') {
+ floating_bits[floating] = i;
+ floating++;
+ }
+ }
+
+ long masked_addr = address;
+ for (long perm = 0; perm < (1 << floating); ++perm) {
+ long address = masked_addr;
+ for (int j = 0; j < floating; ++j) {
+ if (perm & (1L << j)) {
+ address ^= (1L << (36 - floating_bits[j] - 1));
+ }
+ }
+ new_entry(&mem_map, address, value);
+ }
+ }
+ }
+
+ return count_doku(&mem_map);
}
int main(int argc, char *argv[])
@@ -104,7 +143,7 @@ int main(int argc, char *argv[])
clock_t tic = clock();
printf("%lu\n", part_one(fp));
rewind(fp);
- printf("%d\n", part_two(fp));
+ printf("%lu\n", part_two(fp));
clock_t toc = clock();
printf("TIME: %f seconds\n", (double)(toc - tic) / CLOCKS_PER_SEC);