parent
f6acd0d44d
commit
50e1f31093
@ -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…
Reference in new issue