Files
adventofcode2022/day25/snafu.c
dobiadi b80bd0674c Day25
2022-12-25 10:26:59 +01:00

103 lines
2.1 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFER_SIZE 64
#define MAGIC_NUMBER 5
long powNum(long, long);
long snafu_to_human(char*, int);
void human_to_snafu(char*, long);
int main() {
char buf[BUFFER_SIZE], *p, c;
memset(buf, 0, BUFFER_SIZE);
p = buf;
long sum = 0;
while ((c = getchar()) != EOF) {
*p++ = c;
if (c == '\n') {
sum += snafu_to_human(p-2, p-buf);
memset(buf, 0, BUFFER_SIZE);
p = buf;
}
}
printf("Sum in decimal: %li\n", sum);
char snafu[64];
memset(snafu, 0, 64);
human_to_snafu(snafu, sum);
printf("Sum in SNAFU: %s\n", snafu);
}
long powNum(long b, long e) {
long result = 1;
for (int i = 0; i < e; i++) {
result *= b;
}
return result;
}
long snafu_to_human(char* p, int len) {
long result = 0;
for (int i = 0; i < len; i++) {
switch(*(p-i)) {
case '0':
break;
case '1':
result += powNum(MAGIC_NUMBER, i);
break;
case '2':
result += 2*powNum(MAGIC_NUMBER, i);
break;
case '-':
result += -powNum(MAGIC_NUMBER, i);
break;
case '=':
result += -2*powNum(MAGIC_NUMBER, i);
break;
}
}
return result;
}
void human_to_snafu(char* p, long decimal) {
char buf[64], *q;
memset(buf, 0, 64);
long num = decimal;
int len = 0;
int remainder = 0;
while (num != 0) {
int numeric = num % MAGIC_NUMBER;
num /= MAGIC_NUMBER;
numeric += remainder;
remainder = 0;
if (numeric > 2) {
remainder = 1;
numeric = numeric - MAGIC_NUMBER;
}
if (numeric == -1) {
buf[len] = '-';
} else if (numeric == -2) {
buf[len] = '=';
} else {
buf[len] = '0' + numeric;
}
len++;
}
if (remainder) {
buf[len] = '1';
len++;
}
for (int i = 0; i <= len; i++) {
*(p+len-i-1) = buf[i];
}
}