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.
100 lines
2.0 KiB
100 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 48
|
|
|
|
struct proc {
|
|
result_t mv;
|
|
off_t field;
|
|
|
|
// void* jmp;
|
|
};
|
|
|
|
#define _LIT_MV_FORWARD "forward"
|
|
#define _LIT_MV_UP "up"
|
|
#define _LIT_MV_DOWN "down"
|
|
|
|
static const struct proc MAP[255] = {
|
|
['f'] = { .mv = 8, .field = (offsetof(struct psum, forward) / sizeof(result_t)) },
|
|
['u'] = { .mv = 3, .field = (offsetof(struct psum, up) / sizeof(result_t)) },
|
|
['d'] = { .mv = 5, .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 3], off_t field, result_t v)
|
|
{
|
|
f[field & 3] += v;
|
|
}
|
|
|
|
inline static void fresolv(result_t f[restrict 3], const struct proc* restrict p, result_t v)
|
|
{
|
|
_fresolv(f, p->field, v);
|
|
//f[p->field] += v;
|
|
}
|
|
|
|
inline static void mresolv(struct psum* restrict add, const struct proc* p, result_t v)
|
|
{
|
|
_fresolv((result_t* restrict)add, p->field, v);
|
|
//_fresolv((result_t(*)[3])add, p->field, v);
|
|
//*(((result_t*restrict)add)+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;
|
|
}
|