aoc-2019-c

Advent of Code 2019 Solutions in C
git clone https://git.sinitax.com/sinitax/aoc-2019-c
Log | Files | Refs | README | sfeed.txt

maxint.h (3731B)


      1#pragma once
      2
      3#include <stdint.h>
      4#include <stdbool.h>
      5#include <stdlib.h>
      6
      7#define MI_NEG 1
      8#define MI_POS 0
      9
     10#define MI_BIT(a,n) ((mi_ul) ((a) >> (n)) & 1)
     11#define MI_BITA(a,m,n) ((mi_ul) ((a)[(n) / (m)] >> ((n) % (m))) & 1)
     12
     13#define MI_UL_BYTES (sizeof(mi_ul))
     14#define MI_UL_BITS  (8 * sizeof(mi_ul))
     15
     16#define MI_ULS_BYTES (sizeof(mi_uls))
     17#define MI_ULS_BITS (8 * sizeof(mi_uls))
     18
     19#define MI_ABS(x) ((mi_ul) ((x) > 0 ? (x) : -(x)))
     20#define MI_SIGN(x) ((x) >= 0 ? MI_POS : MI_NEG)
     21#define MI_TO_SIGN(x) ((x)->sign == MI_POS ? 1 : -1)
     22
     23#define MI_INIT ((struct maxint) { \
     24	.data = NULL,   \
     25	.size = 0,      \
     26	.cap = 0,       \
     27	.sign = MI_POS, \
     28})
     29
     30/* unsigned underlying type */
     31typedef uint64_t mi_ul;
     32typedef int64_t mi_uls;
     33
     34enum {
     35	MI_OK,
     36	MI_ERR_OOM,
     37	MI_ERR_INVAL,
     38};
     39
     40struct maxint {
     41	mi_ul *data;
     42	size_t size, cap;
     43	int sign;
     44};
     45
     46/* void mi_init(struct maxint *m); */
     47void mi_deinit(struct maxint *m);
     48
     49/* struct maxint *mi_imm(struct maxint *storage, mi_ul tmp, int sign); */
     50
     51int mi_set(struct maxint *m1, const struct maxint *m2);
     52int mi_setv(struct maxint *m, mi_ul v, int sign);
     53int mi_setstr(struct maxint *m, const char *str,
     54	const char **end, const char *alph);
     55
     56int mi_resize(struct maxint *m, size_t size);
     57
     58static inline mi_ul mi_cast_ul(const struct maxint *m);
     59static inline mi_uls mi_cast_uls(const struct maxint *m);
     60
     61bool mi_zero(const struct maxint *m);
     62
     63size_t mi_lastset(const struct maxint *m);
     64
     65ssize_t mi_str(const struct maxint *m, char *buf, size_t buflen,
     66	mi_ul base, const char *alph, size_t zfill);
     67ssize_t mi_hex(const struct maxint *m, char *buf, size_t buflen,
     68	bool capital, size_t zfill);
     69ssize_t mi_dec(const struct maxint *m, char *buf, size_t buflen, size_t zfill);
     70ssize_t mi_bin(const struct maxint *m, char *buf, size_t buflen, size_t zfill);
     71
     72/* mi_add: o1 = i1 + i2
     73 * allowed: o1 == i1 */
     74int mi_add(struct maxint *o1, const struct maxint *i1, const struct maxint *i2);
     75
     76/* mi_sub: o1 = i1 - i2
     77 * allowed: o1 == i1 */
     78int mi_sub(struct maxint *o1, const struct maxint *i1, const struct maxint *i2);
     79
     80/* mi_shl: o1 = i1 << shift
     81 * allowed: o1 == i1 */
     82int mi_shl(struct maxint *o1, const struct maxint *i1, size_t shift);
     83
     84/* mi_shr: o1 = i1 >> shift
     85 * allowed: o1 == i1 */
     86int mi_shr(struct maxint *o1, const struct maxint *i1, size_t shift);
     87
     88/* mi_mul: o1 = i1 * i2
     89 * allowed: o1 == i1 */
     90int mi_mul(struct maxint *o1, const struct maxint *i1, const struct maxint *i2);
     91
     92/* mi_div: o1 = i1 / i2, o2 = i1 % i2
     93 * allowed: o1 == i1 */
     94int mi_div(struct maxint *o1, struct maxint *o2,
     95	const struct maxint *i1, const struct maxint *i2);
     96
     97/* mi_swap: o1 <=> o2 */
     98void mi_swap(struct maxint *o1, struct maxint *o2);
     99
    100/* mi_gcm: o1 = gcm(i1, i2)
    101 * allowed: o1 == i1 */
    102int mi_gcm(struct maxint *o1, const struct maxint *i1, const struct maxint *i2);
    103
    104/* mi_lcm: o1 = lcm(i1, i2)
    105 * allowed: o1 == i1 */
    106int mi_lcm(struct maxint *o1, const struct maxint *i1, const struct maxint *i2);
    107
    108/* mi_cmp: (i1 < i2) => -1 | (i1 == i2) => 0 | (i1 < i2) => 1 */
    109int mi_cmp(const struct maxint *i1, const struct maxint *i2);
    110
    111static inline void
    112mi_init(struct maxint *m)
    113{
    114	m->data = NULL;
    115	m->size = 0;
    116	m->cap = 0;
    117	m->sign = MI_POS;
    118}
    119
    120static inline struct maxint *
    121mi_imm(struct maxint *mi_tmp, mi_ul *ul_tmp, mi_ul imm, int sign)
    122{
    123	mi_tmp->sign = sign;
    124	if (mi_tmp->data) {
    125		mi_tmp->data[0] = imm;
    126	} else {
    127		*ul_tmp = imm;
    128		mi_tmp->data = ul_tmp;
    129	}
    130	mi_tmp->size = 1;
    131	return mi_tmp;
    132}
    133
    134static inline mi_ul
    135mi_cast_ul(const struct maxint *m)
    136{
    137	return m->data[0];
    138}
    139
    140static inline mi_uls
    141mi_cast_uls(const struct maxint *m)
    142{
    143	mi_uls val;
    144	mi_ul mask;
    145
    146	mask = (((mi_ul) 1) << (MI_ULS_BITS - 1)) - 1;
    147	val = (mi_uls) (m->data[0] & mask);
    148
    149	return val * MI_TO_SIGN(m);;
    150}
    151