#include <ctype.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "aocdailies.h"
#include "aocutils.h"
#if 0
/* === aocYYYYDD =======================================================
===================================================================== */
void aocYYYYDD(char *data, size_t len) {
(void)len; // unused argument
}
#endif
/* === aoc202504 =======================================================
===================================================================== */
static unsigned evolve(struct RectangularMap *rm, unsigned src) {
unsigned changes = 0;
unsigned dst = 1 - src;
for (int row = 0; row < rm->rows; row++) {
for (int col = 0; col < rm->cols; col++) {
char cc = RMcharat(rm + src, col, row);
char *destin = RMcharptr(rm + dst, col, row);
if (cc == '@') {
unsigned nearby = 0;
for (int deltarow = -1; deltarow <= 1; deltarow++) {
for (int deltacol = -1; deltacol <= 1; deltacol++) {
nearby += (RMcharat(rm + src, col+deltacol,
row+deltarow) == '@');
}
}
nearby -= 1; // remove self
if (nearby < 4) {
*destin = '.';
changes++;
} else {
*destin = '@';
}
} else if (cc != 0) {
*destin = '.';
} else {
*destin = 0; // shouldn't happen
}
}
}
return changes;
}
void aoc202504(char *data, size_t len) {
(void)len; // unused argument
struct RectangularMap rm[2] = {0};
while (*data) {
char *data2 = data;
while (*data != '\n') data++;
*data = 0; // erase newline
RMaddline(rm + 0, data2);
RMaddline(rm + 1, data2); // set both rm's to the same thing
*data++ = '\n'; // unerase newline and skip it
}
unsigned part1 = evolve(rm, 0); // evolve from rm[0] to rm[1]
unsigned part2 = part1, src = 1;
for (;;) {
unsigned tmp = evolve(rm, src); // keep evolving
if (tmp == 0) break; // STOP
src = 1 - src; // back and forth
part2 += tmp; // add changes in this round
}
printf("P1: %u; P2: %u\n", part1, part2);
RMfree(rm);
RMfree(rm + 1);
}
/* === aoc202503 =======================================================
===================================================================== */
static long long unsigned maxj(const unsigned char *b, unsigned blen, unsigned nlen) {
if (nlen == 0) return 0;
const unsigned char *newb = b + 1;
unsigned newlen = blen - 1;
unsigned localmax = 0;
for (unsigned k = 0; k < blen - nlen + 1; k++) {
if (b[k] > localmax) {
localmax = b[k];
newb = b + k + 1;
newlen = blen - k - 1;
}
}
return localmax*upow(10, nlen - 1) + maxj(newb, newlen, nlen - 1);
}
void aoc202503(char *data, size_t len) {
(void)len; // unused argument
long long unsigned part1 = 0, part2 = 0;
char *p = data;
for (;;) {
char *pp = strchr(p, '\n');
if (pp == NULL) break;
unsigned char bank[256] = {0};
unsigned banklen;
for (banklen = 0; banklen < (unsigned)(pp - p); banklen++) {
bank[banklen] = (unsigned)p[banklen] - '0';
}
part1 += maxj(bank, banklen, 2);
part2 += maxj(bank, banklen, 12);
p = pp + 1;
}
printf("parts 1 and 2: %llu %llu\n", part1, part2);
}
/* === aoc202502 =======================================================
===================================================================== */
static int extractdata(char **data, char *p1, char *p2) {
char *d = *data;
if (*d == ',') d++; // skip ','
if (!isdigit(*d)) return 0;
while (isdigit(*d)) { *p1++ = *d++; *p1 = 0; }
if (*d != '-') { fprintf(stderr, "bad data\n"); exit(EXIT_FAILURE); }
d++; // skip '-'
while (isdigit(*d)) { *p2++ = *d++; *p2 = 0; }
*data = d;
return 1;
}
static int prepeat(int n, long long unsigned v) {
char tmp[42];
int len = sprintf(tmp, "%llu", v);
if (len % n) return 0;
if (len < 2*n) return 0;
for (int k = 0; k+n < len; k++) {
if (tmp[k] != tmp[k+n]) return 0;
}
return 1;
}
static long long unsigned suminvalid2(const char *start, const char *finis) {
long long unsigned retval = 0;
long long unsigned pstart = 0, pfinis = 0;
int k = 0;
while (start[k]) {
pstart *= 10; pstart += (unsigned)start[k] - '0';
k++;
}
k = 0;
while (finis[k]) {
pfinis *= 10; pfinis += (unsigned)finis[k] - '0';
k++;
}
for (long long unsigned kk = pstart; kk <= pfinis; kk++) {
if (prepeat(1, kk)) retval += kk;
else if (prepeat(2, kk)) retval += kk;
else if (prepeat(3, kk)) retval += kk;
else if (prepeat(4, kk)) retval += kk;
else if (prepeat(5, kk)) retval += kk;
else if (prepeat(6, kk)) retval += kk;
else if (prepeat(7, kk)) retval += kk;
else if (prepeat(8, kk)) retval += kk;
else if (prepeat(9, kk)) retval += kk;
}
return retval;
}
static long long unsigned suminvalid(const char *start, const char *finis) {
long long unsigned pstart = 0, pfinis = 0;
int k = 0;
while (start[k]) {
pstart *= 10; pstart += (unsigned)start[k] - '0';
pfinis *= 10; pfinis += (unsigned)finis[k] - '0';
k++;
}
long long unsigned lo = pstart / upow(10, (unsigned)(k/2));
long long unsigned hi = pfinis / upow(10, (unsigned)(k/2));
long long unsigned retval = 0;
for (long long unsigned kk = lo; kk <= hi; kk++) {
long long unsigned val = kk*upow(10, (unsigned)(k/2)) + kk;
if ((pstart <= val) && (val <= pfinis)) retval += val;
}
return retval;
}
void aoc202502(char *data, size_t len) {
(void)len; // unused argument
long long unsigned part1 = 0;
long long unsigned part2 = 0;
char start[42], finis[42];
while (extractdata(&data, start, finis)) {
int lenstart = strlen(start);
int lenfinis = strlen(finis);
part2 += suminvalid2(start, finis);
if (lenstart != lenfinis) {
char tmp[42];
if (lenfinis % 2) {
sprintf(tmp, "%llu", upow(10, (unsigned)lenstart) - 1);
part1 += suminvalid(start, tmp);
} else {
sprintf(tmp, "%llu", upow(10, (unsigned)lenstart));
part1 += suminvalid(tmp, finis);
}
} else {
if (lenstart % 2) {
part1 += 0;
} else {
part1 += suminvalid(start, finis);
}
}
}
printf("parts 1 and 2: %llu %llu\n", part1, part2);
}
/* === aoc202501 =======================================================
===================================================================== */
static int zeroaccum(int start, char d, int v, int *p1, int *p2) {
int direction;
switch (d) {
default: fprintf(stderr, "Invalid letter: %c\n", d);
exit(EXIT_FAILURE);
case 'R': direction = 1;
break;
case 'L': direction = -1;
break;
}
while (v--) {
start += direction;
if (start == -1) start = 99;
if (start == 100) start = 0;
if (start == 0) *p2 += 1;
}
if (start == 0) *p1 += 1;
return start;
}
void aoc202501(char *data, size_t len) {
(void)len; // unused argument
int pos = 50;
int part1 = 0, part2 = 0;
char dir; int value;
while (*data) {
dir = *data++;
value = 0;
while (isdigit(*data)) {
value *= 10;
value += *data - '0';
data++;
}
while (isspace(*data)) data++; // skip whitespace
pos = zeroaccum(pos, dir, value, &part1, &part2);
}
// part1
printf("password for part1 is %d\n", part1);
// part2
printf("password for part2 is %d\n", part2);
}