From 36f763830f949676f4275132563a1132751016f1 Mon Sep 17 00:00:00 2001 From: Bruno Raoult Date: Sat, 3 Dec 2022 14:42:37 +0100 Subject: [PATCH] 2020: Tentative C & Bash frameworks (common functions) --- 2022/RESULTS.txt | 7 +++++ 2022/day01/Makefile | 4 +-- 2022/day01/aoc-c.c | 30 +++------------------ 2022/day01/aoc.bash | 61 ++++++++++++++++++++++-------------------- 2022/day01/aoc.h | 17 ++++++++++++ 2022/day01/common.bash | 19 ++++++------- 2022/day01/common.c | 49 +++++++++++++++++++++++++++++++++ 7 files changed, 121 insertions(+), 66 deletions(-) create mode 100644 2022/day01/aoc.h create mode 100644 2022/day01/common.c diff --git a/2022/RESULTS.txt b/2022/RESULTS.txt index 7e4acdd..a3e1bc7 100644 --- a/2022/RESULTS.txt +++ b/2022/RESULTS.txt @@ -7,8 +7,15 @@ aoc.bash: res=66719 time: 0:00.03 real, 0.02 user, 0.00 sys context-switch: 0+1, page-faults: 0+274 +aoc-c : res=66719 + time: 0:00.00 real, 0.00 user, 0.00 sys + context-switch: 0+1, page-faults: 0+89 + +++++++++++++++++ part 2 aoc.bash: res=198551 time: 0:00.03 real, 0.03 user, 0.00 sys context-switch: 2+1, page-faults: 0+283 +aoc-c : res=198551 + time: 0:00.00 real, 0.00 user, 0.00 sys + context-switch: 5+1, page-faults: 0+87 diff --git a/2022/day01/Makefile b/2022/day01/Makefile index 9387298..e0add74 100644 --- a/2022/day01/Makefile +++ b/2022/day01/Makefile @@ -82,9 +82,9 @@ ccls: $(CCLSFILE) clean: @rm -f aoc-c core* vgcore* gmon.out aoc-c.s aoc-c.i README.html compile_commands.json -.c: +aoc-c: aoc-c.c common.c @echo compiling $< - @$(CC) $(CFLAGS) $(LDFLAGS) -I $(INCDIR) $< $(LDLIB) -o $@ + $(CC) $(CFLAGS) $(LDFLAGS) -I $(INCDIR) $^ $(LDLIB) -o $@ # generate pre-processed file (.i) and assembler (.s) %.i: %.c diff --git a/2022/day01/aoc-c.c b/2022/day01/aoc-c.c index 0cd18ae..3daf1ce 100644 --- a/2022/day01/aoc-c.c +++ b/2022/day01/aoc-c.c @@ -17,6 +17,8 @@ #include "plist.h" #include "debug.h" #include "pool.h" +#include "aoc.h" + PLIST_HEAD(plist); @@ -45,7 +47,7 @@ static void parse(pool_t *pool) buflen = getline(&buf, &alloc, stdin); switch (buflen) { case 1: - case -1: + case -1: /* EOF */ node = pool_get(pool); plist_node_init(node, total); plist_add(node, &plist); @@ -62,35 +64,11 @@ end: return; } -static int usage(char *prg) -{ - fprintf(stderr, "Usage: %s [-d debug_level] [-p part] [-i input]\n", prg); - return 1; -} - int main(int ac, char **av) { - int opt, part = 1; - - while ((opt = getopt(ac, av, "d:p:")) != -1) { - switch (opt) { - case 'd': - debug_level_set(atoi(optarg)); - break; - case 'p': /* 1 or 2 */ - part = atoi(optarg); - if (part < 1 || part > 2) - return usage(*av); - break; - default: - return usage(*av); - } - } - if (optind < ac) - return usage(*av); + int part = parseargs(ac, av); pool_t *pool_tot = pool_create("total", 128, sizeof(struct plist_node)); - parse(pool_tot); printf("%s : res=%d\n", *av, calc_top_plist(part == 1? 1: 3)); diff --git a/2022/day01/aoc.bash b/2022/day01/aoc.bash index fb51e89..571028a 100755 --- a/2022/day01/aoc.bash +++ b/2022/day01/aoc.bash @@ -13,41 +13,44 @@ . common.bash -declare -a total -declare max=0 -declare -i res=0 +declare -a elf +declare -i maxwanted=3 parse() { - local -i elf=0 + local -i tot=0 i res - while read -r line; do - if [[ -n $line ]]; then - (( total[elf] += line)) - else - (( total[elf] > max )) && (( max = total[elf] )) - ((elf++)) - fi - done -} - -part1() { - res=$max -} - -part2() { - local -i i elf newbest - - for ((i=0; i<3; ++i)); do - newbest=0 - for ((elf=0; elf<${#total[@]}; ++elf)); do - (( total[elf] > total[newbest] )) && newbest=$elf + while true; do + read -r line + res=$? + # number found: sum & continue + [[ -n $line ]] && (( tot += line)) && continue + # first elf: we set it and continue + (( !${#elf[@]} )) && (( elf[0] = tot )) && continue + # find a place to (maybe) insert new high (keep array sorted) + for (( i = 0; i < ${#elf[@]}; ++i )); do + if (( tot > elf[i] )); then # normal insert (tot > old value) + elf=( "${elf[@]:0:i}" "$tot" "${elf[@]:i}" ) + break + elif (( i == ${#elf[@]}-1 )); then # insert at end + elf+=( "$tot" ) + break + fi done - (( res+=total[newbest] )) - unset "total[$newbest]" # remove current max - total=("${total[@]}") # pack array + # keep array size <= maxwanted + elf=( "${elf[@]:0:maxwanted}" ) + (( tot = 0 )) + ((res > 0)) && break # EOF done } +solve() { + local -i part="$1" + if ((part == 1)); then + (( res = elf[0] )) + else + (( res = elf[0] + elf[1] + elf[2] )) + fi +} + main "$@" -printf "%s: res=%s\n" "$cmdname" "$res" exit 0 diff --git a/2022/day01/aoc.h b/2022/day01/aoc.h new file mode 100644 index 0000000..2ef8361 --- /dev/null +++ b/2022/day01/aoc.h @@ -0,0 +1,17 @@ +/* aoc.c: Advent of Code 2022 + * + * Copyright (C) 2022 Bruno Raoult ("br") + * Licensed under the GNU General Public License v3.0 or later. + * Some rights reserved. See COPYING. + * + * You should have received a copy of the GNU General Public License along with this + * program. If not, see . + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ +#ifndef _AOC_H_ +#define _AOC_H_ + +extern int parseargs(int ac, char**av); + +#endif /* _AOC_H_ */ diff --git a/2022/day01/common.bash b/2022/day01/common.bash index 12ef04e..f3756df 100755 --- a/2022/day01/common.bash +++ b/2022/day01/common.bash @@ -14,17 +14,18 @@ # shellcheck disable=2034 export cmdname=${0##*/} export debug=0 -export part=1 -export res="" +export res shopt -s extglob set -o noglob usage() { printf "usage: %s [-d DEBUG] [-p PART]\n" "$cmdname" + exit 1 } checkargs() { + local part while getopts p:d: todo; do case "$todo" in d) @@ -45,7 +46,6 @@ checkargs() { ;; *) usage - exit 1 ;; esac done @@ -53,14 +53,15 @@ checkargs() { shift $((OPTIND - 1)) (( $# > 1 )) && usage + return "$part" } main() { + local -i part + checkargs "$@" - parse - if ((part == 1)); then - part1 - else - part2 - fi + part=$? + parse "$part" + solve "$part" + printf "%s: res=%s\n" "$cmdname" "$res" } diff --git a/2022/day01/common.c b/2022/day01/common.c new file mode 100644 index 0000000..a3827b6 --- /dev/null +++ b/2022/day01/common.c @@ -0,0 +1,49 @@ +/* common.c: Advent of Code 2022, common functions + * + * Copyright (C) 2022 Bruno Raoult ("br") + * Licensed under the GNU General Public License v3.0 or later. + * Some rights reserved. See COPYING. + * + * You should have received a copy of the GNU General Public License along with this + * program. If not, see . + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include +#include +#include + +#include "aoc.h" +#include "debug.h" + +static int usage(char *prg) +{ + fprintf(stderr, "Usage: %s [-d debug_level] [-p part] [-i input]\n", prg); + return 1; +} + +int parseargs(int ac, char **av) +{ + int opt, part = 1; + + while ((opt = getopt(ac, av, "d:p:")) != -1) { + switch (opt) { + case 'd': + debug_level_set(atoi(optarg)); + break; + case 'p': /* 1 or 2 */ + part = atoi(optarg); + if (part < 1 || part > 2) + return usage(*av); + break; + case 'i': + + default: + return usage(*av); + } + } + if (optind < ac) + return usage(*av); + return part; +}