~cdv/aoc-2019-c

e66485a5b289010bd101d7543ca270595ac1211a — Chris Vittal 3 months ago cf32369
Solve day 22
2 files changed, 241 insertions(+), 3 deletions(-)

A input/day_22.txt
M solutions/day22.c
A input/day_22.txt => input/day_22.txt +100 -0
@@ 0,0 1,100 @@
deal with increment 15
cut 2234
deal with increment 30
cut -1865
deal with increment 26
cut -5396
deal with increment 69
deal into new stack
deal with increment 64
cut -5111
deal with increment 23
deal into new stack
deal with increment 53
deal into new stack
deal with increment 54
cut -5384
deal with increment 18
cut -1325
deal into new stack
deal with increment 49
cut 1174
deal with increment 71
deal into new stack
cut -5632
deal with increment 12
cut -6300
deal with increment 73
cut -1310
deal into new stack
cut 6522
deal with increment 36
deal into new stack
cut 2878
deal with increment 50
cut 7596
deal with increment 40
cut 3179
deal with increment 27
cut 538
deal with increment 46
cut 7520
deal with increment 71
cut -3471
deal with increment 5
cut -274
deal into new stack
cut -846
deal into new stack
deal with increment 60
cut -5584
deal with increment 13
deal into new stack
deal with increment 47
deal into new stack
cut -5887
deal with increment 4
cut -7255
deal with increment 54
cut 8329
deal with increment 18
cut -1293
deal into new stack
cut -2840
deal into new stack
cut -2203
deal with increment 74
cut 4303
deal with increment 42
cut -7783
deal with increment 43
cut -4040
deal with increment 21
cut -8001
deal with increment 70
cut 7243
deal with increment 41
cut 9882
deal with increment 50
cut -1588
deal with increment 35
cut 4225
deal with increment 5
cut 9281
deal with increment 57
deal into new stack
deal with increment 10
deal into new stack
cut -29
deal with increment 71
cut -3739
deal with increment 20
cut 2236
deal with increment 9
deal into new stack
cut -1199
deal with increment 33
deal into new stack
deal with increment 30
cut -2735
deal with increment 54

M solutions/day22.c => solutions/day22.c +141 -3
@@ 1,15 1,153 @@
#include "aoc.h"

#include <stdlib.h>

typedef __int128_t i128;

struct op {
	enum {
		DEAL,
		INCR,
		CUT,
		END,
	} t;
	i128 v;
};

struct input
parse_day22(FILE *in)
{
	return (struct input){ 0 };
	struct op *inp = malloc(128 * sizeof(struct op));
	int i = 0;

	char *line = NULL;
	size_t n = 0;
	long v;
	while (getline(&line, &n, in) != -1) {
		struct op op = { .t=DEAL };
		if (sscanf(line, "cut %ld", &v) == 1) {
			op.t = CUT;
			op.v = v;
		} else if (sscanf(line, "deal with increment %ld", &v) == 1) {
			op.t = INCR;
			op.v = v;
		}
		inp[i++] = op;
	}

	inp[i].t = END;
	free(line);
	return (struct input){ inp, true };
}

void
part_one_day22(void *input)
{}
{
	struct op *ops = input;
	static const long D = 10007;
	long p = 2019;
	for (struct op *op = ops; op->t != END; ++op) {
		switch (op->t) {
		case CUT: p = (p - op->v + D) % D; break;
		case INCR: p = op->v * p % D; break;
		case DEAL: p = D - 1 - p; break;
		default: break;
		}
	}
	printf("%ld", p);
}

static i128
modinv(i128 a, i128 m)
{
	if (m == 1) {
		return 0;
	}

	i128 x = 1, y = 0, orig = m;
	while (a > 1) {
		i128 q = a / m, t = m;
		m = a % m;
		a = t;
		t = y;
		y = x - q * y;
		x = t;

	}

	if (x < 0) {
		return x + orig;
	} else {
		return x;
	}
}

static i128
modp(i128 a, i128 e, i128 m)
{
	i128 x = 1, p = a % m;

	for (int i = 0; i < 128; ++i) {
		if (1 & (e >> i)) {
			x = x * p % m;
		}

		p = p * p % m;
	}

	return x;
}

void
part_two_day22(void *input)
{}
{
	struct op *ops = input;
	struct op *op;
	for (op = ops; op->t != END; ++op) { /* do nothing */ }

	static const i128 D = 119315717514047;
	static const i128 N = 101741582076661;
	static const i128 TGT = 2020;

	i128 a = 1, b = 0;
	for (; ops != op;) {
		--op;
		switch (op->t) {
		case CUT:
			if (op->v < 0) {
				b += op->v + D;
			} else {
				b += op->v;
			}
			break;
		case INCR: {
			i128 inv = modinv(op->v, D);
			a = a * inv % D;
			b = b * inv % D;
			break;
		}
		case DEAL:
			b = -b - 1;
			a *= -1;
			break;
		default:
			break;
		}

		a %= D;
		b %= D;

		if (a < 0)
			a += D;
		if (b < 0)
			b += D;
	}

	i128 _1 = modp(a, N, D) * TGT % D;
	i128 _2 = (modp(a, N, D) + D - 1) % D;
	i128 _3 = b * _2 % D;
	i128 _4 = modp(a - 1, D - 2, D);
	i128 ans = (_1 + _3 * _4) % D;

	printf("%ld", (long)ans);
}