You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

98 lines
2.0 KiB

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
#include <input.h>
#include <result.h>
#define RIMAX_STR (sizeof(size_t))
struct proc {
union {
struct {
result_t mv;
off_t field;
};
struct {
//TODO: part2 shit
} aimed;
};
};
#define _LIT_MV_FORWARD "forward"
#define _LIT_MV_UP "up"
#define _LIT_MV_DOWN "down"
_Static_assert(sizeof(_LIT_MV_FORWARD)==8, "bad literal size");
static const struct proc MAP[255] = {
['f'] = { .mv = sizeof(_LIT_MV_FORWARD), .field = (offsetof(struct psum, forward) / sizeof(result_t)) },
['u'] = { .mv = sizeof(_LIT_MV_UP), .field = (offsetof(struct psum, up) / sizeof(result_t)) },
['d'] = { .mv = sizeof(_LIT_MV_DOWN), .field = (offsetof(struct psum, down) / sizeof(result_t)) },
};
static const unsigned char DIGITS[255] = {
['0' ... '9'] = 1,
};
inline static void _fresolv(result_t f[restrict SUM_FIELDS], off_t field, result_t v)
{
f[field & SUM_FIELDS] += v;
}
inline static void fresolv(result_t f[restrict SUM_FIELDS], const struct proc* restrict p, result_t v)
{
_fresolv(f, p->field, v);
//f[p->field] += v;
}
inline static __attribute__((const, always_inline, artificial, gnu_inline)) bool is_digit(char c)
{
return !!c[DIGITS];
}
inline static result_t ri64p(const char* restrict *restrict pinput)
{
char dig[RIMAX_STR] = {0};
size_t i = 0;
while(is_digit(dig[i]=**pinput)) { i+=1; *pinput+=1; }
#if DEBUG
assert(i<RIMAX_STR);
#endif
dig[i] = 0;
#ifdef DEBUG
fprintf(stderr, "read: %s\n", dig);
#endif
return atol(dig);
}
__attribute__((pure))
struct psum compute_unnormalised(const char* restrict input)
{
struct psum res = {0};
while(*input)
{
const struct proc p = (*input)[MAP];
#ifdef DEBUG
fprintf(stderr, "ch: %c\n", *input);
assert(p.mv > 0);
#endif
input+=p.mv;
result_t n = ri64p(&input);
fresolv(res._fields, &p, n);
}
return res;
}
int part1(result_t* restrict _res)
{
position_t final = normalise_position(compute_unnormalised(INPUT));
*_res = final.hoz * final.depth;
return 0;
}