day2: part1

Fortune for day2's current commit: Small blessing − 小吉
master
Avril 3 years ago
parent f6acd0d44d
commit 50e1f31093
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -0,0 +1,100 @@
# aoc2021-day2
PROJECT=day2
AUTHOR=Avril (Flanchan) <flanchan@cumallover.me>
SRC_C = $(wildcard src/*.c)
SRC_CXX = $(wildcard src/*.cpp)
INCLUDE=include
INPUT_SOURCE=input
INPUT_DEST=src/input.c
COMMON_FLAGS+= -W -Wall -fno-strict-aliasing $(addprefix -I,$(INCLUDE))
COMMON_FLAGS+=-msse -msse2 -msse3
COMMON_FLAGS+=-D_PART1
#-D_PART2
OPT_FLAGS?= -march=native -fgraphite -fopenmp -floop-parallelize-all -ftree-parallelize-loops=4 \
-floop-interchange -ftree-loop-distribution -floop-strip-mine -floop-block \
-fno-stack-check
CXX_OPT_FLAGS?= $(OPT_FLAGS) -felide-constructors
CFLAGS += $(COMMON_FLAGS) --std=gnu17
CXXFLAGS += $(COMMON_FLAGS) --std=gnu++20
LDFLAGS +=
STRIP=strip
RELEASE_COMMON_FLAGS+= -Werror
DEBUG_COMMON_FLAGS+= -fanalyzer
ifneq ($(TARGET_SPEC_FLAGS),no)
RELEASE_CFLAGS?= -O3 -flto $(OPT_FLAGS)
RELEASE_CXXFLAGS?= -O3 -flto $(CXX_OPT_FLAGS)
RELEASE_LDFLAGS?= -Wl,-O3 -Wl,-flto
DEBUG_CFLAGS?= -Og -g
DEBUG_CXXFLAGS?=-Og -g
DEBUG_LDFLAGS?=
endif
DEBUG_CFLAGS+=-DDEBUG $(DEBUG_COMMON_FLAGS)
DEBUG_CXXFLAGS+=-DDEBUG $(DEBUG_COMMON_FLAGS)
RELEASE_CFLAGS+=-DRELEASE $(RELEASE_COMMON_FLAGS)
RELEASE_CXXFLAGS+=-DRELEASE $(RELEASE_COMMON_FLAGS)
# Objects
OBJ_C = $(addprefix obj/c/,$(SRC_C:.c=.o))
OBJ_CXX = $(addprefix obj/cxx/,$(SRC_CXX:.cpp=.o))
OBJ = $(OBJ_C) $(OBJ_CXX)
# Phonies
.PHONY: release
release: | dirs $(INPUT_DEST)
$(MAKE) $(PROJECT)-release
.PHONY: debug
debug: | dirs $(INPUT_DEST)
$(MAKE) $(PROJECT)-debug
# Targets
dirs:
@mkdir -p obj/c{,xx}/src
$(INPUT_DEST): $(INPUT_SOURCE)
./mkinput $< > $@
obj/c/%.o: %.c
$(CC) -c $< $(CFLAGS) -o $@ $(LDFLAGS)
obj/cxx/%.o: %.cpp
$(CXX) -c $< $(CXXFLAGS) -o $@ $(LDFLAGS)
$(PROJECT)-release: CFLAGS+= $(RELEASE_CFLAGS)
$(PROJECT)-release: CXXFLAGS += $(RELEASE_CXXFLAGS)
$(PROJECT)-release: LDFLAGS += $(RELEASE_LDFLAGS)
$(PROJECT)-release: $(OBJ)
$(CXX) $^ $(CXXFLAGS) -o $@ $(LDFLAGS)
$(STRIP) $@
$(PROJECT)-debug: CFLAGS+= $(DEBUG_CFLAGS)
$(PROJECT)-debug: CXXFLAGS += $(DEBUG_CXXFLAGS)
$(PROJECT)-debug: LDFLAGS += $(DEBUG_LDFLAGS)
$(PROJECT)-debug: $(OBJ)
$(CXX) $^ $(CXXFLAGS) -o $@ $(LDFLAGS)
clean-rebuild:
rm -rf obj
clean: clean-rebuild
rm -f $(PROJECT)-{release,debug,pgo}
rm -f $(INPUT_DEST)

@ -0,0 +1,17 @@
#ifndef _INPUT_H
#define _INPUT_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
extern const char INPUT[];
extern const size_t INPUT_SIZE;
#ifdef __cplusplus
extern "C" {
#endif
#endif

@ -0,0 +1,40 @@
#ifndef _RESULT_H
#define _RESULT_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
typedef int64_t result_t;
struct psum {
union {
struct { result_t forward, up, down; };
result_t _fields[3];
};
};
typedef struct nsum {
result_t hoz, depth;
} position_t;
#ifdef DEBUG
static
#else
extern
#endif
inline __attribute__((gnu_inline, const)) position_t normalise_position(struct psum p)
{
return (struct nsum) {
.hoz = p.forward,
.depth = p.down - p.up,
};
}
#ifdef __cplusplus
}
#endif
#endif /* _RESULT_H */

File diff suppressed because it is too large Load Diff

@ -0,0 +1,15 @@
#!/bin/bash
INPUT=${1:-input}
echo "#include <input.h>"
echo ""
printf "const char INPUT[] = "
while IFS= read -r line; do
echo " \"$line\""
done < $INPUT
unset line
echo ";"
echo "const size_t INPUT_SIZE=sizeof(INPUT)/sizeof(char);"

File diff suppressed because it is too large Load Diff

@ -0,0 +1,34 @@
#include <stdio.h>
#include <input.h>
#include <result.h>
extern int part1(result_t* restrict);
extern int part2(result_t* restrict);
static void print_result(int part, result_t r)
{
#ifdef DEBUG
printf(">>> [%d] %lu\n", part, r);
#else
(void)part;
printf("%ld\n", r);
#endif
}
int main()
{
int r = 0;
#ifdef _PART1
result_t p1;
if( (r = part1(&p1)) ) return r;
print_result(1, p1);
#endif
#ifdef _PART2
result_t p2;
if( (r = part2(&p2)) ) return r;
print_result(2, p2);
#endif
return r;
}

@ -0,0 +1,99 @@
#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;
}
Loading…
Cancel
Save