Compare commits
84 Commits
9d375aecfc
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| ad6a39e82a | |||
| 3a857e4d53 | |||
| f80a051177 | |||
| 129fa07787 | |||
| 1472082c86 | |||
| e8bed49e13 | |||
| 83d70dcc7a | |||
| 56d2e63fac | |||
| 5c91de5d40 | |||
| 40a9c7b12e | |||
| 34b6cd7b57 | |||
| 5ad5c87fd8 | |||
| 11e7b45676 | |||
| 3f2a5648df | |||
| 0a3b404c4c | |||
| a214d2b70d | |||
| f490c2353e | |||
| 2ed6284bcd | |||
| 5fc204744a | |||
| d1cf8d96b8 | |||
| b285f74997 | |||
| c949c64da2 | |||
| 357e8ce087 | |||
| 5cde9051ec | |||
| 111fde4fbd | |||
| f54479189b | |||
| 8e00fec33c | |||
| d0376f21c3 | |||
| 04a856dc47 | |||
| 0658ffdd7d | |||
| efe0dec8f0 | |||
| 6d4a8dd85b | |||
| 11cb3c5c64 | |||
| 7e0a21704e | |||
| 008599e79c | |||
| fe381ae7f0 | |||
| 4a0749999e | |||
| 18720b9e09 | |||
| 17e140f235 | |||
| a1e436babc | |||
| 02a1dda786 | |||
| ef29ca28a1 | |||
| c1b3e83c68 | |||
| bd2548fca9 | |||
| 3f5b282883 | |||
| 38ef781f0a | |||
| 13d183de79 | |||
| dfe2207e8e | |||
| 31a255a9ac | |||
| 25d25b399e | |||
| f5ebb5c5cc | |||
| c608f6dcde | |||
| 9e3a875e37 | |||
| 4c0f6e3025 | |||
| 68f200ff65 | |||
| 8aff410ff4 | |||
| 16da47600c | |||
| 8b68bf4449 | |||
| c86517897e | |||
| 9c999e9717 | |||
| 05643127c2 | |||
| 6a5a0da435 | |||
| 3dd072c53e | |||
| 8f09fcf13f | |||
| 8f444d7341 | |||
| d7fa1c4fb5 | |||
| 0c787d9a51 | |||
| 64ad068ec8 | |||
| ab73311d6b | |||
| d116b98ae9 | |||
| 325c8254b8 | |||
| 76ab3d0c5b | |||
| bc2b2ac726 | |||
| b7c0b1fa01 | |||
| 487766c0a2 | |||
| a0fddb5f44 | |||
| f68d5b319e | |||
| 9455b99342 | |||
| ea4967bfcd | |||
| d1026e8f59 | |||
| 01cdce6608 | |||
| b8f6763a3b | |||
| 81a58c6266 | |||
| ca06a4a355 |
@@ -12,9 +12,9 @@ declare floor
|
||||
|
||||
function adj() {
|
||||
local -i r="$1" n="$2" c="$3" count=0
|
||||
local -a prow=(${rows[r-1]})
|
||||
local -a row=(${rows[r]})
|
||||
local -a nrow=(${rows[r+1]})
|
||||
local -a prow=("${rows[r-1]}")
|
||||
local -a row=("${rows[r]}")
|
||||
local -a nrow=("${rows[r+1]}")
|
||||
#echo
|
||||
#echo p="${prow[*]}"
|
||||
#echo r="${row[*]}"
|
||||
@@ -51,7 +51,7 @@ function run() {
|
||||
changed=0
|
||||
seated=0
|
||||
for ((r=1; r<=NROWS; ++r)); do
|
||||
row=(${rows[r]})
|
||||
row=("${rows[r]}")
|
||||
newrow=(0)
|
||||
for ((c=1; c<=RLENGTH; ++c)); do
|
||||
newrow+=("${row[c]}")
|
||||
@@ -61,13 +61,13 @@ function run() {
|
||||
case ${row[c]} in
|
||||
0) continue
|
||||
;;
|
||||
1) if (( $(adj $r $c 2) == 0 )); then
|
||||
1) if (( $(adj "$r" "$c" 2) == 0 )); then
|
||||
((++changed))
|
||||
newrow[c]=2
|
||||
fi
|
||||
#printf "[%d][%d]: %s %s %d\n" $r $c "${row[c]}" "${newrow[c]}" $(adj $r $c 2)
|
||||
;;
|
||||
2) if (( $(adj $r $c 2) >= 4 )); then
|
||||
2) if (( $(adj "$r" "$c" 2) >= 4 )); then
|
||||
((++changed))
|
||||
newrow[c]=1
|
||||
fi
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* debug.c - debug/log management
|
||||
*
|
||||
* Copyright (C) 2021 Bruno Raoult ("br")
|
||||
* Copyright (C) 2021-2022 Bruno Raoult ("br")
|
||||
* Licensed under the GNU General Public License v3.0 or later.
|
||||
* Some rights reserved. See COPYING.
|
||||
*
|
||||
@@ -22,8 +22,9 @@
|
||||
#include "bits.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define NANOSEC 1000000000 /* nano sec in sec */
|
||||
#define MILLISEC 1000000 /* milli sec in sec */
|
||||
#define NS_SEC 1000000000 /* nano sec in sec */
|
||||
#define MS_SEC 1000000 /* microsec in sec */
|
||||
#define NS_MS 1000 /* nano in micro */
|
||||
|
||||
static long long timer_start; /* in nanosecond */
|
||||
static u32 debug_level=0;
|
||||
@@ -41,7 +42,7 @@ void debug_init(u32 level)
|
||||
|
||||
debug_level_set(level);
|
||||
if (!clock_gettime(CLOCK_MONOTONIC, &timer)) {
|
||||
timer_start = timer.tv_sec * NANOSEC + timer.tv_nsec;
|
||||
timer_start = timer.tv_sec * NS_SEC + timer.tv_nsec;
|
||||
}
|
||||
else {
|
||||
timer_start = 0;
|
||||
@@ -54,10 +55,9 @@ inline static long long timer_elapsed()
|
||||
struct timespec timer;
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &timer);
|
||||
return (timer.tv_sec * NANOSEC + timer.tv_nsec) - timer_start;
|
||||
return (timer.tv_sec * NS_SEC + timer.tv_nsec) - timer_start;
|
||||
}
|
||||
|
||||
|
||||
/* void debug - log function
|
||||
* @timestamp : boolean
|
||||
* @indent : indent level (2 spaces each)
|
||||
@@ -77,8 +77,8 @@ void debug(u32 level, bool timestamp, u32 indent, const char *src,
|
||||
|
||||
if (timestamp) {
|
||||
long long diff = timer_elapsed();
|
||||
printf("%lld.%03lld ", diff/NANOSEC, (diff/1000000)%1000);
|
||||
printf("%010lld ", diff);
|
||||
printf("%lld.%03lld ", diff / NS_SEC, (diff % NS_SEC) / NS_MS);
|
||||
printf("%010lldμs ", diff / NS_MS);
|
||||
}
|
||||
|
||||
if (src) {
|
||||
|
||||
308
2022/RESULTS.txt
308
2022/RESULTS.txt
@@ -5,17 +5,313 @@
|
||||
+++++++++++++++++ part 1
|
||||
aoc.bash: res=66719
|
||||
time: 0:00.03 real, 0.02 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+274
|
||||
context-switch: 0+1, page-faults: 0+257
|
||||
|
||||
aoc-c : res=66719
|
||||
aoc-c: res=66719
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+89
|
||||
context-switch: 0+1, page-faults: 0+88
|
||||
|
||||
+++++++++++++++++ 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
|
||||
context-switch: 2+1, page-faults: 0+259
|
||||
|
||||
aoc-c : res=198551
|
||||
aoc-c: res=198551
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 5+1, page-faults: 0+87
|
||||
context-switch: 0+1, page-faults: 0+87
|
||||
|
||||
=========================================
|
||||
================= day02 =================
|
||||
=========================================
|
||||
|
||||
+++++++++++++++++ part 1
|
||||
aoc.bash: res=11841
|
||||
time: 0:00.05 real, 0.05 user, 0.00 sys
|
||||
context-switch: 7+1, page-faults: 0+273
|
||||
|
||||
aoc-c: res=11841
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+87
|
||||
|
||||
+++++++++++++++++ part 2
|
||||
aoc.bash: res=13022
|
||||
time: 0:00.05 real, 0.03 user, 0.01 sys
|
||||
context-switch: 9+1, page-faults: 0+272
|
||||
|
||||
aoc-c: res=13022
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+87
|
||||
|
||||
=========================================
|
||||
================= day03 =================
|
||||
=========================================
|
||||
|
||||
+++++++++++++++++ part 1
|
||||
aoc.bash: res=7878
|
||||
time: 0:00.02 real, 0.01 user, 0.00 sys
|
||||
context-switch: 2+1, page-faults: 0+301
|
||||
|
||||
aoc-c: res=7878
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+87
|
||||
|
||||
+++++++++++++++++ part 2
|
||||
aoc.bash: res=2760
|
||||
time: 0:00.01 real, 0.01 user, 0.00 sys
|
||||
context-switch: 1+1, page-faults: 0+282
|
||||
|
||||
aoc-c: res=2760
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+88
|
||||
|
||||
=========================================
|
||||
================= day04 =================
|
||||
=========================================
|
||||
|
||||
+++++++++++++++++ part 1
|
||||
aoc.bash: res=444
|
||||
time: 0:00.02 real, 0.01 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+258
|
||||
|
||||
aoc-c: res=444
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+87
|
||||
|
||||
+++++++++++++++++ part 2
|
||||
aoc.bash: res=801
|
||||
time: 0:00.02 real, 0.01 user, 0.00 sys
|
||||
context-switch: 1+1, page-faults: 0+261
|
||||
|
||||
aoc-c: res=801
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+87
|
||||
|
||||
=========================================
|
||||
================= day05 =================
|
||||
=========================================
|
||||
|
||||
+++++++++++++++++ part 1
|
||||
aoc.bash: res=VQZNJMWTR
|
||||
time: 0:00.08 real, 0.06 user, 0.01 sys
|
||||
context-switch: 3+1, page-faults: 0+274
|
||||
|
||||
aoc-c: res=VQZNJMWTR
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+87
|
||||
|
||||
+++++++++++++++++ part 2
|
||||
aoc.bash: res=NLCDCLVMQ
|
||||
time: 0:00.04 real, 0.02 user, 0.01 sys
|
||||
context-switch: 20+1, page-faults: 0+274
|
||||
|
||||
aoc-c: res=NLCDCLVMQ
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+86
|
||||
|
||||
=========================================
|
||||
================= day06 =================
|
||||
=========================================
|
||||
|
||||
+++++++++++++++++ part 1
|
||||
aoc.bash: res=1658
|
||||
time: 0:00.06 real, 0.06 user, 0.00 sys
|
||||
context-switch: 1+1, page-faults: 0+266
|
||||
|
||||
aoc-c: res=1658
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+87
|
||||
|
||||
+++++++++++++++++ part 2
|
||||
aoc.bash: res=2260
|
||||
time: 0:00.09 real, 0.09 user, 0.00 sys
|
||||
context-switch: 1+1, page-faults: 0+265
|
||||
|
||||
aoc-c: res=2260
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+87
|
||||
|
||||
=========================================
|
||||
================= day07 =================
|
||||
=========================================
|
||||
|
||||
+++++++++++++++++ part 1
|
||||
aoc.bash: res=1390824
|
||||
time: 0:00.05 real, 0.03 user, 0.01 sys
|
||||
context-switch: 7+1, page-faults: 0+307
|
||||
|
||||
aoc-c: res=1390824
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+98
|
||||
|
||||
+++++++++++++++++ part 2
|
||||
aoc.bash: res=7490863
|
||||
time: 0:00.05 real, 0.05 user, 0.00 sys
|
||||
context-switch: 9+1, page-faults: 0+308
|
||||
|
||||
aoc-c: res=7490863
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+98
|
||||
|
||||
=========================================
|
||||
================= day08 =================
|
||||
=========================================
|
||||
|
||||
+++++++++++++++++ part 1
|
||||
aoc.bash: res=1698
|
||||
time: 0:01.10 real, 1.10 user, 0.00 sys
|
||||
context-switch: 5+1, page-faults: 0+319
|
||||
|
||||
aoc-c: res=1698
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+92
|
||||
|
||||
+++++++++++++++++ part 2
|
||||
aoc.bash: res=672280
|
||||
time: 0:03.54 real, 3.53 user, 0.00 sys
|
||||
context-switch: 48+1, page-faults: 0+284
|
||||
|
||||
aoc-c: res=672280
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+91
|
||||
|
||||
=========================================
|
||||
================= day09 =================
|
||||
=========================================
|
||||
|
||||
+++++++++++++++++ part 1
|
||||
aoc.bash: res=5619
|
||||
time: 0:00.69 real, 0.69 user, 0.00 sys
|
||||
context-switch: 38+1, page-faults: 0+430
|
||||
|
||||
aoc-c: res=5619
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+158
|
||||
|
||||
+++++++++++++++++ part 2
|
||||
aoc.bash: res=2376
|
||||
time: 0:03.25 real, 3.24 user, 0.00 sys
|
||||
context-switch: 46+1, page-faults: 0+340
|
||||
|
||||
aoc-c: res=2376
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+131
|
||||
|
||||
=========================================
|
||||
================= day10 =================
|
||||
=========================================
|
||||
|
||||
+++++++++++++++++ part 1
|
||||
aoc.bash: res=13220
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+260
|
||||
|
||||
aoc-c: res=13220
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+88
|
||||
|
||||
+++++++++++++++++ part 2
|
||||
aoc.bash: res=
|
||||
###..#..#..##..#..#.#..#.###..####.#..##
|
||||
#..#.#..#.#..#.#.#..#..#.#..#.#....#.#..
|
||||
#..#.#..#.#..#.##...####.###..###..##..#
|
||||
###..#..#.####.#.#..#..#.#..#.#....#.#.#
|
||||
#.#..#..#.#..#.#.#..#..#.#..#.#....#.#..
|
||||
#..#..##..#..#.#..#.#..#.###..####.#..#.
|
||||
time: 0:00.01 real, 0.00 user, 0.00 sys
|
||||
context-switch: 3+1, page-faults: 0+262
|
||||
|
||||
###..#..#..##..#..#.#..#.###..####.#..##
|
||||
#..#.#..#.#..#.#.#..#..#.#..#.#....#.#..
|
||||
#..#.#..#.#..#.##...####.###..###..##..#
|
||||
###..#..#.####.#.#..#..#.#..#.#....#.#.#
|
||||
#.#..#..#.#..#.#.#..#..#.#..#.#....#.#..
|
||||
#..#..##..#..#.#..#.#..#.###..####.#..#.
|
||||
aoc-c: res=0
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+88
|
||||
|
||||
=========================================
|
||||
================= day11 =================
|
||||
=========================================
|
||||
|
||||
+++++++++++++++++ part 1
|
||||
aoc.bash: res=54253
|
||||
time: 0:00.05 real, 0.04 user, 0.00 sys
|
||||
context-switch: 1+1, page-faults: 0+268
|
||||
|
||||
aoc-c: res=54253
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+87
|
||||
|
||||
+++++++++++++++++ part 2
|
||||
aoc.bash: res=13119526120
|
||||
time: 0:16.49 real, 16.48 user, 0.00 sys
|
||||
context-switch: 106+1, page-faults: 0+270
|
||||
|
||||
aoc-c: res=13119526120
|
||||
time: 0:00.01 real, 0.01 user, 0.00 sys
|
||||
context-switch: 13+1, page-faults: 0+87
|
||||
|
||||
=========================================
|
||||
================= day12 =================
|
||||
=========================================
|
||||
|
||||
+++++++++++++++++ part 1
|
||||
aoc.bash: res=408
|
||||
time: 0:00.81 real, 0.80 user, 0.00 sys
|
||||
context-switch: 223+1, page-faults: 0+486
|
||||
|
||||
aoc-c: res=408
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+170
|
||||
|
||||
+++++++++++++++++ part 2
|
||||
aoc.bash: res=399
|
||||
time: 0:00.55 real, 0.54 user, 0.01 sys
|
||||
context-switch: 25+1, page-faults: 0+460
|
||||
|
||||
aoc-c: res=399
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+171
|
||||
|
||||
=========================================
|
||||
================= day13 =================
|
||||
=========================================
|
||||
|
||||
+++++++++++++++++ part 1
|
||||
aoc-c: res=5843
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+192
|
||||
|
||||
+++++++++++++++++ part 2
|
||||
aoc-c: res=26289
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 1+1, page-faults: 0+190
|
||||
|
||||
=========================================
|
||||
================= day14 =================
|
||||
=========================================
|
||||
|
||||
+++++++++++++++++ part 1
|
||||
aoc-c: res=665
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+109
|
||||
|
||||
+++++++++++++++++ part 2
|
||||
aoc-c: res=25434
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+121
|
||||
|
||||
=========================================
|
||||
================= day15 =================
|
||||
=========================================
|
||||
|
||||
+++++++++++++++++ part 1
|
||||
aoc-c: res=5176944
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+152
|
||||
|
||||
+++++++++++++++++ part 2
|
||||
aoc-c: res=13350458933732
|
||||
time: 0:00.00 real, 0.00 user, 0.00 sys
|
||||
context-switch: 0+1, page-faults: 0+88
|
||||
|
||||
@@ -71,7 +71,7 @@ int main(int ac, char **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));
|
||||
printf("%s: res=%d\n", *av, calc_top_plist(part == 1? 1: 3));
|
||||
pool_destroy(pool_tot);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
export cmdname=${0##*/}
|
||||
export debug=0
|
||||
export res
|
||||
export LANG=C
|
||||
|
||||
shopt -s extglob
|
||||
set -o noglob
|
||||
@@ -25,7 +26,7 @@ usage() {
|
||||
}
|
||||
|
||||
checkargs() {
|
||||
local part
|
||||
local part=1
|
||||
while getopts p:d: todo; do
|
||||
case "$todo" in
|
||||
d)
|
||||
|
||||
@@ -71,11 +71,11 @@ assembly: aoc-c.s
|
||||
|
||||
part1: aoc-c
|
||||
@$(TIME) aoc.bash -p 1 < $(INPUT) 2>&1
|
||||
@#$(TIME) aoc-c -p 1 < $(INPUT)
|
||||
@$(TIME) aoc-c -p 1 < $(INPUT)
|
||||
|
||||
part2: aoc-c
|
||||
@$(TIME) aoc.bash -p 2 < $(INPUT) 2>&1
|
||||
@#$(TIME) aoc-c -p 2 < $(INPUT)
|
||||
@$(TIME) aoc-c -p 2 < $(INPUT)
|
||||
|
||||
ccls: $(CCLSFILE)
|
||||
|
||||
|
||||
64
2022/day02/aoc-c.c
Normal file
64
2022/day02/aoc-c.c
Normal file
@@ -0,0 +1,64 @@
|
||||
/* aoc-c.c: Advent of Code 2022, day 2
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "plist.h"
|
||||
#include "debug.h"
|
||||
#include "pool.h"
|
||||
#include "aoc.h"
|
||||
|
||||
/* we will use the following convention, for input line "a x":
|
||||
* position in array=(a-'A' * 3) + x - 'X'
|
||||
*/
|
||||
enum {
|
||||
A = 0, B, C,
|
||||
X = 0, Y, Z
|
||||
};
|
||||
#define pos(x, y) ((x) * 3 + (y))
|
||||
|
||||
int outcome[2][9] = { /* shape is known */
|
||||
{
|
||||
[pos(A, X)] = 3 + 1, [pos(A, Y)] = 6 + 2, [pos(A, Z)] = 0 + 3,
|
||||
[pos(B, X)] = 0 + 1, [pos(B, Y)] = 3 + 2, [pos(B, Z)] = 6 + 3,
|
||||
[pos(C, X)] = 6 + 1, [pos(C, Y)] = 0 + 2, [pos(C, Z)] = 3 + 3
|
||||
},
|
||||
{ /* result is known */
|
||||
[pos(A, X)] = 0 + 3, [pos(A, Y)] = 3 + 1, [pos(A, Z)] = 6 + 2,
|
||||
[pos(B, X)] = 0 + 1, [pos(B, Y)] = 3 + 2, [pos(B, Z)] = 6 + 3,
|
||||
[pos(C, X)] = 0 + 2, [pos(C, Y)] = 3 + 3, [pos(C, Z)] = 6 + 1
|
||||
}
|
||||
};
|
||||
|
||||
static int *parse(int *res)
|
||||
{
|
||||
size_t alloc = 0;
|
||||
char *buf = NULL;
|
||||
ssize_t buflen;
|
||||
|
||||
while ((buflen = getline(&buf, &alloc, stdin)) > 0) {
|
||||
for (int i = 0; i < 2; ++i)
|
||||
res[i] += outcome[i][pos(buf[0] - 'A', buf[2] - 'X')];
|
||||
}
|
||||
free(buf);
|
||||
return res;
|
||||
}
|
||||
|
||||
int main(int ac, char **av)
|
||||
{
|
||||
int res[2] = { 0, 0 };
|
||||
|
||||
printf("%s: res=%d\n", *av, parse(res)[parseargs(ac, av) - 1]);
|
||||
exit(0);
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# aoc.bash: Advent of Code 2022, day 1
|
||||
# aoc.bash: Advent of Code 2022, day 2
|
||||
#
|
||||
# Copyright (C) 2022 Bruno Raoult ("br")
|
||||
# Licensed under the GNU General Public License v3.0 or later.
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
export cmdname=${0##*/}
|
||||
export debug=0
|
||||
export res
|
||||
export LANG=C
|
||||
|
||||
shopt -s extglob
|
||||
set -o noglob
|
||||
|
||||
111
2022/day03/Makefile
Normal file
111
2022/day03/Makefile
Normal file
@@ -0,0 +1,111 @@
|
||||
# AOC daily Makefile - GNU make only.
|
||||
#
|
||||
# Copyright (C) 2021-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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
#
|
||||
|
||||
INPUT := input/input.txt
|
||||
SHELL := /bin/bash
|
||||
|
||||
CC := gcc
|
||||
BEAR := bear
|
||||
CCLSFILE:= compile_commands.json
|
||||
|
||||
LIB := aoc_$(shell uname -m)
|
||||
INCDIR := ../include
|
||||
LIBDIR := ../lib
|
||||
LDFLAGS := -L$(LIBDIR)
|
||||
#LDLIB := -l$(LIB) -lm
|
||||
LDLIB := -l$(LIB)
|
||||
|
||||
export LD_LIBRARY_PATH = $(LIBDIR)
|
||||
|
||||
CFLAGS += -std=gnu11
|
||||
CFLAGS += -O2
|
||||
CFLAGS += -g
|
||||
# for gprof
|
||||
# CFLAGS += -pg
|
||||
CFLAGS += -Wall
|
||||
CFLAGS += -Wextra
|
||||
CFLAGS += -march=native
|
||||
# Next one may be useful for valgrind (some invalid instructions)
|
||||
# CFLAGS += -mno-tbm
|
||||
CFLAGS += -Wmissing-declarations
|
||||
CFLAGS += -Wno-unused-result
|
||||
|
||||
CFLAGS += -DDEBUG_DEBUG # activate general debug (debug.c)
|
||||
CFLAGS += -DDEBUG_POOL # memory pools management
|
||||
|
||||
VALGRIND := valgrind
|
||||
VALGRINDFLAGS := --leak-check=full --show-leak-kinds=all --track-origins=yes \
|
||||
--sigill-diagnostics=yes --quiet --show-error-list=yes
|
||||
|
||||
|
||||
TIME := \time -f "\ttime: %E real, %U user, %S sys\n\tcontext-switch:\t%c+%w, page-faults: %F+%R\n"
|
||||
export PATH := .:$(PATH)
|
||||
|
||||
.PHONY: clean all compile assembly memcheck memcheck1 memcheck2 part1 part2 ccls bear org
|
||||
|
||||
all: README.org ccls part1 part2
|
||||
|
||||
memcheck: memcheck1 memcheck2
|
||||
|
||||
memcheck1: aoc-c
|
||||
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 1 < $(INPUT)
|
||||
|
||||
memcheck2: aoc-c
|
||||
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 2 < $(INPUT)
|
||||
@#@valgrind -s --track-origins=yes aoc-c -p 2 < $(INPUT)
|
||||
|
||||
compile: aoc-c
|
||||
|
||||
cpp: aoc-c.i
|
||||
|
||||
assembly: aoc-c.s
|
||||
|
||||
part1: aoc-c
|
||||
@$(TIME) aoc.bash -p 1 < $(INPUT) 2>&1
|
||||
@$(TIME) aoc-c -p 1 < $(INPUT)
|
||||
|
||||
part2: aoc-c
|
||||
@$(TIME) aoc.bash -p 2 < $(INPUT) 2>&1
|
||||
@$(TIME) aoc-c -p 2 < $(INPUT)
|
||||
|
||||
ccls: $(CCLSFILE)
|
||||
|
||||
clean:
|
||||
@rm -f aoc-c core* vgcore* gmon.out aoc-c.s aoc-c.i README.html compile_commands.json
|
||||
|
||||
aoc-c: aoc-c.c common.c
|
||||
@echo compiling $<
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -I $(INCDIR) $^ $(LDLIB) -o $@
|
||||
|
||||
# generate pre-processed file (.i) and assembler (.s)
|
||||
%.i: %.c
|
||||
@echo generating $@
|
||||
@$(CC) -E $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||
|
||||
%.s: %.c
|
||||
@echo generating $@
|
||||
@$(CC) -S -fverbose-asm $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||
|
||||
# generate README.org from README.html (must cleanup !)
|
||||
org: README.org
|
||||
|
||||
%.org: %.html
|
||||
@echo generating $@. Cleanup before commit !
|
||||
@pandoc $< -o $@
|
||||
|
||||
# generate compile_commands.json
|
||||
$(CCLSFILE): aoc-c.c Makefile
|
||||
$(BEAR) -- make clean compile
|
||||
|
||||
bear: clean
|
||||
@touch .ccls-root
|
||||
@$(BEAR) -- make compile
|
||||
114
2022/day03/README.org
Normal file
114
2022/day03/README.org
Normal file
@@ -0,0 +1,114 @@
|
||||
** --- Day 3: Rucksack Reorganization ---
|
||||
One Elf has the important job of loading all of the
|
||||
[[https://en.wikipedia.org/wiki/Rucksack][rucksacks]] with supplies for
|
||||
the jungle journey. Unfortunately, that Elf didn't quite follow the
|
||||
packing instructions, and so a few items now need to be rearranged.
|
||||
|
||||
Each rucksack has two large /compartments/. All items of a given type
|
||||
are meant to go into exactly one of the two compartments. The Elf that
|
||||
did the packing failed to follow this rule for exactly one item type per
|
||||
rucksack.
|
||||
|
||||
The Elves have made a list of all of the items currently in each
|
||||
rucksack (your puzzle input), but they need your help finding the
|
||||
errors. Every item type is identified by a single lowercase or uppercase
|
||||
letter (that is, =a= and =A= refer to different types of items).
|
||||
|
||||
The list of items for each rucksack is given as characters all on a
|
||||
single line. A given rucksack always has the same number of items in
|
||||
each of its two compartments, so the first half of the characters
|
||||
represent items in the first compartment, while the second half of the
|
||||
characters represent items in the second compartment.
|
||||
|
||||
For example, suppose you have the following list of contents from six
|
||||
rucksacks:
|
||||
|
||||
#+begin_example
|
||||
vJrwpWtwJgWrhcsFMMfFFhFp
|
||||
jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
|
||||
PmmdzqPrVvPwwTWBwg
|
||||
wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn
|
||||
ttgJtRGJQctTZtZT
|
||||
CrZsJsPPZsGzwwsLwLmpwMDw
|
||||
#+end_example
|
||||
|
||||
- The first rucksack contains the items =vJrwpWtwJgWrhcsFMMfFFhFp=,
|
||||
which means its first compartment contains the items =vJrwpWtwJgWr=,
|
||||
while the second compartment contains the items =hcsFMMfFFhFp=. The
|
||||
only item type that appears in both compartments is lowercase =p=.
|
||||
- The second rucksack's compartments contain =jqHRNqRjqzjGDLGL= and
|
||||
=rsFMfFZSrLrFZsSL=. The only item type that appears in both
|
||||
compartments is uppercase =L=.
|
||||
- The third rucksack's compartments contain =PmmdzqPrV= and =vPwwTWBwg=;
|
||||
the only common item type is uppercase =P=.
|
||||
- The fourth rucksack's compartments only share item type =v=.
|
||||
- The fifth rucksack's compartments only share item type =t=.
|
||||
- The sixth rucksack's compartments only share item type =s=.
|
||||
|
||||
To help prioritize item rearrangement, every item type can be converted
|
||||
to a /priority/:
|
||||
|
||||
- Lowercase item types =a= through =z= have priorities 1 through 26.
|
||||
- Uppercase item types =A= through =Z= have priorities 27 through 52.
|
||||
|
||||
In the above example, the priority of the item type that appears in both
|
||||
compartments of each rucksack is 16 (=p=), 38 (=L=), 42 (=P=), 22 (=v=),
|
||||
20 (=t=), and 19 (=s=); the sum of these is =157=.
|
||||
|
||||
Find the item type that appears in both compartments of each rucksack.
|
||||
/What is the sum of the priorities of those item types?/
|
||||
|
||||
Your puzzle answer was =7878=.
|
||||
|
||||
** --- Part Two ---
|
||||
As you finish identifying the misplaced items, the Elves come to you
|
||||
with another issue.
|
||||
|
||||
For safety, the Elves are divided into groups of three. Every Elf
|
||||
carries a badge that identifies their group. For efficiency, within each
|
||||
group of three Elves, the badge is the /only item type carried by all
|
||||
three Elves/. That is, if a group's badge is item type =B=, then all
|
||||
three Elves will have item type =B= somewhere in their rucksack, and at
|
||||
most two of the Elves will be carrying any other item type.
|
||||
|
||||
The problem is that someone forgot to put this year's updated
|
||||
authenticity sticker on the badges. All of the badges need to be pulled
|
||||
out of the rucksacks so the new authenticity stickers can be attached.
|
||||
|
||||
Additionally, nobody wrote down which item type corresponds to each
|
||||
group's badges. The only way to tell which item type is the right one is
|
||||
by finding the one item type that is /common between all three Elves/ in
|
||||
each group.
|
||||
|
||||
Every set of three lines in your list corresponds to a single group, but
|
||||
each group can have a different badge item type. So, in the above
|
||||
example, the first group's rucksacks are the first three lines:
|
||||
|
||||
#+begin_example
|
||||
vJrwpWtwJgWrhcsFMMfFFhFp
|
||||
jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
|
||||
PmmdzqPrVvPwwTWBwg
|
||||
#+end_example
|
||||
|
||||
And the second group's rucksacks are the next three lines:
|
||||
|
||||
#+begin_example
|
||||
wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn
|
||||
ttgJtRGJQctTZtZT
|
||||
CrZsJsPPZsGzwwsLwLmpwMDw
|
||||
#+end_example
|
||||
|
||||
In the first group, the only item type that appears in all three
|
||||
rucksacks is lowercase =r=; this must be their badges. In the second
|
||||
group, their badge item type must be =Z=.
|
||||
|
||||
Priorities for these items must still be found to organize the sticker
|
||||
attachment efforts: here, they are 18 (=r=) for the first group and 52
|
||||
(=Z=) for the second group. The sum of these is =70=.
|
||||
|
||||
Find the item type that corresponds to the badges of each three-Elf
|
||||
group. /What is the sum of the priorities of those item types?/
|
||||
|
||||
Your puzzle answer was =2760=.
|
||||
|
||||
Both parts of this puzzle are complete! They provide two gold stars: **
|
||||
97
2022/day03/aoc-c.c
Normal file
97
2022/day03/aoc-c.c
Normal file
@@ -0,0 +1,97 @@
|
||||
/* aoc-c.c: Advent of Code 2022, day 3
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "aoc.h"
|
||||
|
||||
#define NCHARS ('Z' - 'A' + 1 + 'z' - 'a' + 1)
|
||||
|
||||
/* convert item to map position, and vice versa */
|
||||
#define CHAR2POS(c) ((c) > 'Z'? (c) - 'a': (c) - 'A' + 26)
|
||||
#define POS2CHAR(p) ((p) < 26? (p) + 'a': (p) - 26 + 'A')
|
||||
|
||||
/* set a map from char */
|
||||
#define SET_MAP(ex, c) ((ex)[CHAR2POS(c)] = 1)
|
||||
|
||||
static void map_init(char *p)
|
||||
{
|
||||
memset(p, 0, NCHARS);
|
||||
}
|
||||
|
||||
static void map_populate(char *ex, char *p, int len)
|
||||
{
|
||||
map_init(ex);
|
||||
for (; len; --len)
|
||||
SET_MAP(ex, p[len - 1]);
|
||||
}
|
||||
|
||||
/* match map with items list. If dest is NULL, return first match,
|
||||
* otherwise populate dest with matching chars.
|
||||
*/
|
||||
static int map_match(char *dest, char *map, char *items, int ilen)
|
||||
{
|
||||
if (dest)
|
||||
map_init(dest);
|
||||
|
||||
for (int i = 0; i < ilen; ++i) {
|
||||
int pos = CHAR2POS(items[i]);
|
||||
if (map[pos]) { /* already exists */
|
||||
if (dest)
|
||||
dest[pos] = 1; /* fill dest array */
|
||||
else
|
||||
return pos + 1; /* one match only: return prio */
|
||||
}
|
||||
}
|
||||
return -1; /* unused if dest != NULL */
|
||||
}
|
||||
|
||||
static int parse(int part)
|
||||
{
|
||||
size_t alloc = 0;
|
||||
char *buf = NULL;
|
||||
ssize_t buflen;
|
||||
int line = 0, res = 0;
|
||||
char map[2][NCHARS];
|
||||
|
||||
while ((buflen = getline(&buf, &alloc, stdin)) > 0) {
|
||||
buf[--buflen] = 0;
|
||||
if (part == 1) {
|
||||
int half = buflen / 2;
|
||||
map_populate(*map, buf, half); /* populate and calculate */
|
||||
res += map_match(NULL, *map, buf + half, half);
|
||||
continue;
|
||||
}
|
||||
/* Part 2 here */
|
||||
switch (++line % 3) { /* group lines by 3 */
|
||||
case 1: /* line 1: populate *map */
|
||||
map_populate(*map, buf, buflen);
|
||||
break;
|
||||
case 2: /* line 2: merge #1 into map[1] */
|
||||
map_match(*(map + 1), *map, buf, buflen);
|
||||
break;
|
||||
case 0: /* line 3: final merge & calc */
|
||||
res += map_match(NULL, *(map + 1), buf, buflen);
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(buf);
|
||||
return res;
|
||||
}
|
||||
|
||||
int main(int ac, char **av)
|
||||
{
|
||||
printf("%s: res=%d\n", *av, parse(parseargs(ac, av)));
|
||||
exit(0);
|
||||
}
|
||||
86
2022/day03/aoc.bash
Executable file
86
2022/day03/aoc.bash
Executable file
@@ -0,0 +1,86 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# aoc.bash: Advent of Code 2022, day 3
|
||||
#
|
||||
# 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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
|
||||
. common.bash
|
||||
|
||||
declare -a input
|
||||
|
||||
# prio - get priority value for an item
|
||||
# $1: reference of variable for result
|
||||
# $2: string
|
||||
prio() {
|
||||
local -n _val="$1"
|
||||
local _char="${2:0:1}"
|
||||
|
||||
printf -v _val "%d" "'$_char"
|
||||
if [[ $_char > "Z" ]]; then # a-z
|
||||
((_val += (1 - 97) ))
|
||||
else # A-Z
|
||||
((_val += (27 - 65) ))
|
||||
fi
|
||||
}
|
||||
|
||||
# common=chars - get common characters in two strings
|
||||
# $1: reference of variable for result
|
||||
# $2, $3: The two strings
|
||||
common_chars() {
|
||||
local -n _res="$1"
|
||||
|
||||
_res="${2//[^$3]}"
|
||||
}
|
||||
|
||||
parse() {
|
||||
readarray -t input
|
||||
}
|
||||
|
||||
part1() {
|
||||
local line half1 half2 common
|
||||
local -i half i prio
|
||||
declare -ig res=0
|
||||
|
||||
for line in "${input[@]}"; do
|
||||
(( half = ${#line} / 2 ))
|
||||
half1="${line:0:half}"
|
||||
half2="${line:half}"
|
||||
common="${half1//[^${half2}]}"
|
||||
prio prio "${common}"
|
||||
(( res += prio ))
|
||||
done
|
||||
}
|
||||
|
||||
part2() {
|
||||
local one two three common
|
||||
local -i i prio
|
||||
declare -ig res=0
|
||||
|
||||
for (( i = ${#input[@]} - 1; i > 1; i -= 3)); do
|
||||
three=${input[i]}
|
||||
two=${input[i - 1]}
|
||||
one=${input[i - 2]}
|
||||
common_chars common "$three" "$two"
|
||||
common_chars common "$common" "$one"
|
||||
prio prio "${common}"
|
||||
(( res += prio ))
|
||||
done
|
||||
}
|
||||
|
||||
solve() {
|
||||
if (($1 == 1)); then
|
||||
part1
|
||||
else
|
||||
part2
|
||||
fi
|
||||
}
|
||||
|
||||
main "$@"
|
||||
exit 0
|
||||
17
2022/day03/aoc.h
Normal file
17
2022/day03/aoc.h
Normal file
@@ -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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
#ifndef _AOC_H_
|
||||
#define _AOC_H_
|
||||
|
||||
extern int parseargs(int ac, char**av);
|
||||
|
||||
#endif /* _AOC_H_ */
|
||||
68
2022/day03/common.bash
Executable file
68
2022/day03/common.bash
Executable file
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# common.bash: Advent of Code 2022, common bash 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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
|
||||
# shellcheck disable=2034
|
||||
export cmdname=${0##*/}
|
||||
export debug=0
|
||||
export res
|
||||
export LANG=C
|
||||
|
||||
shopt -s extglob
|
||||
set -o noglob
|
||||
|
||||
usage() {
|
||||
printf "usage: %s [-d DEBUG] [-p PART]\n" "$cmdname"
|
||||
exit 1
|
||||
}
|
||||
|
||||
checkargs() {
|
||||
local part=1
|
||||
while getopts p:d: todo; do
|
||||
case "$todo" in
|
||||
d)
|
||||
if [[ "$OPTARG" =~ ^[[:digit:]+]$ ]]; then
|
||||
debug="$OPTARG"
|
||||
else
|
||||
printf "%s: illegal [%s] debug level.\n" "$CMD" "$OPTARG"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
p)
|
||||
if [[ "$OPTARG" =~ ^[12]$ ]]; then
|
||||
part="$OPTARG"
|
||||
else
|
||||
printf "%s: illegal [%s] part.\n" "$CMD" "$OPTARG"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
# Now check remaining argument (backup directory)
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
(( $# > 1 )) && usage
|
||||
return "$part"
|
||||
}
|
||||
|
||||
main() {
|
||||
local -i part
|
||||
|
||||
checkargs "$@"
|
||||
part=$?
|
||||
parse "$part"
|
||||
solve "$part"
|
||||
printf "%s: res=%s\n" "$cmdname" "$res"
|
||||
}
|
||||
49
2022/day03/common.c
Normal file
49
2022/day03/common.c
Normal file
@@ -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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
6
2022/day03/input/example.txt
Normal file
6
2022/day03/input/example.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
vJrwpWtwJgWrhcsFMMfFFhFp
|
||||
jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
|
||||
PmmdzqPrVvPwwTWBwg
|
||||
wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn
|
||||
ttgJtRGJQctTZtZT
|
||||
CrZsJsPPZsGzwwsLwLmpwMDw
|
||||
300
2022/day03/input/input.txt
Normal file
300
2022/day03/input/input.txt
Normal file
@@ -0,0 +1,300 @@
|
||||
ZNNvFWHqLNPZHHqPTHHnTGBhrrpjvmwfMmpfpjBjwpmw
|
||||
sbdzQgzgssgbglRtmjlwhjBlfrSrMt
|
||||
zgsCRzJbsdRVQCDbcgLGWWLnZNGVLLZMNZnq
|
||||
tvHhRtZGMvMHvfsrBBCTRbwbccRc
|
||||
qznnlpzzDppWlDpQpCrcrwnBNwTZnBTZrn
|
||||
PdVZJJqVZdllDPFtMjMgLjGMHvSgMF
|
||||
csbhhVDDvzlVDcbccGGvfRjDHCjNLRHRCLfmnZfR
|
||||
dFrStSTTmrrrHVfV
|
||||
MMgQMMTMVTdgWtwTPwSgWSgGbbppJzlplvhBlPbzhlhbzG
|
||||
FDJSTtSGhpPFDmFTZDpTFPmCBBrHqsCBhgBlqqrqrlRrHH
|
||||
dQwMtfdzVwWfwctwnfnQCHllzRrsNzrrgNlCgqsr
|
||||
fLfQnVjfwQfMdfvfnVvWDvtJPFGDpvZGbZpmbSPP
|
||||
TzzCrJcDrTDdLDCJDvGNPCFqlZWlvNvWpq
|
||||
RRHfjsQBFsjgjBQsWqGpNvZQqQlPPQPN
|
||||
VnHBnRVssnnjsSfBwbMSrrbTwJTcwSDF
|
||||
HJCgHCCFFFVGJWTlbqDdlqTDDpgl
|
||||
cZccSmLrfZcrmmzSQftdpDtTHdbQTDMQ
|
||||
NZZccrrBwZRPNNzmcLSSjJhGhVWCnsFnHBjGChsJ
|
||||
qwwwJHTHqdFDtZBFPfFBZFzM
|
||||
gVRcLnnWVgggnnnQgVWWNZtZrBfLBzZzBrMPPrZvPv
|
||||
GQgQSVRtsVnNRGSCdpmwspmbmDpHmhwd
|
||||
bhNgNfgwpbLMhCZMGQBmDm
|
||||
FrcHrSllcqcFFMGLBDQlMDTGlT
|
||||
FVSddRSJRjLwbjJPJw
|
||||
wzhhrTwwTrSsdHQjjSHnBjQj
|
||||
gRDCmVgRgMvtMfVMRBBBhWCHQQHGJHZJQZ
|
||||
NtgVgttVbMNmvsNlpcrLhLTNPw
|
||||
MCgjsfnscgjjgnGgJHHqHDgdHbGr
|
||||
QSSmRFPpRtPFQLQRmPzvBzzzDWqrqWWHJGGNrJJbdtVWHJDV
|
||||
BdSFdLQzRFlSLmQplffwncfscChhcsMj
|
||||
GfVmfnmJVnNVFhnhGmbmhpHvqjrzHZBjfvrtBHHZrwBt
|
||||
ddWQldlMdWMlQsLWTLQgMNwBrvjrZjNrwzZjswHqrv
|
||||
QQdTRcgTRPDlMQlQPQdhcNNnbJmbGpVnGchFmm
|
||||
CjjZCCZfvWZRHHhRtwhvPN
|
||||
mrnqlqMqBlSSLnBTLBwmHPPWhPPHtFRPWzwt
|
||||
rBVTrrMMSMLQBrndGcddWQbbdZfCZJ
|
||||
LFtdjHjLjLqHqstLTjFLFqNMnMhhZdDDNMVbWdDDbhnZ
|
||||
CrBpBGnzrzmczcllrphCZZWJMDWRbbZNMDMR
|
||||
GwgvzpzvrcmBrnfHjTgqTsgHjF
|
||||
rMPPZcplCZlZPwtSwhtBwCQQzB
|
||||
FvDGffLqqmQFwmmhzt
|
||||
TjJjJfHHVDVnHVgZZlQppcVscP
|
||||
hVcqHwhgwwwjHjjGWbvrbBGrsWVWGn
|
||||
CttPRpMmPDTWbWltlLBnGl
|
||||
pZmDFMmPMfnZwqqwfcqJdHgz
|
||||
bSJWhWJCbGGWJPStWTgRQwzDjgQQjsDW
|
||||
nFBBVQVrVBrNFMFZVpBBZFZrDgdTldgsRsslsljsRzTRjzns
|
||||
rMcZcHcBQPvbbHGP
|
||||
mSfmwqfmzrfHwFfmrwvPHqPmMFRlMDDZBCVVRCVZVlZpMRRR
|
||||
TWjdTWhTsssLTGsJNWhTQddjRMDMtNNBSCDBllMMBVtDMVRZ
|
||||
QhWTQcdhjThsdGbTLGjWHmffnmHwnwHrwqmmfcwS
|
||||
LmrsMQnnpfmMLllvTvqvFFzvFHNN
|
||||
WGRFVWdwZWZvCbJzcvJNzw
|
||||
VjGhDtWGSFRGjVVSFdjjDPBfspPnnMBLPLrrpMMm
|
||||
qqqCCJjtqtqCtqLZspHWBdSrWWSzzbzHFWBldb
|
||||
GhwwcwPFVDcNFRRGwwzmlBrBWvllrvSzlrcd
|
||||
DGGhQNNDhTpZZqqLQFQQ
|
||||
QfZmgQQZCCMLfNrgprdNvvdrTg
|
||||
hhttsBmBDcFRBlJshJcRrnjnTvNqpddNNqvndp
|
||||
JtsGJGtGGJJJHDbctllhZHmMwMQSPVPzHSLMPZmV
|
||||
DScSjZcNBZqjDDcLLfFtPfCfjfPvfv
|
||||
pTmRlWhdMwTLGwCf
|
||||
mRdWCVVglWrCmVHVrVCmdrbSzNcBDBqBZDNHqssscNzqNc
|
||||
sPMHGFMsrPNCPnNS
|
||||
ffJzllbzpZBllttBtfglgBTbSCVCmmrNFmmbFNvCFLLb
|
||||
cpZqpfgZZJtJqJJJfWHWhHdHWHjcdRdFHD
|
||||
ZZPfppvzMrlNBFcvFB
|
||||
shJgstJwWLVJwcrFFVFrBVNNqFFB
|
||||
HwWJdLHWWLcQgssHwwSQSQtQzCnZZMpZCmdzZCzpPzpCPRCj
|
||||
QCpLRbsCCQQLbQzCBQDQBBfTTffWtTctJVRNVtnfwtWV
|
||||
GvlqqlGlmMrdsvrhmlcTvwJtwNwTvfJfcWTW
|
||||
lMhgqGhddjqFFCzBBpbsSQpD
|
||||
JJwGJwVQQwVSsSMhQMQgHfgfTtrrfVTNgNNfrt
|
||||
dFDWCDdFppvDFmWWWnJTPllHmHlgrqrgggtH
|
||||
DzFbWjdRpbdFCjjRbnFbQBGhhQBBJZwMhScwZwJz
|
||||
HttvHpHmpJWtHmFNvlvdMSVdPMtLVCCMMMfcfL
|
||||
GjgzhGSGSSdCcRMVjMdc
|
||||
QshbnghgnGDnqsFrNSJFrsNs
|
||||
wJpjMwzjzdVbzPPVpbCHnqGnBqnsBrNCwgrC
|
||||
ftTLLDTQtLTGTGtFrgHrvqgQnrvQsCHH
|
||||
fTcFFfLSfFFcGFllcFhPJPjWWJSjSWzMWPdS
|
||||
ZjNdmjVQVZmvNNZNNZHWZmWtsJnwTpJJswpWwGqJhJqGpp
|
||||
FcRRcDblDMLRcRMLFFMDGsJnqhwpqTTJGwnsfnlp
|
||||
LRBrcLbbgLFgBbFqDvdHQvCCjNzzzVrZdV
|
||||
BdbLWrgdvgWvVJgWnDfNhVnqhCCpDpcq
|
||||
tSQPSTSGPMmlMPtQQPJGtGQRCcnqqfnRhCcChDqnCfRScf
|
||||
jTssPsjMQMmszPjlTtsJdFBFrJzrbJdHZFHdWH
|
||||
vCccctvvTTtZcgLGcZTbssbMWnpMpmLWqnNjpfPPfPjMPp
|
||||
wwBBlRBBwDDVFRhFlRhdRRVWPnnpMpffmmffrpWqVNPm
|
||||
ddhddRzHlQHFJcGsCztTgbNzST
|
||||
fJctfpVWcnfRLfrRwP
|
||||
vmmnvDQDZTNTmGGTqTMTvMqwBdLjBvRzBRrRBRLjjBPzBB
|
||||
GMnmqSTFFQqttcbcJWgsSt
|
||||
rHNfmfRsmfRGfDNcRmcmMQlLCGSnQwwPPCSnzQlSCl
|
||||
bsJTBsVhFsVpqFWFgPCwnQwBZzwQzZLlzn
|
||||
qggTTqvqgqbbTTFqVqgWqvNmmMMRdffftNfMDMmscR
|
||||
rFWQFszrwjsjFWvshPTCmLZLSTLwSLlgSP
|
||||
BQbcqVHNVqVpVpmClJgJJHSmZLJm
|
||||
qBNNNVdDMGBpDcDWsvdQsFrFnjttfj
|
||||
qGhmttmzhtMvhbrLdSHbdSHRzb
|
||||
WCBgQJJpjCQlgdHZrfPRPSRbNg
|
||||
jBTTDjlnjnJDJTQCVntcwtwMSvqcGFDhcvsh
|
||||
ZTrnTqMWWWnfrddMGJPgPLlPbw
|
||||
VvmGRVpBpNNmvNvjVjtpNpCNLLLJHHBdgLPdwsdsbLlwwlwb
|
||||
GmCVSCRVGmpCRVvttmpDrQZfhnzhzqnDWnrZZTQq
|
||||
DQBZHHtWHzSvZvDQWchgqsqqhrrhhcqrcZ
|
||||
jdMfwlFfFlTfndwpjjwGnNrqhPTmPSPTPPhmgrPSrh
|
||||
jlGbwGMdlnJpGFGjpnFCSJzzDDtWHCBBQBvtVC
|
||||
RrbBWBRRWSRsBBVvsPHZDwSjjPdnHwtPtH
|
||||
fTgfzMmNJpmJgfllgpjVQtDDndVQpdnHVtPp
|
||||
gGmlNclTGmGFhLVcVrvLqrvc
|
||||
QcpCTVCZVcCwLcCVvHvvVsCcNzNNSbPRzsDRDSBlsNNzDRtb
|
||||
fggMfJqgrWFpmjWMggmrfMWNSbRSPBDbNtJRtPJzlStBbN
|
||||
gdnmpWGnZvdQCvdv
|
||||
tqqcLqqDDqNtDrqHrrPWlTlTWZTMzTFzQlMPSZ
|
||||
pfnpmmppmppRGjwbjmnjwspWbQQQTMWZbCTSZCSQlCllZF
|
||||
gmpVnGmmmpjDvVLBFqqvrH
|
||||
LqBvJHZvbHGBHrBtGGQTmSVprVzhpVPDPQzQ
|
||||
CRdRgwCfhTVDzSdQ
|
||||
fRCcjgSMjfNgMMLGbGZtvBbGHv
|
||||
HgvtDDzDpvwgvvqdHPZWdMssTTddSs
|
||||
rJFrGNFVQmNFVmRnWhhsrTbhwhZTrdTd
|
||||
VQGBBBVNQClpcBvBwD
|
||||
PWlSzZGmdmGmlGmhggBpvMjvMjFgPJ
|
||||
TtLRDtQQfTVcQQQRtBsJFFccFjWhJJFMBs
|
||||
HqVCNtWHCDwdnlGwGqSr
|
||||
RwdRJgCJRGGmdMbcGbdnTnTtttLLnptMtMtMqZ
|
||||
DWsWPFrPqVPPLVCB
|
||||
zQWWsslsQHFhDSszDSFQzJJJmvcgblRgmNvCJmvNgw
|
||||
tpmFrWTtRpRTtggsSlnQpsnnlSHPsn
|
||||
bZwZjNNZGLSrVsGndPPV
|
||||
NvrcjCfbvvLBDBWfWFgRRm
|
||||
WWFMgWmMhhwDcMMMDcmLWLtQwwsjbsQHvZHbRjZfsZzH
|
||||
PTCplTCdSJJCpvPGNSvsbsfHtbQZzdHjQtjjsj
|
||||
vNGJPpqJvJvqghgFgWFmLD
|
||||
RlRpLTZCjWRjRWwpRsjHjbSbqMqMvvnbnGMnGGqQCq
|
||||
gddfDNczmgPthNcDdgPVnbbzbnJrJJGSSVJJQS
|
||||
BmDmcDmcmhffdBHlRwjRLpwlWQ
|
||||
prQlfzlWRPzgQWzlMPMRppssHHsDsHjwnHHbWDwwbwjL
|
||||
vFBJJtZNShJvZFtdSqtmqjTDVHVGDHbwVHDVsDnThH
|
||||
vcjBZZdZqvCfpzRfcgRp
|
||||
cggpqgRlSpNsgNggbjjj
|
||||
ZZSSJVLVLFDZWNGjCWWbCjsF
|
||||
vZLvfZQQfQtJVJDQShLrLfMmnldmwqwTqqMcMTMTndrm
|
||||
bQBMtBPddtMFbJFhRGzMfzvnRGRSvWnW
|
||||
TmHTqlVHwVpQqjmwGvSgSpnLpzfWGWSn
|
||||
TTrDQCDrrTmDCCCVHHQZBdZFPdsNdFBtFDhtFB
|
||||
fjpQvNZcGhGGTtQS
|
||||
DVJzvbVmHbbtSTSTRStzTM
|
||||
VDvmqllmJfjWlnplNs
|
||||
ZmdHZJjvQLdRjpmLJrqqZBhhtCschPfBPcrDfPffCD
|
||||
MWWSMMwnwlSgzWFFgSwzVwzqcfDCfChCbbtssbfDChcD
|
||||
NMqFTwGqMwgwwgjHRdHRjdmQmQTm
|
||||
TTqWPCWRhTWqPNjPJMNtrlbJFttQwwrBrlbwlc
|
||||
GfpSDGZvpQffSHDgggDZrHctFmrHncnnwwbBtBrt
|
||||
SQGfLsSLZsqMTRNMPT
|
||||
HdBdnBZJTZBBmsfwwBlh
|
||||
MjCVjzwqWrfzplzW
|
||||
vVbqCjjRgjwMbnbGHJScScZHLL
|
||||
dwwwtCdznvDDFrMrrw
|
||||
GmWLQmgQmHgcdGcsTgTDqDbSfFWfMDMfbSNqvr
|
||||
QhTLmVQHLmdLTjGGVptRnZpZBZVRpPpP
|
||||
CzjFpzRHdtBFBCqNqSbJZWcQJTSbQjMTWZ
|
||||
wGwVLlGrdVGwDnwsgfMSZvJMbWJcWlvbbMSc
|
||||
rDfsgggrGnGngsPwdVLfDnmDtzzFNCPHtzCtFHpBRqhPztzR
|
||||
mrgWzBcDtVCcQcCCdscf
|
||||
LRJhjRjPZvqSRGhGjLgMCdHpMNwQCpMHpHMS
|
||||
GRvGJRJjqPZbvGGhRjnqLJWtgFgtzTzDrFnTWrlTlllW
|
||||
cbmcddlffvbTfvFflpZzsMVNznNVlnqnzqHMNM
|
||||
StWJBQRWLRWNPNMCswRVHC
|
||||
BJQBhSWhjSthJQGGWWggJDDDfbdbbfHbddbrFrddvFvv
|
||||
jFqvqvWZWDtBJrrlrq
|
||||
TzGcbHcrmVzMGNSmTcGDtBthJCNtsJDlBCghgP
|
||||
bTrnTccnLSrrTHbnwfLjfdvRRwZFdwfR
|
||||
drHVrdVDfsDbVsdVDbVqRwbZZwCRCCCJlJThwRgT
|
||||
jFPcFpBSvtNPzSFcjcQpcQjpThZCRltGRRRJhwCwGhwgwhRm
|
||||
SQSzPBjjPPSvLqqssdnqLZLMsM
|
||||
bQTWlWlvQclNwwWlCCLStCRSSjStpj
|
||||
zVZZDdBnBmgzVsjsLthSpshdCL
|
||||
DfBnrmBmgzHBfDHmnGrNFCwQvTPvqCTwqTFGbF
|
||||
srSWJnrbmlWlbhzsWszSvPGwvgDhcjdjjfvhjvGv
|
||||
BRRQFLtNfQNMpqpQHDjdDjDcZZcvwZZHPH
|
||||
NLCNCtRQfRttRFRCTqMBqQQrzrbzrlJmVVbsSWmVrTbSzJ
|
||||
RHLfLcSRTFSghLRHGbwZmMZddgJswZsbMm
|
||||
ptqjtCzzQztqCjDlBGpDpbMZdwmMbZsdwNmdJpbs
|
||||
tttzCVllDCtDQnQBVHGHWvWTLWcLSLHf
|
||||
FVlNnPqbGTHftghggJqf
|
||||
zLcZWZpWWrcrZLLZDWrwMcrhBFBttChBmBgptChhtFftmf
|
||||
LZZLrDrrDDMrcwrDwsWFzdTlnGQPQQVbdbnsvnvsVQ
|
||||
BbPNMJNbQvDbvPLwHflczlwwzf
|
||||
pZjWZGZjFGdgpnVgZhghdmcflrlswzzcstlrLwhtwc
|
||||
WZSdqFjqSqSWdGFjZpdMTTDNTvLCRRLLqRQMCN
|
||||
FqgFGtbgTvRwrLqhvw
|
||||
JCCWJWCdJMQNNsSWsMPQRDDLDSDLwTrrvnwfDvnD
|
||||
HdPJlBBHCCQdBMWdTtVbgHczGVGjmtzG
|
||||
PLlZDLZDsFCvbDQv
|
||||
HVcTmVmJqVzqczfzbjvvCFMRfCsWjMvR
|
||||
cqHzTqJTTTTzzmnmrctrBlLlvSlgLdZvSwSlpw
|
||||
SbMMNJjmgMnJdSSbjVFZVSQrlQfWVQVWZh
|
||||
PtqDqPGcLHzHpqLcRzRsfQFfZlfRfZfRFVsl
|
||||
cTDLcqGCzDTqzzDLDzqPTtJvbBJMnmvjbdlmJNvmdgNC
|
||||
tDJDlZVqJGbvHNQbNFFsFPmLns
|
||||
ppczpzpffGwfBNLGmn
|
||||
WShzgTTpWzhWztJJGJSvtvvtjq
|
||||
TbZFTFScnCZFQRTCqQdBjdJqjBqjjQDB
|
||||
rmmLpLLfzrlmslMBHvdRddNDDJDrqD
|
||||
MWwLPzmWfpsMmmlMPMWLwRTZTZnnTcVCcZFCwSnZ
|
||||
SqmClqHssNWCqPTcWcGhBTchVV
|
||||
ZnnnDflRpBVTTVhPBZ
|
||||
DpgfvnvMfCsqlMtSll
|
||||
ZzLMRZpLMwwppZqnQGvQgBSvlNVlBFFNFVrg
|
||||
HcqhTmhmdDTPFTJgTTFBSgJN
|
||||
mccPdDDHbssbtwZMqpbzCRGM
|
||||
TgqnTltgWqLRSRnlqddngFfrvHvrBTfCCFrFVTvVCf
|
||||
cwNJmPzQwNzczzNsJGhhHfhrfvVHGvtvVVfC
|
||||
jjtbtDswcmPWlbgRnRdMZL
|
||||
TmpTBBwvspTptRmsmTGLQDGRHGgVGLSQSMHQ
|
||||
ZlPWqjWrzjPqdrlzbrbrwfrWLHVMLnHDMVDQnLQfQfVngQLS
|
||||
zNwbrrFWbFJpmpmvvt
|
||||
RMQQMwHMMzcFsWsDrWfcpJpS
|
||||
LLhZmGVLhVlTZfWWfWpCrDsGSp
|
||||
VLVTnqjjZngtQRFjvzDM
|
||||
gmRBpjrpRvCfRCrBgvjHShnbnngbgSJnNsHMHS
|
||||
ZDPTwGWtqwHhSnbcMNJw
|
||||
DWGGqtVVqldWZzMzWmvjrjprLRFjRVvvff
|
||||
tCzVzsVtDFzssnSsgdqJdCNqJhmgmpqq
|
||||
PZccPGvQfRLMQwNdhpwhNh
|
||||
jLrcbRjPZBrcPdjRHFlWnVtBFslSWznW
|
||||
vvvbJbWrLvFWHzZzZRhB
|
||||
chtwTmCNlRRZzRPT
|
||||
hmcCssCswrMDGMSrsr
|
||||
LStGBsQLlllhzMzs
|
||||
dzVZDNWRDdZNDTZTPvWVhhphpMlfMccRmfnlMlRn
|
||||
VFvgTrNPdFWNNFNFTzTFFSjSQBCqrtQwSBGLLBGwGL
|
||||
qGJSJhWStdSfWvSvtGRRnzRDDggrgvnzsmRP
|
||||
lTTLpcljjGlLlLNBpjwFQDQmRnrRDPrPscRrDDng
|
||||
NCNjFlHNCTVjpwGqGSVbJddqZZJM
|
||||
MbWdgvHFlMvmzTzShvmm
|
||||
tqjqpLsNsrrsjstNLpQrGVhVBzrhVcfmchDcTPVVmc
|
||||
RqwjqjqsGjjGGQNjGpQZpqRFJgmMHwdbFWgnHMFdwmmCFW
|
||||
HHHLcCcVHjTHglsB
|
||||
wDSRwzzRpMSdNSPSwSpRbqvgBsdqlgTvBFBjgFvvgB
|
||||
RpbzPssDMWwNRbRNRPDsDhJthLQVGLJcctQCJQfQJCLm
|
||||
WsZgbNgZVCCWbVVVmgZbCCRPccGnzPBqJjzWJBJPzvBvGz
|
||||
SpfThHtrHFBPPzJvPntj
|
||||
QHDhhrhpTQpHhQHnfwnTCNlbZCCDLNllZlVsNCNl
|
||||
QtzJFRQLMRnZcZsfcphlPQ
|
||||
qSBbjmWSCNmVldSqqSqmjCSZshfwfrPPZZfcPVZfhgsgPg
|
||||
HqBbHqBGSlNBbltnLLHFJMtRvRTD
|
||||
tcGtDdMcttttHNBlMctldlwjwwqqCLCwDwZjFCZhmnwC
|
||||
VrJgvWWsPvRgVgrJQvfQfzgVzZwCbLZmnmwCwZqmnhjZbnLj
|
||||
sJpffsRWWRJVWWpHltSpnMHGcMTl
|
||||
zNqRbqSbfdcTLLfS
|
||||
ZVPzPnVvdLwLDPfF
|
||||
VWnzQCVWZVMzQRHgqgqrHGtGMp
|
||||
PbHpWfWPvRfbzWPFfRpPDtBwSHMwCBgDwBjDtMMM
|
||||
hTTdZQlcnTcmqVTdcddrDgBSwsjjBgqBtsCgMD
|
||||
hlldTmdJJmJdZvzfFfNJFJgRzR
|
||||
PJWvJBbWsfLQWsLvmCqHCcNLHqHLLcwDqV
|
||||
dQztrZrdwHhptqDH
|
||||
ZrMGjgMSrdzQGQRJPvGGbm
|
||||
RmjljZChlDZBCRRvlmNSLSqMNLzwLvppwQSQ
|
||||
sTnVnPrVGsGTPddJrfgQgqLgGpMNQtgNtNzg
|
||||
sbbTfTdcJPnHbsJfHsdcmDDmmqBZlClmjBRDCZ
|
||||
CJmHLmHFFCFbHsbJsJqvqhQqLDhQZvnQDZnn
|
||||
wGwppTjdWPdgFpGcScBqNnNqNhQlDqnDlZZW
|
||||
pGcgGgTpGjFdwpSFVgSdpPjrMCMffzJzRzztRfHCRsVmtbsz
|
||||
CgBClZfCflPflNZRvfQswwmwmwQsQhgppdhm
|
||||
qbzDGrjLLNLDHDqtJmmhhmQdhwpQhhbp
|
||||
NLGqVqjDjjGrMFrvFWPBRBZnCvfFnT
|
||||
tbrrHsgsVmmmbtgwVsQRqjJMmqMjQfJfLFLD
|
||||
ZvlBGzdvjGfRFJQJ
|
||||
dBppnnBBhdzZncBPlznpnNdWHSsbWthbSCgHrVfgSSwVgr
|
||||
VRvMtRVFHQLvMRQFQtBctrthshTTgCmhTrgWhWZsZZ
|
||||
lzJlGBSPPhzjgZsTCr
|
||||
wJlpJPfDSpwBnddqJDdpPpcvMFHFMvNbvnNMFHHRVVbR
|
||||
CPShbbdlGCdQqlRPGPdlDWDFzjtFjggCDJgWczfF
|
||||
mrHrTrrBMBsmNsrwsBpnfpggDDcjjDDpjzFJzzjtJz
|
||||
BvsNvBLHrrrNvwBTNNsNGbdQhlPGGfqhhRGqLGdl
|
||||
PSSlPtlStGhPNMtwPMPJzDddnbnDNTDDnJqjbz
|
||||
FFVHRwVLvFvVrVHrZcLmRHggjDmdDnDnznnznzQjzdmJddbn
|
||||
WrvgRgcRcRrrcRvgcVrHVrwCCSfsCsGsllhMSSSSMttlSCpG
|
||||
hBPJqVZTqqPSlGlfddfddZvl
|
||||
JWWMJCpnMrmztzdjnzld
|
||||
RbWsrwMrpbRspbWgpwhLJPccNVqLLPSVgVPV
|
||||
hcTrWqcfhwGfWrWMjHjGvDHPmJMDzF
|
||||
ZtlsnZZtLBSbSssnbndjDJJFHFHJPHPsHMTHHM
|
||||
ntRZtSbtZgZStTqchwQfRwNpcq
|
||||
GfLqrsqQGgPgjjQGVcNvTpTpNFcWPvPPpT
|
||||
bRnRLnMZFdCMcpvT
|
||||
RnRhzRlmlhhHhhmhRsqLrfzrGVSrGBSGrL
|
||||
fbMffwdZsncrGcfG
|
||||
qDBjSSLqhLBSmDbjqNhqTLjCGrCHGrvcGWcpWcrGWnCrpm
|
||||
STLDqbhTLqNTNSRhlwZlJlRQFFRwMdPQ
|
||||
TVVGNFggcjPPJzwvQlRRwRvSlcSc
|
||||
frsBbWhtSRzSLfRf
|
||||
qDCqddbsWrqzhsdNmdJNJHjTggFFVV
|
||||
NTWTDrSdFTLtPTGf
|
||||
lZqjHlVRvRltLtRWFMtFLL
|
||||
qvjWzzvVbZpjqllggscdchwDrCphwsdhrD
|
||||
111
2022/day04/Makefile
Normal file
111
2022/day04/Makefile
Normal file
@@ -0,0 +1,111 @@
|
||||
# AOC daily Makefile - GNU make only.
|
||||
#
|
||||
# Copyright (C) 2021-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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
#
|
||||
|
||||
INPUT := input/input.txt
|
||||
SHELL := /bin/bash
|
||||
|
||||
CC := gcc
|
||||
BEAR := bear
|
||||
CCLSFILE:= compile_commands.json
|
||||
|
||||
LIB := aoc_$(shell uname -m)
|
||||
INCDIR := ../include
|
||||
LIBDIR := ../lib
|
||||
LDFLAGS := -L$(LIBDIR)
|
||||
#LDLIB := -l$(LIB) -lm
|
||||
LDLIB := -l$(LIB)
|
||||
|
||||
export LD_LIBRARY_PATH = $(LIBDIR)
|
||||
|
||||
CFLAGS += -std=gnu11
|
||||
CFLAGS += -O2
|
||||
CFLAGS += -g
|
||||
# for gprof
|
||||
# CFLAGS += -pg
|
||||
CFLAGS += -Wall
|
||||
CFLAGS += -Wextra
|
||||
CFLAGS += -march=native
|
||||
# Next one may be useful for valgrind (some invalid instructions)
|
||||
# CFLAGS += -mno-tbm
|
||||
CFLAGS += -Wmissing-declarations
|
||||
CFLAGS += -Wno-unused-result
|
||||
|
||||
CFLAGS += -DDEBUG_DEBUG # activate general debug (debug.c)
|
||||
CFLAGS += -DDEBUG_POOL # memory pools management
|
||||
|
||||
VALGRIND := valgrind
|
||||
VALGRINDFLAGS := --leak-check=full --show-leak-kinds=all --track-origins=yes \
|
||||
--sigill-diagnostics=yes --quiet --show-error-list=yes
|
||||
|
||||
|
||||
TIME := \time -f "\ttime: %E real, %U user, %S sys\n\tcontext-switch:\t%c+%w, page-faults: %F+%R\n"
|
||||
export PATH := .:$(PATH)
|
||||
|
||||
.PHONY: clean all compile assembly memcheck memcheck1 memcheck2 part1 part2 ccls bear org
|
||||
|
||||
all: README.org ccls part1 part2
|
||||
|
||||
memcheck: memcheck1 memcheck2
|
||||
|
||||
memcheck1: aoc-c
|
||||
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 1 < $(INPUT)
|
||||
|
||||
memcheck2: aoc-c
|
||||
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 2 < $(INPUT)
|
||||
@#@valgrind -s --track-origins=yes aoc-c -p 2 < $(INPUT)
|
||||
|
||||
compile: aoc-c
|
||||
|
||||
cpp: aoc-c.i
|
||||
|
||||
assembly: aoc-c.s
|
||||
|
||||
part1: aoc-c
|
||||
@$(TIME) aoc.bash -p 1 < $(INPUT) 2>&1
|
||||
@$(TIME) aoc-c -p 1 < $(INPUT)
|
||||
|
||||
part2: aoc-c
|
||||
@$(TIME) aoc.bash -p 2 < $(INPUT) 2>&1
|
||||
@$(TIME) aoc-c -p 2 < $(INPUT)
|
||||
|
||||
ccls: $(CCLSFILE)
|
||||
|
||||
clean:
|
||||
@rm -f aoc-c core* vgcore* gmon.out aoc-c.s aoc-c.i README.html compile_commands.json
|
||||
|
||||
aoc-c: aoc-c.c common.c
|
||||
@echo compiling $<
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -I $(INCDIR) $^ $(LDLIB) -o $@
|
||||
|
||||
# generate pre-processed file (.i) and assembler (.s)
|
||||
%.i: %.c
|
||||
@echo generating $@
|
||||
@$(CC) -E $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||
|
||||
%.s: %.c
|
||||
@echo generating $@
|
||||
@$(CC) -S -fverbose-asm $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||
|
||||
# generate README.org from README.html (must cleanup !)
|
||||
org: README.org
|
||||
|
||||
%.org: %.html
|
||||
@echo generating $@. Cleanup before commit !
|
||||
@pandoc $< -o $@
|
||||
|
||||
# generate compile_commands.json
|
||||
$(CCLSFILE): aoc-c.c Makefile
|
||||
$(BEAR) -- make clean compile
|
||||
|
||||
bear: clean
|
||||
@touch .ccls-root
|
||||
@$(BEAR) -- make compile
|
||||
90
2022/day04/README.org
Normal file
90
2022/day04/README.org
Normal file
@@ -0,0 +1,90 @@
|
||||
** --- Day 4: Camp Cleanup ---
|
||||
Space needs to be cleared before the last supplies can be unloaded from
|
||||
the ships, and so several Elves have been assigned the job of cleaning
|
||||
up sections of the camp. Every section has a unique /ID number/, and
|
||||
each Elf is assigned a range of section IDs.
|
||||
|
||||
However, as some of the Elves compare their section assignments with
|
||||
each other, they've noticed that many of the assignments /overlap/. To
|
||||
try to quickly find overlaps and reduce duplicated effort, the Elves
|
||||
pair up and make a /big list of the section assignments for each pair/
|
||||
(your puzzle input).
|
||||
|
||||
For example, consider the following list of section assignment pairs:
|
||||
|
||||
#+begin_example
|
||||
2-4,6-8
|
||||
2-3,4-5
|
||||
5-7,7-9
|
||||
2-8,3-7
|
||||
6-6,4-6
|
||||
2-6,4-8
|
||||
#+end_example
|
||||
|
||||
For the first few pairs, this list means:
|
||||
|
||||
- Within the first pair of Elves, the first Elf was assigned sections
|
||||
=2-4= (sections =2=, =3=, and =4=), while the second Elf was assigned
|
||||
sections =6-8= (sections =6=, =7=, =8=).
|
||||
- The Elves in the second pair were each assigned two sections.
|
||||
- The Elves in the third pair were each assigned three sections: one got
|
||||
sections =5=, =6=, and =7=, while the other also got =7=, plus =8= and
|
||||
=9=.
|
||||
|
||||
This example list uses single-digit section IDs to make it easier to
|
||||
draw; your actual list might contain larger numbers. Visually, these
|
||||
pairs of section assignments look like this:
|
||||
|
||||
#+begin_example
|
||||
.234..... 2-4
|
||||
.....678. 6-8
|
||||
|
||||
.23...... 2-3
|
||||
...45.... 4-5
|
||||
|
||||
....567.. 5-7
|
||||
......789 7-9
|
||||
|
||||
.2345678. 2-8
|
||||
..34567.. 3-7
|
||||
|
||||
.....6... 6-6
|
||||
...456... 4-6
|
||||
|
||||
.23456... 2-6
|
||||
...45678. 4-8
|
||||
#+end_example
|
||||
|
||||
Some of the pairs have noticed that one of their assignments /fully
|
||||
contains/ the other. For example, =2-8= fully contains =3-7=, and =6-6=
|
||||
is fully contained by =4-6=. In pairs where one assignment fully
|
||||
contains the other, one Elf in the pair would be exclusively cleaning
|
||||
sections their partner will already be cleaning, so these seem like the
|
||||
most in need of reconsideration. In this example, there are =2= such
|
||||
pairs.
|
||||
|
||||
/In how many assignment pairs does one range fully contain the other?/
|
||||
|
||||
Your puzzle answer was =444=.
|
||||
|
||||
** --- Part Two ---
|
||||
It seems like there is still quite a bit of duplicate work planned.
|
||||
Instead, the Elves would like to know the number of pairs that /overlap
|
||||
at all/.
|
||||
|
||||
In the above example, the first two pairs (=2-4,6-8= and =2-3,4-5=)
|
||||
don't overlap, while the remaining four pairs (=5-7,7-9=, =2-8,3-7=,
|
||||
=6-6,4-6=, and =2-6,4-8=) do overlap:
|
||||
|
||||
- =5-7,7-9= overlaps in a single section, =7=.
|
||||
- =2-8,3-7= overlaps all of the sections =3= through =7=.
|
||||
- =6-6,4-6= overlaps in a single section, =6=.
|
||||
- =2-6,4-8= overlaps in sections =4=, =5=, and =6=.
|
||||
|
||||
So, in this example, the number of overlapping assignment pairs is =4=.
|
||||
|
||||
/In how many assignment pairs do the ranges overlap?/
|
||||
|
||||
Your puzzle answer was =801=.
|
||||
|
||||
Both parts of this puzzle are complete! They provide two gold stars: **
|
||||
43
2022/day04/aoc-c.c
Normal file
43
2022/day04/aoc-c.c
Normal file
@@ -0,0 +1,43 @@
|
||||
/* aoc-c.c: Advent of Code 2022, day 4
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "aoc.h"
|
||||
|
||||
static int parse(int part)
|
||||
{
|
||||
int res = 0, val[4];
|
||||
|
||||
while (scanf("%d-%d,%d-%d", val, val+1, val+2, val+3) == 4) {
|
||||
if (part == 1) {
|
||||
if ( (val[0] >= val[2] && val[1] <= val[3] ) ||
|
||||
(val[0] <= val[2] && val[1] >= val[3] ) ) {
|
||||
res++;
|
||||
}
|
||||
} else {
|
||||
if ( (val[0] >= val[2] && val[0] <= val[3] ) ||
|
||||
(val[0] <= val[2] && val[1] >= val[2] ) ) {
|
||||
res++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int main(int ac, char **av)
|
||||
{
|
||||
printf("%s: res=%d\n", *av, parse(parseargs(ac, av)));
|
||||
exit(0);
|
||||
}
|
||||
37
2022/day04/aoc.bash
Executable file
37
2022/day04/aoc.bash
Executable file
@@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# aoc.bash: Advent of Code 2022, day 4
|
||||
#
|
||||
# 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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
|
||||
. common.bash
|
||||
|
||||
parse() {
|
||||
local -i _part="$1"
|
||||
local -a _arr
|
||||
declare -ig res=0
|
||||
|
||||
while IFS=-, read -ra _arr; do
|
||||
# shellcheck disable=2068
|
||||
set -- ${_arr[@]}
|
||||
if (( _part == 1 )); then
|
||||
(( ( ($1 >= $3 && $2 <= $4) || ($1 <= $3 && $2 >= $4) ) && res++ ))
|
||||
else
|
||||
(( ( ($1 >= $3 && $1 <= $4) || ($1 <= $3 && $2 >= $3) ) && res++ ))
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
solve() {
|
||||
:
|
||||
}
|
||||
|
||||
main "$@"
|
||||
exit 0
|
||||
17
2022/day04/aoc.h
Normal file
17
2022/day04/aoc.h
Normal file
@@ -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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
#ifndef _AOC_H_
|
||||
#define _AOC_H_
|
||||
|
||||
extern int parseargs(int ac, char**av);
|
||||
|
||||
#endif /* _AOC_H_ */
|
||||
68
2022/day04/common.bash
Executable file
68
2022/day04/common.bash
Executable file
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# common.bash: Advent of Code 2022, common bash 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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
|
||||
# shellcheck disable=2034
|
||||
export cmdname=${0##*/}
|
||||
export debug=0
|
||||
export res
|
||||
export LANG=C
|
||||
|
||||
shopt -s extglob
|
||||
set -o noglob
|
||||
|
||||
usage() {
|
||||
printf "usage: %s [-d DEBUG] [-p PART]\n" "$cmdname"
|
||||
exit 1
|
||||
}
|
||||
|
||||
checkargs() {
|
||||
local part=1
|
||||
while getopts p:d: todo; do
|
||||
case "$todo" in
|
||||
d)
|
||||
if [[ "$OPTARG" =~ ^[[:digit:]+]$ ]]; then
|
||||
debug="$OPTARG"
|
||||
else
|
||||
printf "%s: illegal [%s] debug level.\n" "$CMD" "$OPTARG"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
p)
|
||||
if [[ "$OPTARG" =~ ^[12]$ ]]; then
|
||||
part="$OPTARG"
|
||||
else
|
||||
printf "%s: illegal [%s] part.\n" "$CMD" "$OPTARG"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
# Now check remaining argument (backup directory)
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
(( $# > 1 )) && usage
|
||||
return "$part"
|
||||
}
|
||||
|
||||
main() {
|
||||
local -i part
|
||||
|
||||
checkargs "$@"
|
||||
part=$?
|
||||
parse "$part"
|
||||
solve "$part"
|
||||
printf "%s: res=%s\n" "$cmdname" "$res"
|
||||
}
|
||||
49
2022/day04/common.c
Normal file
49
2022/day04/common.c
Normal file
@@ -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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
6
2022/day04/input/example.txt
Normal file
6
2022/day04/input/example.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
2-4,6-8
|
||||
2-3,4-5
|
||||
5-7,7-9
|
||||
2-8,3-7
|
||||
6-6,4-6
|
||||
2-6,4-8
|
||||
1000
2022/day04/input/input.txt
Normal file
1000
2022/day04/input/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
111
2022/day05/Makefile
Normal file
111
2022/day05/Makefile
Normal file
@@ -0,0 +1,111 @@
|
||||
# AOC daily Makefile - GNU make only.
|
||||
#
|
||||
# Copyright (C) 2021-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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
#
|
||||
|
||||
INPUT := input/input.txt
|
||||
SHELL := /bin/bash
|
||||
|
||||
CC := gcc
|
||||
BEAR := bear
|
||||
CCLSFILE:= compile_commands.json
|
||||
|
||||
LIB := aoc_$(shell uname -m)
|
||||
INCDIR := ../include
|
||||
LIBDIR := ../lib
|
||||
LDFLAGS := -L$(LIBDIR)
|
||||
#LDLIB := -l$(LIB) -lm
|
||||
LDLIB := -l$(LIB)
|
||||
|
||||
export LD_LIBRARY_PATH = $(LIBDIR)
|
||||
|
||||
CFLAGS += -std=gnu11
|
||||
CFLAGS += -O2
|
||||
CFLAGS += -g
|
||||
# for gprof
|
||||
# CFLAGS += -pg
|
||||
CFLAGS += -Wall
|
||||
CFLAGS += -Wextra
|
||||
CFLAGS += -march=native
|
||||
# Next one may be useful for valgrind (some invalid instructions)
|
||||
# CFLAGS += -mno-tbm
|
||||
CFLAGS += -Wmissing-declarations
|
||||
CFLAGS += -Wno-unused-result
|
||||
|
||||
CFLAGS += -DDEBUG_DEBUG # activate general debug (debug.c)
|
||||
CFLAGS += -DDEBUG_POOL # memory pools management
|
||||
|
||||
VALGRIND := valgrind
|
||||
VALGRINDFLAGS := --leak-check=full --show-leak-kinds=all --track-origins=yes \
|
||||
--sigill-diagnostics=yes --quiet --show-error-list=yes
|
||||
|
||||
|
||||
TIME := \time -f "\ttime: %E real, %U user, %S sys\n\tcontext-switch:\t%c+%w, page-faults: %F+%R\n"
|
||||
export PATH := .:$(PATH)
|
||||
|
||||
.PHONY: clean all compile assembly memcheck memcheck1 memcheck2 part1 part2 ccls bear org
|
||||
|
||||
all: README.org ccls part1 part2
|
||||
|
||||
memcheck: memcheck1 memcheck2
|
||||
|
||||
memcheck1: aoc-c
|
||||
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 1 < $(INPUT)
|
||||
|
||||
memcheck2: aoc-c
|
||||
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 2 < $(INPUT)
|
||||
@#@valgrind -s --track-origins=yes aoc-c -p 2 < $(INPUT)
|
||||
|
||||
compile: aoc-c
|
||||
|
||||
cpp: aoc-c.i
|
||||
|
||||
assembly: aoc-c.s
|
||||
|
||||
part1: aoc-c
|
||||
@$(TIME) aoc.bash -p 1 < $(INPUT) 2>&1
|
||||
@$(TIME) aoc-c -p 1 < $(INPUT)
|
||||
|
||||
part2: aoc-c
|
||||
@$(TIME) aoc.bash -p 2 < $(INPUT) 2>&1
|
||||
@$(TIME) aoc-c -p 2 < $(INPUT)
|
||||
|
||||
ccls: $(CCLSFILE)
|
||||
|
||||
clean:
|
||||
@rm -f aoc-c core* vgcore* gmon.out aoc-c.s aoc-c.i README.html compile_commands.json
|
||||
|
||||
aoc-c: aoc-c.c common.c
|
||||
@echo compiling $<
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -I $(INCDIR) $^ $(LDLIB) -o $@
|
||||
|
||||
# generate pre-processed file (.i) and assembler (.s)
|
||||
%.i: %.c
|
||||
@echo generating $@
|
||||
@$(CC) -E $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||
|
||||
%.s: %.c
|
||||
@echo generating $@
|
||||
@$(CC) -S -fverbose-asm $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||
|
||||
# generate README.org from README.html (must cleanup !)
|
||||
org: README.org
|
||||
|
||||
%.org: %.html
|
||||
@echo generating $@. Cleanup before commit !
|
||||
@pandoc $< -o $@
|
||||
|
||||
# generate compile_commands.json
|
||||
$(CCLSFILE): aoc-c.c Makefile
|
||||
$(BEAR) -- make clean compile
|
||||
|
||||
bear: clean
|
||||
@touch .ccls-root
|
||||
@$(BEAR) -- make compile
|
||||
169
2022/day05/README.org
Normal file
169
2022/day05/README.org
Normal file
@@ -0,0 +1,169 @@
|
||||
** --- Day 5: Supply Stacks ---
|
||||
The expedition can depart as soon as the final supplies have been
|
||||
unloaded from the ships. Supplies are stored in stacks of marked
|
||||
/crates/, but because the needed supplies are buried under many other
|
||||
crates, the crates need to be rearranged.
|
||||
|
||||
The ship has a /giant cargo crane/ capable of moving crates between
|
||||
stacks. To ensure none of the crates get crushed or fall over, the crane
|
||||
operator will rearrange them in a series of carefully-planned steps.
|
||||
After the crates are rearranged, the desired crates will be at the top
|
||||
of each stack.
|
||||
|
||||
The Elves don't want to interrupt the crane operator during this
|
||||
delicate procedure, but they forgot to ask her /which/ crate will end up
|
||||
where, and they want to be ready to unload them as soon as possible so
|
||||
they can embark.
|
||||
|
||||
They do, however, have a drawing of the starting stacks of crates /and/
|
||||
the rearrangement procedure (your puzzle input). For example:
|
||||
|
||||
#+begin_example
|
||||
[D]
|
||||
[N] [C]
|
||||
[Z] [M] [P]
|
||||
1 2 3
|
||||
|
||||
move 1 from 2 to 1
|
||||
move 3 from 1 to 3
|
||||
move 2 from 2 to 1
|
||||
move 1 from 1 to 2
|
||||
#+end_example
|
||||
|
||||
In this example, there are three stacks of crates. Stack 1 contains two
|
||||
crates: crate =Z= is on the bottom, and crate =N= is on top. Stack 2
|
||||
contains three crates; from bottom to top, they are crates =M=, =C=, and
|
||||
=D=. Finally, stack 3 contains a single crate, =P=.
|
||||
|
||||
Then, the rearrangement procedure is given. In each step of the
|
||||
procedure, a quantity of crates is moved from one stack to a different
|
||||
stack. In the first step of the above rearrangement procedure, one crate
|
||||
is moved from stack 2 to stack 1, resulting in this configuration:
|
||||
|
||||
#+begin_example
|
||||
[D]
|
||||
[N] [C]
|
||||
[Z] [M] [P]
|
||||
1 2 3
|
||||
#+end_example
|
||||
|
||||
In the second step, three crates are moved from stack 1 to stack 3.
|
||||
Crates are moved /one at a time/, so the first crate to be moved (=D=)
|
||||
ends up below the second and third crates:
|
||||
|
||||
#+begin_example
|
||||
[Z]
|
||||
[N]
|
||||
[C] [D]
|
||||
[M] [P]
|
||||
1 2 3
|
||||
#+end_example
|
||||
|
||||
Then, both crates are moved from stack 2 to stack 1. Again, because
|
||||
crates are moved /one at a time/, crate =C= ends up below crate =M=:
|
||||
|
||||
#+begin_example
|
||||
[Z]
|
||||
[N]
|
||||
[M] [D]
|
||||
[C] [P]
|
||||
1 2 3
|
||||
#+end_example
|
||||
|
||||
Finally, one crate is moved from stack 1 to stack 2:
|
||||
|
||||
#+begin_example
|
||||
[Z]
|
||||
[N]
|
||||
[D]
|
||||
[C] [M] [P]
|
||||
1 2 3
|
||||
#+end_example
|
||||
|
||||
The Elves just need to know /which crate will end up on top of each
|
||||
stack/; in this example, the top crates are =C= in stack 1, =M= in stack
|
||||
2, and =Z= in stack 3, so you should combine these together and give the
|
||||
Elves the message =CMZ=.
|
||||
|
||||
/After the rearrangement procedure completes, what crate ends up on top
|
||||
of each stack?/
|
||||
|
||||
Your puzzle answer was =VQZNJMWTR=.
|
||||
|
||||
** --- Part Two ---
|
||||
As you watch the crane operator expertly rearrange the crates, you
|
||||
notice the process isn't following your prediction.
|
||||
|
||||
Some mud was covering the writing on the side of the crane, and you
|
||||
quickly wipe it away. The crane isn't a CrateMover 9000 - it's a
|
||||
/CrateMover 9001/.
|
||||
|
||||
The CrateMover 9001 is notable for many new and exciting features: air
|
||||
conditioning, leather seats, an extra cup holder, and /the ability to
|
||||
pick up and move multiple crates at once/.
|
||||
|
||||
Again considering the example above, the crates begin in the same
|
||||
configuration:
|
||||
|
||||
#+begin_example
|
||||
[D]
|
||||
[N] [C]
|
||||
[Z] [M] [P]
|
||||
1 2 3
|
||||
#+end_example
|
||||
|
||||
Moving a single crate from stack 2 to stack 1 behaves the same as
|
||||
before:
|
||||
|
||||
#+begin_example
|
||||
[D]
|
||||
[N] [C]
|
||||
[Z] [M] [P]
|
||||
1 2 3
|
||||
#+end_example
|
||||
|
||||
However, the action of moving three crates from stack 1 to stack 3 means
|
||||
that those three moved crates /stay in the same order/, resulting in
|
||||
this new configuration:
|
||||
|
||||
#+begin_example
|
||||
[D]
|
||||
[N]
|
||||
[C] [Z]
|
||||
[M] [P]
|
||||
1 2 3
|
||||
#+end_example
|
||||
|
||||
Next, as both crates are moved from stack 2 to stack 1, they /retain
|
||||
their order/ as well:
|
||||
|
||||
#+begin_example
|
||||
[D]
|
||||
[N]
|
||||
[C] [Z]
|
||||
[M] [P]
|
||||
1 2 3
|
||||
#+end_example
|
||||
|
||||
Finally, a single crate is still moved from stack 1 to stack 2, but now
|
||||
it's crate =C= that gets moved:
|
||||
|
||||
#+begin_example
|
||||
[D]
|
||||
[N]
|
||||
[Z]
|
||||
[M] [C] [P]
|
||||
1 2 3
|
||||
#+end_example
|
||||
|
||||
In this example, the CrateMover 9001 has put the crates in a totally
|
||||
different order: =MCD=.
|
||||
|
||||
Before the rearrangement process finishes, update your simulation so
|
||||
that the Elves know where they should stand to be ready to unload the
|
||||
final supplies. /After the rearrangement procedure completes, what crate
|
||||
ends up on top of each stack?/
|
||||
|
||||
Your puzzle answer was =NLCDCLVMQ=.
|
||||
|
||||
Both parts of this puzzle are complete! They provide two gold stars: **
|
||||
115
2022/day05/aoc-c.c
Normal file
115
2022/day05/aoc-c.c
Normal file
@@ -0,0 +1,115 @@
|
||||
/* aoc-c.c: Advent of Code 2022, day 5
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "br.h"
|
||||
#include "list.h"
|
||||
#include "pool.h"
|
||||
#include "aoc.h"
|
||||
|
||||
#define MAXSTACKS 128
|
||||
|
||||
typedef struct crate {
|
||||
int code;
|
||||
struct list_head list;
|
||||
} crate_t;
|
||||
|
||||
static pool_t *pool_crates;
|
||||
|
||||
static void move_stack(struct list_head *stacks, int from, int to, int nb)
|
||||
{
|
||||
for (int i = 0; i < nb; ++i)
|
||||
/* Attention !! we should test if &stacks[from - 1] is not empty here */
|
||||
list_move(stacks[from - 1].next, &stacks[to - 1]);
|
||||
}
|
||||
|
||||
static void move_bulk(struct list_head *stacks, int from, int to, int nb)
|
||||
{
|
||||
struct list_head *tail;
|
||||
LIST_HEAD(bulk);
|
||||
|
||||
int count = 1;
|
||||
list_for_each(tail, &stacks[from - 1])
|
||||
if (count++ == nb)
|
||||
break;
|
||||
list_cut_position(&bulk, &stacks[from - 1], tail);
|
||||
list_splice(&bulk, &stacks[to - 1]);
|
||||
}
|
||||
|
||||
static void parse(struct list_head *stacks, int *nstacks, int part)
|
||||
{
|
||||
size_t alloc = 0;
|
||||
char *buf = NULL;
|
||||
ssize_t buflen;
|
||||
int state = 0;
|
||||
|
||||
while ((buflen = getline(&buf, &alloc, stdin)) > 0) {
|
||||
buf[--buflen] = 0;
|
||||
|
||||
if (!buflen || buf[1] == '1') {
|
||||
state = 1;
|
||||
continue;
|
||||
}
|
||||
if (!state) { /* stacks */
|
||||
int stack = 0, pos, code;
|
||||
|
||||
for(pos = 1; pos < buflen; pos += 4, stack++) {
|
||||
if ((code = buf[pos]) != ' ') {
|
||||
crate_t *new = pool_get(pool_crates);
|
||||
new->code = code;
|
||||
list_add_tail(&new->list, stacks + stack);
|
||||
if (stack == *nstacks)
|
||||
++*nstacks;
|
||||
}
|
||||
}
|
||||
} else { /* moves */
|
||||
int nb, from, to;
|
||||
if ((sscanf(buf, "%*s%d%*s%d%*s%d", &nb, &from, &to)) == 3) {
|
||||
if (part == 1)
|
||||
move_stack(stacks, from, to, nb);
|
||||
else
|
||||
move_bulk(stacks, from, to, nb);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static char *build_res(struct list_head *stacks, int nstacks, char *res)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < nstacks; ++ i) {
|
||||
crate_t *cur = list_first_entry(&stacks[i], crate_t, list);
|
||||
res[i] = cur->code;
|
||||
}
|
||||
res[i] = 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
int main(int ac, char **av)
|
||||
{
|
||||
char res[MAXSTACKS + 1];
|
||||
int part = parseargs(ac, av);
|
||||
struct list_head stacks[MAXSTACKS];
|
||||
int nstacks = 0;
|
||||
|
||||
for (ulong ul = 0; ul < ARRAY_SIZE(stacks); ++ul)
|
||||
INIT_LIST_HEAD(&stacks[ul]);
|
||||
pool_crates = pool_create("crates", 64, sizeof (crate_t));
|
||||
|
||||
parse(stacks, &nstacks, part);
|
||||
printf("%s: res=%s\n", *av, build_res(stacks, nstacks, res));
|
||||
pool_destroy(pool_crates);
|
||||
exit(0);
|
||||
}
|
||||
62
2022/day05/aoc.bash
Executable file
62
2022/day05/aoc.bash
Executable file
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# aoc.bash: Advent of Code 2022, day 5
|
||||
#
|
||||
# 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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
|
||||
. common.bash
|
||||
|
||||
declare -a stacks=() rules=()
|
||||
|
||||
parse() {
|
||||
local -i _queue _state=1
|
||||
local _input
|
||||
local -a _parse
|
||||
|
||||
while IFS= read -r _input; do
|
||||
if [[ -z ${_input} || ${_input:1:1} == "1" ]]; then
|
||||
_state=2
|
||||
continue
|
||||
fi
|
||||
if (( _state == 1 )); then # stacks description
|
||||
for (( i = 0, _queue = 0; i < ${#_input}; i += 4, _queue++ )); do
|
||||
sub=${_input:i:4}
|
||||
[[ $sub == " "* ]] || stacks[$_queue]+="${sub:1:1}"
|
||||
done
|
||||
else # moves description
|
||||
rules+=( "${_input//[a-z]/}" )
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
solve() {
|
||||
local -i _part="$1" _i=0 _j=0 _nb _from _to
|
||||
local -a _rule
|
||||
|
||||
for ((; _i < ${#rules[@]}; ++_i )); do
|
||||
read -ra _rule <<< "${rules[$_i]}"
|
||||
(( _nb = _rule[0], _from = _rule[1] - 1, _to = _rule[2] - 1 ))
|
||||
if ((_part == 1)); then
|
||||
# move elements one by one
|
||||
for ((_j = 0; _j < _nb; ++_j)); do
|
||||
stacks[$_to]="${stacks[$_from]:0:1}${stacks[$_to]}"
|
||||
stacks[$_from]=${stacks[$_from]:1}
|
||||
done
|
||||
else
|
||||
# move elements by block
|
||||
stacks[$_to]="${stacks[$_from]:0:_nb}${stacks[$_to]}"
|
||||
stacks[$_from]=${stacks[$_from]:_nb}
|
||||
fi
|
||||
done
|
||||
printf -v res "%c" "${stacks[@]}"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
exit 0
|
||||
17
2022/day05/aoc.h
Normal file
17
2022/day05/aoc.h
Normal file
@@ -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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
#ifndef _AOC_H_
|
||||
#define _AOC_H_
|
||||
|
||||
extern int parseargs(int ac, char**av);
|
||||
|
||||
#endif /* _AOC_H_ */
|
||||
68
2022/day05/common.bash
Executable file
68
2022/day05/common.bash
Executable file
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# common.bash: Advent of Code 2022, common bash 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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
|
||||
# shellcheck disable=2034
|
||||
export cmdname=${0##*/}
|
||||
export debug=0
|
||||
export res
|
||||
export LANG=C
|
||||
|
||||
shopt -s extglob
|
||||
set -o noglob
|
||||
|
||||
usage() {
|
||||
printf "usage: %s [-d DEBUG] [-p PART]\n" "$cmdname"
|
||||
exit 1
|
||||
}
|
||||
|
||||
checkargs() {
|
||||
local part=1
|
||||
while getopts p:d: todo; do
|
||||
case "$todo" in
|
||||
d)
|
||||
if [[ "$OPTARG" =~ ^[[:digit:]+]$ ]]; then
|
||||
debug="$OPTARG"
|
||||
else
|
||||
printf "%s: illegal [%s] debug level.\n" "$CMD" "$OPTARG"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
p)
|
||||
if [[ "$OPTARG" =~ ^[12]$ ]]; then
|
||||
part="$OPTARG"
|
||||
else
|
||||
printf "%s: illegal [%s] part.\n" "$CMD" "$OPTARG"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
# Now check remaining argument (backup directory)
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
(( $# > 1 )) && usage
|
||||
return "$part"
|
||||
}
|
||||
|
||||
main() {
|
||||
local -i part
|
||||
|
||||
checkargs "$@"
|
||||
part=$?
|
||||
parse "$part"
|
||||
solve "$part"
|
||||
printf "%s: res=%s\n" "$cmdname" "$res"
|
||||
}
|
||||
49
2022/day05/common.c
Normal file
49
2022/day05/common.c
Normal file
@@ -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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
9
2022/day05/input/example.txt
Normal file
9
2022/day05/input/example.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
[D]
|
||||
[N] [C]
|
||||
[Z] [M] [P]
|
||||
1 2 3
|
||||
|
||||
move 1 from 2 to 1
|
||||
move 3 from 1 to 3
|
||||
move 2 from 2 to 1
|
||||
move 1 from 1 to 2
|
||||
511
2022/day05/input/input.txt
Normal file
511
2022/day05/input/input.txt
Normal file
@@ -0,0 +1,511 @@
|
||||
[L] [M] [M]
|
||||
[D] [R] [Z] [C] [L]
|
||||
[C] [S] [T] [G] [V] [M]
|
||||
[R] [L] [Q] [B] [B] [D] [F]
|
||||
[H] [B] [G] [D] [Q] [Z] [T] [J]
|
||||
[M] [J] [H] [M] [P] [S] [V] [L] [N]
|
||||
[P] [C] [N] [T] [S] [F] [R] [G] [Q]
|
||||
[Z] [P] [S] [F] [F] [T] [N] [P] [W]
|
||||
1 2 3 4 5 6 7 8 9
|
||||
|
||||
move 7 from 3 to 9
|
||||
move 5 from 8 to 9
|
||||
move 3 from 9 to 5
|
||||
move 6 from 9 to 2
|
||||
move 9 from 9 to 3
|
||||
move 3 from 7 to 3
|
||||
move 8 from 2 to 3
|
||||
move 9 from 3 to 1
|
||||
move 11 from 3 to 8
|
||||
move 5 from 6 to 9
|
||||
move 1 from 6 to 3
|
||||
move 1 from 2 to 7
|
||||
move 1 from 4 to 8
|
||||
move 1 from 3 to 9
|
||||
move 4 from 4 to 3
|
||||
move 6 from 8 to 3
|
||||
move 2 from 8 to 2
|
||||
move 4 from 9 to 3
|
||||
move 3 from 2 to 5
|
||||
move 2 from 5 to 4
|
||||
move 5 from 3 to 4
|
||||
move 11 from 1 to 4
|
||||
move 1 from 7 to 6
|
||||
move 1 from 3 to 5
|
||||
move 2 from 1 to 9
|
||||
move 1 from 1 to 4
|
||||
move 7 from 5 to 8
|
||||
move 21 from 4 to 6
|
||||
move 6 from 6 to 2
|
||||
move 6 from 8 to 9
|
||||
move 5 from 8 to 5
|
||||
move 2 from 2 to 7
|
||||
move 4 from 3 to 7
|
||||
move 1 from 2 to 6
|
||||
move 1 from 2 to 5
|
||||
move 2 from 2 to 7
|
||||
move 4 from 3 to 7
|
||||
move 1 from 4 to 6
|
||||
move 9 from 5 to 3
|
||||
move 7 from 3 to 4
|
||||
move 7 from 7 to 3
|
||||
move 7 from 4 to 1
|
||||
move 8 from 3 to 5
|
||||
move 1 from 3 to 5
|
||||
move 3 from 8 to 2
|
||||
move 2 from 2 to 9
|
||||
move 13 from 9 to 4
|
||||
move 5 from 5 to 3
|
||||
move 4 from 7 to 6
|
||||
move 1 from 7 to 4
|
||||
move 2 from 4 to 2
|
||||
move 3 from 3 to 4
|
||||
move 2 from 5 to 2
|
||||
move 6 from 1 to 7
|
||||
move 1 from 2 to 8
|
||||
move 1 from 3 to 8
|
||||
move 1 from 1 to 6
|
||||
move 1 from 3 to 4
|
||||
move 1 from 2 to 6
|
||||
move 24 from 6 to 1
|
||||
move 3 from 2 to 3
|
||||
move 3 from 3 to 5
|
||||
move 2 from 8 to 6
|
||||
move 2 from 5 to 4
|
||||
move 3 from 5 to 1
|
||||
move 7 from 4 to 8
|
||||
move 3 from 8 to 9
|
||||
move 2 from 9 to 5
|
||||
move 2 from 6 to 3
|
||||
move 1 from 9 to 8
|
||||
move 5 from 7 to 5
|
||||
move 2 from 3 to 1
|
||||
move 1 from 7 to 1
|
||||
move 7 from 4 to 7
|
||||
move 2 from 4 to 8
|
||||
move 6 from 8 to 6
|
||||
move 3 from 6 to 9
|
||||
move 10 from 5 to 1
|
||||
move 7 from 7 to 1
|
||||
move 1 from 4 to 9
|
||||
move 1 from 6 to 3
|
||||
move 2 from 9 to 7
|
||||
move 1 from 4 to 2
|
||||
move 1 from 9 to 5
|
||||
move 1 from 8 to 5
|
||||
move 39 from 1 to 8
|
||||
move 1 from 2 to 5
|
||||
move 2 from 6 to 9
|
||||
move 3 from 9 to 5
|
||||
move 3 from 1 to 6
|
||||
move 1 from 7 to 2
|
||||
move 1 from 3 to 2
|
||||
move 2 from 6 to 2
|
||||
move 3 from 2 to 3
|
||||
move 1 from 6 to 2
|
||||
move 1 from 1 to 8
|
||||
move 3 from 1 to 2
|
||||
move 3 from 2 to 4
|
||||
move 2 from 4 to 5
|
||||
move 2 from 3 to 8
|
||||
move 8 from 5 to 2
|
||||
move 8 from 8 to 2
|
||||
move 15 from 2 to 7
|
||||
move 1 from 1 to 5
|
||||
move 25 from 8 to 7
|
||||
move 2 from 2 to 4
|
||||
move 2 from 4 to 3
|
||||
move 1 from 8 to 4
|
||||
move 2 from 4 to 6
|
||||
move 1 from 2 to 1
|
||||
move 26 from 7 to 2
|
||||
move 15 from 2 to 1
|
||||
move 7 from 8 to 9
|
||||
move 10 from 1 to 6
|
||||
move 10 from 7 to 2
|
||||
move 1 from 8 to 1
|
||||
move 5 from 9 to 8
|
||||
move 1 from 8 to 9
|
||||
move 2 from 6 to 9
|
||||
move 3 from 7 to 1
|
||||
move 1 from 7 to 1
|
||||
move 5 from 9 to 2
|
||||
move 1 from 3 to 1
|
||||
move 9 from 6 to 3
|
||||
move 1 from 6 to 1
|
||||
move 4 from 2 to 4
|
||||
move 3 from 4 to 8
|
||||
move 1 from 4 to 1
|
||||
move 9 from 3 to 1
|
||||
move 1 from 7 to 6
|
||||
move 9 from 2 to 5
|
||||
move 14 from 1 to 6
|
||||
move 1 from 3 to 8
|
||||
move 5 from 2 to 6
|
||||
move 8 from 1 to 8
|
||||
move 6 from 6 to 8
|
||||
move 14 from 6 to 7
|
||||
move 1 from 1 to 7
|
||||
move 10 from 5 to 4
|
||||
move 11 from 8 to 5
|
||||
move 15 from 7 to 1
|
||||
move 4 from 5 to 6
|
||||
move 4 from 8 to 9
|
||||
move 6 from 5 to 3
|
||||
move 1 from 6 to 9
|
||||
move 1 from 1 to 6
|
||||
move 1 from 5 to 8
|
||||
move 2 from 6 to 2
|
||||
move 6 from 1 to 5
|
||||
move 1 from 5 to 8
|
||||
move 2 from 5 to 4
|
||||
move 9 from 2 to 9
|
||||
move 13 from 9 to 8
|
||||
move 1 from 2 to 1
|
||||
move 1 from 4 to 8
|
||||
move 3 from 3 to 1
|
||||
move 2 from 4 to 5
|
||||
move 2 from 1 to 5
|
||||
move 1 from 9 to 3
|
||||
move 17 from 8 to 1
|
||||
move 3 from 3 to 2
|
||||
move 4 from 5 to 1
|
||||
move 2 from 2 to 4
|
||||
move 1 from 6 to 1
|
||||
move 1 from 2 to 8
|
||||
move 4 from 4 to 6
|
||||
move 1 from 5 to 9
|
||||
move 5 from 6 to 8
|
||||
move 1 from 5 to 4
|
||||
move 1 from 5 to 6
|
||||
move 3 from 8 to 6
|
||||
move 8 from 4 to 5
|
||||
move 32 from 1 to 7
|
||||
move 11 from 7 to 6
|
||||
move 8 from 5 to 3
|
||||
move 3 from 8 to 7
|
||||
move 6 from 3 to 9
|
||||
move 4 from 3 to 8
|
||||
move 5 from 8 to 2
|
||||
move 1 from 8 to 5
|
||||
move 11 from 6 to 3
|
||||
move 1 from 5 to 2
|
||||
move 2 from 8 to 6
|
||||
move 12 from 7 to 8
|
||||
move 2 from 6 to 2
|
||||
move 2 from 6 to 4
|
||||
move 5 from 2 to 5
|
||||
move 8 from 7 to 2
|
||||
move 2 from 7 to 1
|
||||
move 2 from 7 to 6
|
||||
move 5 from 5 to 4
|
||||
move 5 from 4 to 7
|
||||
move 5 from 8 to 2
|
||||
move 2 from 9 to 7
|
||||
move 5 from 8 to 4
|
||||
move 2 from 7 to 3
|
||||
move 2 from 9 to 3
|
||||
move 3 from 7 to 9
|
||||
move 1 from 1 to 8
|
||||
move 2 from 6 to 1
|
||||
move 2 from 9 to 8
|
||||
move 1 from 7 to 8
|
||||
move 1 from 2 to 5
|
||||
move 1 from 7 to 9
|
||||
move 7 from 4 to 3
|
||||
move 3 from 3 to 6
|
||||
move 5 from 8 to 6
|
||||
move 3 from 9 to 5
|
||||
move 16 from 3 to 1
|
||||
move 2 from 9 to 1
|
||||
move 7 from 1 to 8
|
||||
move 1 from 1 to 2
|
||||
move 5 from 8 to 2
|
||||
move 12 from 1 to 4
|
||||
move 1 from 3 to 5
|
||||
move 1 from 2 to 9
|
||||
move 1 from 9 to 4
|
||||
move 4 from 6 to 5
|
||||
move 5 from 6 to 1
|
||||
move 1 from 6 to 5
|
||||
move 1 from 1 to 4
|
||||
move 1 from 4 to 7
|
||||
move 1 from 3 to 7
|
||||
move 9 from 4 to 6
|
||||
move 2 from 7 to 8
|
||||
move 1 from 3 to 4
|
||||
move 2 from 8 to 9
|
||||
move 4 from 8 to 4
|
||||
move 4 from 2 to 8
|
||||
move 2 from 9 to 7
|
||||
move 2 from 7 to 8
|
||||
move 10 from 2 to 4
|
||||
move 1 from 2 to 1
|
||||
move 5 from 4 to 7
|
||||
move 1 from 1 to 3
|
||||
move 3 from 8 to 7
|
||||
move 6 from 7 to 2
|
||||
move 3 from 2 to 7
|
||||
move 1 from 6 to 7
|
||||
move 5 from 5 to 8
|
||||
move 4 from 1 to 3
|
||||
move 4 from 3 to 1
|
||||
move 8 from 4 to 2
|
||||
move 1 from 3 to 2
|
||||
move 2 from 7 to 2
|
||||
move 2 from 6 to 3
|
||||
move 4 from 7 to 2
|
||||
move 4 from 5 to 7
|
||||
move 14 from 2 to 7
|
||||
move 3 from 2 to 1
|
||||
move 3 from 8 to 2
|
||||
move 1 from 5 to 7
|
||||
move 6 from 2 to 4
|
||||
move 2 from 2 to 7
|
||||
move 2 from 3 to 6
|
||||
move 6 from 8 to 2
|
||||
move 4 from 6 to 4
|
||||
move 2 from 6 to 9
|
||||
move 4 from 4 to 2
|
||||
move 2 from 4 to 8
|
||||
move 10 from 7 to 2
|
||||
move 18 from 2 to 6
|
||||
move 2 from 2 to 6
|
||||
move 2 from 9 to 2
|
||||
move 2 from 8 to 5
|
||||
move 1 from 2 to 9
|
||||
move 1 from 2 to 9
|
||||
move 1 from 5 to 7
|
||||
move 1 from 2 to 6
|
||||
move 2 from 9 to 2
|
||||
move 6 from 7 to 3
|
||||
move 7 from 6 to 8
|
||||
move 5 from 7 to 2
|
||||
move 1 from 7 to 4
|
||||
move 1 from 5 to 7
|
||||
move 4 from 8 to 7
|
||||
move 5 from 2 to 3
|
||||
move 1 from 7 to 5
|
||||
move 2 from 2 to 8
|
||||
move 9 from 4 to 3
|
||||
move 13 from 6 to 8
|
||||
move 10 from 3 to 1
|
||||
move 1 from 5 to 2
|
||||
move 3 from 6 to 8
|
||||
move 5 from 1 to 2
|
||||
move 1 from 1 to 8
|
||||
move 2 from 4 to 3
|
||||
move 17 from 8 to 6
|
||||
move 5 from 6 to 3
|
||||
move 3 from 1 to 2
|
||||
move 9 from 6 to 5
|
||||
move 2 from 6 to 8
|
||||
move 5 from 5 to 9
|
||||
move 3 from 9 to 8
|
||||
move 3 from 1 to 3
|
||||
move 3 from 7 to 5
|
||||
move 6 from 5 to 8
|
||||
move 7 from 2 to 4
|
||||
move 1 from 6 to 3
|
||||
move 1 from 1 to 5
|
||||
move 4 from 4 to 5
|
||||
move 2 from 2 to 9
|
||||
move 3 from 1 to 3
|
||||
move 4 from 5 to 8
|
||||
move 1 from 4 to 5
|
||||
move 6 from 8 to 7
|
||||
move 1 from 5 to 2
|
||||
move 4 from 9 to 2
|
||||
move 2 from 5 to 9
|
||||
move 2 from 1 to 8
|
||||
move 2 from 4 to 9
|
||||
move 6 from 7 to 5
|
||||
move 3 from 5 to 2
|
||||
move 3 from 2 to 5
|
||||
move 10 from 8 to 3
|
||||
move 2 from 8 to 5
|
||||
move 3 from 2 to 5
|
||||
move 6 from 5 to 1
|
||||
move 4 from 5 to 6
|
||||
move 1 from 7 to 5
|
||||
move 23 from 3 to 7
|
||||
move 2 from 5 to 9
|
||||
move 2 from 1 to 5
|
||||
move 2 from 6 to 3
|
||||
move 6 from 3 to 1
|
||||
move 1 from 1 to 7
|
||||
move 4 from 3 to 1
|
||||
move 1 from 8 to 5
|
||||
move 2 from 9 to 2
|
||||
move 3 from 3 to 8
|
||||
move 2 from 6 to 8
|
||||
move 12 from 1 to 3
|
||||
move 1 from 9 to 7
|
||||
move 3 from 5 to 9
|
||||
move 9 from 3 to 8
|
||||
move 1 from 1 to 7
|
||||
move 1 from 9 to 4
|
||||
move 3 from 3 to 6
|
||||
move 3 from 2 to 1
|
||||
move 3 from 8 to 6
|
||||
move 1 from 4 to 2
|
||||
move 1 from 2 to 9
|
||||
move 1 from 2 to 7
|
||||
move 20 from 7 to 5
|
||||
move 3 from 7 to 3
|
||||
move 3 from 1 to 3
|
||||
move 5 from 8 to 1
|
||||
move 5 from 1 to 5
|
||||
move 4 from 5 to 2
|
||||
move 3 from 2 to 6
|
||||
move 3 from 8 to 7
|
||||
move 1 from 2 to 6
|
||||
move 2 from 8 to 6
|
||||
move 2 from 7 to 5
|
||||
move 2 from 3 to 6
|
||||
move 12 from 5 to 1
|
||||
move 6 from 5 to 7
|
||||
move 12 from 6 to 8
|
||||
move 4 from 9 to 3
|
||||
move 4 from 5 to 8
|
||||
move 3 from 1 to 5
|
||||
move 4 from 7 to 4
|
||||
move 3 from 5 to 9
|
||||
move 7 from 1 to 6
|
||||
move 1 from 1 to 3
|
||||
move 6 from 7 to 6
|
||||
move 1 from 1 to 3
|
||||
move 10 from 3 to 6
|
||||
move 10 from 6 to 2
|
||||
move 2 from 9 to 5
|
||||
move 4 from 6 to 5
|
||||
move 9 from 6 to 1
|
||||
move 16 from 8 to 7
|
||||
move 3 from 8 to 7
|
||||
move 1 from 8 to 1
|
||||
move 7 from 2 to 1
|
||||
move 1 from 5 to 9
|
||||
move 1 from 6 to 1
|
||||
move 2 from 2 to 1
|
||||
move 3 from 1 to 4
|
||||
move 1 from 6 to 8
|
||||
move 7 from 4 to 1
|
||||
move 1 from 8 to 2
|
||||
move 22 from 1 to 8
|
||||
move 18 from 7 to 9
|
||||
move 6 from 5 to 2
|
||||
move 2 from 2 to 7
|
||||
move 2 from 1 to 5
|
||||
move 4 from 7 to 6
|
||||
move 1 from 5 to 6
|
||||
move 2 from 8 to 2
|
||||
move 3 from 2 to 6
|
||||
move 1 from 5 to 6
|
||||
move 15 from 9 to 6
|
||||
move 6 from 9 to 5
|
||||
move 1 from 9 to 8
|
||||
move 1 from 2 to 9
|
||||
move 5 from 5 to 9
|
||||
move 9 from 8 to 6
|
||||
move 3 from 2 to 7
|
||||
move 12 from 8 to 9
|
||||
move 1 from 7 to 5
|
||||
move 1 from 5 to 7
|
||||
move 3 from 7 to 1
|
||||
move 17 from 6 to 3
|
||||
move 1 from 2 to 6
|
||||
move 2 from 1 to 4
|
||||
move 16 from 6 to 4
|
||||
move 7 from 4 to 6
|
||||
move 1 from 5 to 7
|
||||
move 8 from 4 to 5
|
||||
move 9 from 9 to 8
|
||||
move 16 from 3 to 7
|
||||
move 1 from 1 to 5
|
||||
move 3 from 5 to 1
|
||||
move 5 from 6 to 2
|
||||
move 3 from 1 to 7
|
||||
move 3 from 6 to 7
|
||||
move 3 from 9 to 3
|
||||
move 5 from 8 to 5
|
||||
move 11 from 5 to 7
|
||||
move 2 from 3 to 7
|
||||
move 1 from 2 to 1
|
||||
move 1 from 3 to 6
|
||||
move 17 from 7 to 9
|
||||
move 1 from 3 to 2
|
||||
move 3 from 4 to 6
|
||||
move 1 from 1 to 2
|
||||
move 1 from 6 to 4
|
||||
move 14 from 7 to 6
|
||||
move 15 from 9 to 6
|
||||
move 4 from 8 to 7
|
||||
move 1 from 4 to 7
|
||||
move 7 from 9 to 5
|
||||
move 5 from 2 to 9
|
||||
move 7 from 5 to 1
|
||||
move 3 from 1 to 7
|
||||
move 29 from 6 to 4
|
||||
move 1 from 2 to 4
|
||||
move 18 from 4 to 2
|
||||
move 3 from 1 to 4
|
||||
move 1 from 1 to 7
|
||||
move 18 from 2 to 4
|
||||
move 3 from 6 to 5
|
||||
move 15 from 4 to 1
|
||||
move 1 from 5 to 1
|
||||
move 1 from 5 to 4
|
||||
move 9 from 4 to 1
|
||||
move 5 from 1 to 3
|
||||
move 9 from 1 to 5
|
||||
move 2 from 4 to 3
|
||||
move 5 from 5 to 6
|
||||
move 3 from 7 to 9
|
||||
move 7 from 7 to 5
|
||||
move 6 from 4 to 6
|
||||
move 2 from 3 to 7
|
||||
move 6 from 5 to 8
|
||||
move 2 from 8 to 4
|
||||
move 1 from 8 to 9
|
||||
move 9 from 6 to 2
|
||||
move 3 from 9 to 3
|
||||
move 1 from 2 to 1
|
||||
move 6 from 7 to 4
|
||||
move 2 from 2 to 8
|
||||
move 3 from 9 to 5
|
||||
move 5 from 4 to 8
|
||||
move 1 from 6 to 9
|
||||
move 1 from 3 to 1
|
||||
move 1 from 3 to 4
|
||||
move 1 from 6 to 5
|
||||
move 1 from 9 to 3
|
||||
move 10 from 8 to 7
|
||||
move 3 from 9 to 2
|
||||
move 7 from 2 to 4
|
||||
move 6 from 5 to 7
|
||||
move 4 from 5 to 8
|
||||
move 7 from 3 to 2
|
||||
move 3 from 7 to 1
|
||||
move 9 from 1 to 5
|
||||
move 5 from 7 to 9
|
||||
move 7 from 1 to 4
|
||||
move 11 from 4 to 2
|
||||
move 4 from 8 to 3
|
||||
move 5 from 4 to 7
|
||||
move 4 from 4 to 1
|
||||
move 1 from 3 to 6
|
||||
move 12 from 7 to 4
|
||||
move 2 from 1 to 8
|
||||
move 5 from 9 to 7
|
||||
move 7 from 5 to 6
|
||||
move 1 from 1 to 4
|
||||
move 1 from 9 to 8
|
||||
move 1 from 4 to 7
|
||||
move 1 from 8 to 9
|
||||
move 5 from 7 to 9
|
||||
move 2 from 7 to 5
|
||||
move 2 from 6 to 3
|
||||
move 5 from 2 to 7
|
||||
move 1 from 7 to 8
|
||||
move 1 from 1 to 6
|
||||
move 3 from 5 to 1
|
||||
111
2022/day06/Makefile
Normal file
111
2022/day06/Makefile
Normal file
@@ -0,0 +1,111 @@
|
||||
# AOC daily Makefile - GNU make only.
|
||||
#
|
||||
# Copyright (C) 2021-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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
#
|
||||
|
||||
INPUT := input/input.txt
|
||||
SHELL := /bin/bash
|
||||
|
||||
CC := gcc
|
||||
BEAR := bear
|
||||
CCLSFILE:= compile_commands.json
|
||||
|
||||
LIB := aoc_$(shell uname -m)
|
||||
INCDIR := ../include
|
||||
LIBDIR := ../lib
|
||||
LDFLAGS := -L$(LIBDIR)
|
||||
#LDLIB := -l$(LIB) -lm
|
||||
LDLIB := -l$(LIB)
|
||||
|
||||
export LD_LIBRARY_PATH = $(LIBDIR)
|
||||
|
||||
CFLAGS += -std=gnu11
|
||||
CFLAGS += -O2
|
||||
CFLAGS += -g
|
||||
# for gprof
|
||||
# CFLAGS += -pg
|
||||
CFLAGS += -Wall
|
||||
CFLAGS += -Wextra
|
||||
CFLAGS += -march=native
|
||||
# Next one may be useful for valgrind (some invalid instructions)
|
||||
# CFLAGS += -mno-tbm
|
||||
CFLAGS += -Wmissing-declarations
|
||||
CFLAGS += -Wno-unused-result
|
||||
|
||||
CFLAGS += -DDEBUG_DEBUG # activate general debug (debug.c)
|
||||
CFLAGS += -DDEBUG_POOL # memory pools management
|
||||
|
||||
VALGRIND := valgrind
|
||||
VALGRINDFLAGS := --leak-check=full --show-leak-kinds=all --track-origins=yes \
|
||||
--sigill-diagnostics=yes --quiet --show-error-list=yes
|
||||
|
||||
|
||||
TIME := \time -f "\ttime: %E real, %U user, %S sys\n\tcontext-switch:\t%c+%w, page-faults: %F+%R\n"
|
||||
export PATH := .:$(PATH)
|
||||
|
||||
.PHONY: clean all compile assembly memcheck memcheck1 memcheck2 part1 part2 ccls bear org
|
||||
|
||||
all: README.org ccls part1 part2
|
||||
|
||||
memcheck: memcheck1 memcheck2
|
||||
|
||||
memcheck1: aoc-c
|
||||
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 1 < $(INPUT)
|
||||
|
||||
memcheck2: aoc-c
|
||||
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 2 < $(INPUT)
|
||||
@#@valgrind -s --track-origins=yes aoc-c -p 2 < $(INPUT)
|
||||
|
||||
compile: aoc-c
|
||||
|
||||
cpp: aoc-c.i
|
||||
|
||||
assembly: aoc-c.s
|
||||
|
||||
part1: aoc-c
|
||||
@$(TIME) aoc.bash -p 1 < $(INPUT) 2>&1
|
||||
@$(TIME) aoc-c -p 1 < $(INPUT)
|
||||
|
||||
part2: aoc-c
|
||||
@$(TIME) aoc.bash -p 2 < $(INPUT) 2>&1
|
||||
@$(TIME) aoc-c -p 2 < $(INPUT)
|
||||
|
||||
ccls: $(CCLSFILE)
|
||||
|
||||
clean:
|
||||
@rm -f aoc-c core* vgcore* gmon.out aoc-c.s aoc-c.i README.html compile_commands.json
|
||||
|
||||
aoc-c: aoc-c.c common.c
|
||||
@echo compiling $<
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -I $(INCDIR) $^ $(LDLIB) -o $@
|
||||
|
||||
# generate pre-processed file (.i) and assembler (.s)
|
||||
%.i: %.c
|
||||
@echo generating $@
|
||||
@$(CC) -E $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||
|
||||
%.s: %.c
|
||||
@echo generating $@
|
||||
@$(CC) -S -fverbose-asm $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||
|
||||
# generate README.org from README.html (must cleanup !)
|
||||
org: README.org
|
||||
|
||||
%.org: %.html
|
||||
@echo generating $@. Cleanup before commit !
|
||||
@pandoc $< -o $@
|
||||
|
||||
# generate compile_commands.json
|
||||
$(CCLSFILE): aoc-c.c Makefile
|
||||
$(BEAR) -- make clean compile
|
||||
|
||||
bear: clean
|
||||
@touch .ccls-root
|
||||
@$(BEAR) -- make compile
|
||||
85
2022/day06/README.org
Normal file
85
2022/day06/README.org
Normal file
@@ -0,0 +1,85 @@
|
||||
** --- Day 6: Tuning Trouble ---
|
||||
The preparations are finally complete; you and the Elves leave camp on
|
||||
foot and begin to make your way toward the /star/ fruit grove.
|
||||
|
||||
As you move through the dense undergrowth, one of the Elves gives you a
|
||||
handheld /device/. He says that it has many fancy features, but the most
|
||||
important one to set up right now is the /communication system/.
|
||||
|
||||
However, because he's heard you have [[/2016/day/6][significant]]
|
||||
[[/2016/day/25][experience]] [[/2019/day/7][dealing]]
|
||||
[[/2019/day/9][with]] [[/2019/day/16][signal-based]]
|
||||
[[/2021/day/25][systems]], he convinced the other Elves that it would be
|
||||
okay to give you their one malfunctioning device - surely you'll have no
|
||||
problem fixing it.
|
||||
|
||||
As if inspired by comedic timing, the device emits a few colorful
|
||||
sparks.
|
||||
|
||||
To be able to communicate with the Elves, the device needs to /lock on
|
||||
to their signal/. The signal is a series of seemingly-random characters
|
||||
that the device receives one at a time.
|
||||
|
||||
To fix the communication system, you need to add a subroutine to the
|
||||
device that detects a /start-of-packet marker/ in the datastream. In the
|
||||
protocol being used by the Elves, the start of a packet is indicated by
|
||||
a sequence of /four characters that are all different/.
|
||||
|
||||
The device will send your subroutine a datastream buffer (your puzzle
|
||||
input); your subroutine needs to identify the first position where the
|
||||
four most recently received characters were all different. Specifically,
|
||||
it needs to report the number of characters from the beginning of the
|
||||
buffer to the end of the first such four-character marker.
|
||||
|
||||
For example, suppose you receive the following datastream buffer:
|
||||
|
||||
#+begin_example
|
||||
mjqjpqmgbljsphdztnvjfqwrcgsmlb
|
||||
#+end_example
|
||||
|
||||
After the first three characters (=mjq=) have been received, there
|
||||
haven't been enough characters received yet to find the marker. The
|
||||
first time a marker could occur is after the fourth character is
|
||||
received, making the most recent four characters =mjqj=. Because =j= is
|
||||
repeated, this isn't a marker.
|
||||
|
||||
The first time a marker appears is after the /seventh/ character
|
||||
arrives. Once it does, the last four characters received are =jpqm=,
|
||||
which are all different. In this case, your subroutine should report the
|
||||
value =7=, because the first start-of-packet marker is complete after 7
|
||||
characters have been processed.
|
||||
|
||||
Here are a few more examples:
|
||||
|
||||
- =bvwbjplbgvbhsrlpgdmjqwftvncz=: first marker after character =5=
|
||||
- =nppdvjthqldpwncqszvftbrmjlhg=: first marker after character =6=
|
||||
- =nznrnfrfntjfmvfwmzdfjlvtqnbhcprsg=: first marker after character =10=
|
||||
- =zcfzfwzzqfrljwzlrfnpqdbhtmscgvjw=: first marker after character =11=
|
||||
|
||||
/How many characters need to be processed before the first
|
||||
start-of-packet marker is detected?/
|
||||
|
||||
Your puzzle answer was =1658=.
|
||||
|
||||
** --- Part Two ---
|
||||
Your device's communication system is correctly detecting packets, but
|
||||
still isn't working. It looks like it also needs to look for /messages/.
|
||||
|
||||
A /start-of-message marker/ is just like a start-of-packet marker,
|
||||
except it consists of /14 distinct characters/ rather than 4.
|
||||
|
||||
Here are the first positions of start-of-message markers for all of the
|
||||
above examples:
|
||||
|
||||
- =mjqjpqmgbljsphdztnvjfqwrcgsmlb=: first marker after character =19=
|
||||
- =bvwbjplbgvbhsrlpgdmjqwftvncz=: first marker after character =23=
|
||||
- =nppdvjthqldpwncqszvftbrmjlhg=: first marker after character =23=
|
||||
- =nznrnfrfntjfmvfwmzdfjlvtqnbhcprsg=: first marker after character =29=
|
||||
- =zcfzfwzzqfrljwzlrfnpqdbhtmscgvjw=: first marker after character =26=
|
||||
|
||||
/How many characters need to be processed before the first
|
||||
start-of-message marker is detected?/
|
||||
|
||||
Your puzzle answer was =2260=.
|
||||
|
||||
Both parts of this puzzle are complete! They provide two gold stars: **
|
||||
60
2022/day06/aoc-c.c
Normal file
60
2022/day06/aoc-c.c
Normal file
@@ -0,0 +1,60 @@
|
||||
/* aoc-c.c: Advent of Code 2022, day 6
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "br.h"
|
||||
#include "aoc.h"
|
||||
|
||||
struct msg {
|
||||
char *data;
|
||||
size_t len;
|
||||
};
|
||||
|
||||
static struct msg *parse(struct msg *msg)
|
||||
{
|
||||
size_t alloc = 0;
|
||||
|
||||
msg->data=NULL;
|
||||
msg->len = getline(&msg->data, &alloc, stdin);
|
||||
msg->data[--msg->len] = 0;
|
||||
return msg;
|
||||
}
|
||||
|
||||
static int solve(struct msg *msg, int marklen)
|
||||
{
|
||||
char *pcur = msg->data, *pnext = pcur;
|
||||
int len = msg->len, lmark = 0;
|
||||
|
||||
for (; pnext < msg->data + len && lmark < marklen; lmark = ++pnext - pcur) {
|
||||
for (int j = 0; j < lmark; ++j) { /* compare with prev marker chars */
|
||||
if (*(pcur+j) == *pnext) { /* check new char with cur marker */
|
||||
pcur += j + 1; /* move marker to after dup char */
|
||||
goto nextchar;
|
||||
}
|
||||
}
|
||||
nextchar: ;
|
||||
}
|
||||
return pnext - msg->data;
|
||||
}
|
||||
|
||||
int main(int ac, char **av)
|
||||
{
|
||||
int part = parseargs(ac, av);
|
||||
struct msg msg;
|
||||
|
||||
printf("%s: res=%d\n", *av, solve(parse(&msg), part == 1? 4:14));
|
||||
free(msg.data);
|
||||
exit(0);
|
||||
}
|
||||
46
2022/day06/aoc.bash
Executable file
46
2022/day06/aoc.bash
Executable file
@@ -0,0 +1,46 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# aoc.bash: Advent of Code 2022, day 6
|
||||
#
|
||||
# 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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
|
||||
. common.bash
|
||||
|
||||
declare input # datastream
|
||||
declare -i len # len of datastream
|
||||
|
||||
parse() {
|
||||
read -r input
|
||||
len=${#input}
|
||||
}
|
||||
|
||||
solve() {
|
||||
declare -ig res
|
||||
local -i mark=4 lcur=0 part="$1"
|
||||
local cur next
|
||||
|
||||
((part == 2)) && mark=14
|
||||
for (( i = 0; i < len - mark; ++i )); do # loop on all chars
|
||||
next=${input:i:1} # next char
|
||||
for ((j = 0; j < lcur; ++j)); do # compare with previous ones
|
||||
if [[ $next == "${cur:j:1}" ]]; then # duplicate
|
||||
cur="${cur:j+1}$next" # keep str after dup + new char
|
||||
(( lcur -= j ))
|
||||
continue 2
|
||||
fi
|
||||
done
|
||||
cur+="$next" # add new char
|
||||
((++lcur == mark)) && break # mark len found
|
||||
done
|
||||
((res = i + 1))
|
||||
}
|
||||
|
||||
main "$@"
|
||||
exit 0
|
||||
17
2022/day06/aoc.h
Normal file
17
2022/day06/aoc.h
Normal file
@@ -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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
#ifndef _AOC_H_
|
||||
#define _AOC_H_
|
||||
|
||||
extern int parseargs(int ac, char**av);
|
||||
|
||||
#endif /* _AOC_H_ */
|
||||
68
2022/day06/common.bash
Executable file
68
2022/day06/common.bash
Executable file
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# common.bash: Advent of Code 2022, common bash 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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
|
||||
# shellcheck disable=2034
|
||||
export cmdname=${0##*/}
|
||||
export debug=0
|
||||
export res
|
||||
export LANG=C
|
||||
|
||||
shopt -s extglob
|
||||
set -o noglob
|
||||
|
||||
usage() {
|
||||
printf "usage: %s [-d DEBUG] [-p PART]\n" "$cmdname"
|
||||
exit 1
|
||||
}
|
||||
|
||||
checkargs() {
|
||||
local part=1
|
||||
while getopts p:d: todo; do
|
||||
case "$todo" in
|
||||
d)
|
||||
if [[ "$OPTARG" =~ ^[[:digit:]+]$ ]]; then
|
||||
debug="$OPTARG"
|
||||
else
|
||||
printf "%s: illegal [%s] debug level.\n" "$CMD" "$OPTARG"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
p)
|
||||
if [[ "$OPTARG" =~ ^[12]$ ]]; then
|
||||
part="$OPTARG"
|
||||
else
|
||||
printf "%s: illegal [%s] part.\n" "$CMD" "$OPTARG"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
# Now check remaining argument (backup directory)
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
(( $# > 1 )) && usage
|
||||
return "$part"
|
||||
}
|
||||
|
||||
main() {
|
||||
local -i part
|
||||
|
||||
checkargs "$@"
|
||||
part=$?
|
||||
parse "$part"
|
||||
solve "$part"
|
||||
printf "%s: res=%s\n" "$cmdname" "$res"
|
||||
}
|
||||
49
2022/day06/common.c
Normal file
49
2022/day06/common.c
Normal file
@@ -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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
1
2022/day06/input/example.txt
Normal file
1
2022/day06/input/example.txt
Normal file
@@ -0,0 +1 @@
|
||||
mjqjpqmgbljsphdztnvjfqwrcgsmlb
|
||||
1
2022/day06/input/example2.txt
Normal file
1
2022/day06/input/example2.txt
Normal file
@@ -0,0 +1 @@
|
||||
bvwbjplbgvbhsrlpgdmjqwftvncz
|
||||
1
2022/day06/input/example3.txt
Normal file
1
2022/day06/input/example3.txt
Normal file
@@ -0,0 +1 @@
|
||||
nppdvjthqldpwncqszvftbrmjlhg
|
||||
1
2022/day06/input/example4.txt
Normal file
1
2022/day06/input/example4.txt
Normal file
@@ -0,0 +1 @@
|
||||
nznrnfrfntjfmvfwmzdfjlvtqnbhcprsg
|
||||
1
2022/day06/input/example5.txt
Normal file
1
2022/day06/input/example5.txt
Normal file
@@ -0,0 +1 @@
|
||||
zcfzfwzzqfrljwzlrfnpqdbhtmscgvjw
|
||||
1
2022/day06/input/input.txt
Normal file
1
2022/day06/input/input.txt
Normal file
@@ -0,0 +1 @@
|
||||
cbhbmmqnmmqvqfqgqcqmmtvvvdsvscvssmfmhfmhhgdgcclhlnnvmnvmnnwngnqggqlqhhbqbfbvffcpfcfpcpmcppsgssvcvmmdwmwsmwswnwvnvvtgvgfgqqnlltgllpplhpllrnrwrtrzrlrzllpnlpnplnlwnnzfztzcchczctcbbpwpbbfhhqllgrllnnghnnlnznzzlqqmggqbgbjjlnlnjllwlnwnjnbjnnhhcddgmdmqmllfjllddmgmpggtvvqqwmmhcmmjpjdpdqqnhhqbhhscstsvttbwtwdtwwjffvccrwrvvnqqtwwhgwhwthwthhvshsfsjstshthqqdfdhdqhqrqggfffvhffhbbwtbtvtwvvwgvvjjjvtjvvlmlmtmztmthmhttjwwmqqjffhvhqvvrddbsbfbgffmcfffqqfzzgmggzvggbjjmccftcftfnttqqjzjdzdrrgvgsgvvlqvlqqlplnnjccjqcjcgjgfjgjlgjjzhhjbbbfdbfddgccncppsbbjjsttcqtqgqpqllqggtsthhtvvtrttbthtnhhddvnnbggmtggcsgcscmmvmllttjbjggbzbttrfttgsstwtftdthdththbttcggdldtdlttbvvpgpjpwpwvwcwjwsjsttznztzftzzjpzzrtzrztrrtsrrdtrdtdbdhhdgdwwnjnnvjvsjjrwjjvrrzvrvllrgghgbbgbsssslqlrllbjbttzfztzpzzvtvccszsddtqttjllqgqgpqphptpwttwtmtltljjfnnzwzmzlzssghssqhhphbhfftwwqmwmzzqtzqzqrrndrrmrqrzrszzrcrbccglgcgwgrgdggtvtpptgtfgflglgrrnvrvhrrhlrhhfchfhdhzzwggvbbgfgrrpdrdccfllqflfmlfmlmbbhnbbsblbzbgbqqjppcddcvvsddjfjjlnnwbbflfzzmlmddjssjffcqffwdfdqqphpnhppbttjfjzzdvdjvvddnfffmjfmfmpfmmmdlmlrrhqqcpcmclmmbmppzczjjmlltqlqzzqgqcggdmdzznnnnsjjvbjjwbwhbhfhvvtmmsfmmcgmcmwcwhwnhhpccmbmdbmbgbjbggqqccfllfqqmqwwzbblffthhdnncqnccqppldlpldpllzmmsqqdffnggqlqtllwlglnlnhlhflfssvzzrllbtbnbgnnfvfllwslszswsnnpwwppvspsmmnfnpffrmrhmmctttrjrbjrjpjtpjpssdwdtwtmmtgtsgttlwttfrfvvpjpcjccmtthhldhllzslshhnrnvvfddnllltclcrrhnnjwwwpfpddmtmsmfflslrlmlmwmllgfgmfgmmjttpcpspslsjspsqstqsqqpsprphrrpqqfzqqwcwcddsjjpvvfnfvnnnrncnwcwczzcwzwnwmwffbdfbdfdjjhrhvhhvwvsvhshnhwwzlwlnnphhtjjmljjqzjjsjgsjshhwjjmttvgvsgstggrcrmmrqrhrqrzrmzmggqvqtqgtqqqqltqqwggmmzggjccgmgwgqqmnqnrnprptrrvfrvffnmnfmmnnnwzzldlvlgvlvqqpnphpgglhlshlhzzpcptpssblqvdbpbbcrngctqgptccwpdcpbcjwdmcrzmhwffgzqmmqwpqvplwzmjlzmvmzmbtqjnhzrpppnpntvmjbzmvhjvbgflmmjnwssvqvbnbddfcwqdtvpvddctmpptcjmvwszhbsttcbjlfjvwlljhlqlvvsnzphdjhfswltdhzprltzcszrgcmnmfznmbccstjvjngwpbsfqssfwvpdhhmlmzttzlszsgpvvbcfvzrlsttlqpnqhwtbqfjnbztnwfnhlhfltgdtsrrwrfhlssvsgzpffnnrhgcvclqnjgfhhzswllvcjffpngcmtjphwnbdfrrgjfrfqbnvbwgccsjvvmjgcvqvtggnvgvgnnchbblqnvvdgjtvdmfrzvhvhzcbqzdslphjjqtcwjqptstvvpqgdbgbcmmchjpvjhvbwtlmlnqpldfcbmwvrmpqcsfdhmmwnbvmpglcfbnsgjmljcwpzpwffcqfrbdrztzhqzhzpcrjfdmrctttdrzlmzcqwjftngwjmgqscftnpbjwqrcvqwbwbdhbhvrdcvgrvctjgwjtmdgzwgvdbmsrjpsbhwcqlqzjnzmgpctlwqhfnbmgsprjcqtfjjvzljqpfqgnvrgnjjlmpqgnzpmpsvzjmtvnfgslldjtjdwlzrvqrbvcpspzpcdnpdjmhcdhsbmthmgjqchqwwsnfjnwgpctlwcdpqpmzqcrptscngqnmhzwjdcqwvdmlzntsfbstbtmmnlsspjbjjdspnslgcnlbfnbhjlzjhrrmdbbwtswqpbpwtzhcnldbsfrvndzvcgzjprcrclhfwbvzgthcglfzqrshgtvbflvnznhmlzdtfnrsltnnppqgrtndbsfqmftdnzmqfwdpcrmssldmrrnzchnqpflgbqzqjjrzlfnptqdwzdhmctfbztmfcmbqcwjmgnwgqzqjctphrrthgvpvppztvpzgzhdszfhlzlcnwmfrlsnvftfrlfvbnlwzctphhpfvszntqcvnfmvmwwhsjlnpfhcpjvrncgmsbprwwllvnsbjfhtbtmcvvpzcvqrrqdvgzvllvcvnvvbftngqcqcvvbsqfshmnhwptcsbsnjzltqzmflftrhblqszrzsbfcpgzncvwhlqlcbmgjdpfcmlgdfphsfcgqccthmlzjbdwpsbddwwrtwmsvqwbzwhzmghhrspvbptznqsqvhgnhlwqjnhgnzprrtjddwtqfsshjrvlglhdlstghftmllvzmmfglnscnrtgcwwwzjphzhvqlctdwjlqvbsvlgzrdpvjhhcthgjhlwsgfzlschhfprfcrzfrzmnlwvqsnqlllczwfhswchrlggqszwrvpldrffnzrffbhtfbslgcdrqpjcrbqsrgfrhttcptncfndcbsdbjsqjvgbmnmhlnbltdcgbmllpgjmgljvglrwmrvgthhhzrsmzvgwcfgvcsbzpjcqnhrzhznzjcjghhwqvllrmsvlpzlssrdsqwvzvqwsvfsjqvbgrfbmfzlchqsjgncbljtvzsfdnvmfzcbrlnnvvmjbmgjmqzjtdzpljdwqtvwsrlbslwfvlgbtnmlpcwmngncnmdhqctshmjmnhpqcqzhvlbvgptctrvggdgnpnrlnngrfhsqdfthvcnpwjfjnslcqlfrfvhnctmsqgnqmgpwtlzhtdqhqqrcllzjccnszsqvrzhcffvnfnstgdmljdrqrndljdnfbbjvmpqdnqhtdlnzcvnfjlvzmfzrndhtglvngmbrdbpbnhvfmrbcwqzttnjplgrhchjtfjwfbjfbmzlrnllhzccpfhfhnjpfvzlpbqnhwmpssvwtzhdbtnbtllhpfdcqjjnzgbdrfjjbcltnzdrmtmsmvpjtmdnqszgbqncsvhjbgwswhmghpvstrqbglgrtgbchttbznvvdhppzwnttpgcbdjdhlsqhhtlphjjrjncrmfdtjhdwmjgmpngnbptzwgwdztmhtpglnftwpnnmrmcwfhwnhlsbwsrjnlmdlmffbzsnhsvnbldwtrrhdhfsjdrsnzlgtfzcwwqrfhtrmjhmphqndwtbpczvmfgczmdlqjqdlwmvjjzwmqnpvwzmtjwtprlnbvjdhpjgndrwzcfthnwhnhqpwtcjlhrhdplzsncfmszmhjmgljhnlsrrfwplclcvjjqmtpnwbtsbwdnjdlqntvdnfgwbpwspssprbffjdlcvbwcqlttnwnhwdspfsjhppbhspnrvrsfmzvbwwtjfzmnzwgqddbmcjzzqhqlgrglsvgsjdwlnsbtmqgsnfwwqrjsbcgdlmbgqwvgpqllqwbcplfjrgnzsdtdtvqnrbcrqjhdtqqplvszvtlflgbpwnpzczbvhzfjrslcwcswsgfvvsswzzwhtfjfpsrvcfnrs
|
||||
111
2022/day07/Makefile
Normal file
111
2022/day07/Makefile
Normal file
@@ -0,0 +1,111 @@
|
||||
# AOC daily Makefile - GNU make only.
|
||||
#
|
||||
# Copyright (C) 2021-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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
#
|
||||
|
||||
INPUT := input/input.txt
|
||||
SHELL := /bin/bash
|
||||
|
||||
CC := gcc
|
||||
BEAR := bear
|
||||
CCLSFILE:= compile_commands.json
|
||||
|
||||
LIB := aoc_$(shell uname -m)
|
||||
INCDIR := ../include
|
||||
LIBDIR := ../lib
|
||||
LDFLAGS := -L$(LIBDIR)
|
||||
#LDLIB := -l$(LIB) -lm
|
||||
LDLIB := -l$(LIB)
|
||||
|
||||
export LD_LIBRARY_PATH = $(LIBDIR)
|
||||
|
||||
CFLAGS += -std=gnu11
|
||||
CFLAGS += -O2
|
||||
CFLAGS += -g
|
||||
# for gprof
|
||||
# CFLAGS += -pg
|
||||
CFLAGS += -Wall
|
||||
CFLAGS += -Wextra
|
||||
CFLAGS += -march=native
|
||||
# Next one may be useful for valgrind (some invalid instructions)
|
||||
# CFLAGS += -mno-tbm
|
||||
CFLAGS += -Wmissing-declarations
|
||||
CFLAGS += -Wno-unused-result
|
||||
|
||||
CFLAGS += -DDEBUG_DEBUG # activate general debug (debug.c)
|
||||
CFLAGS += -DDEBUG_POOL # memory pools management
|
||||
|
||||
VALGRIND := valgrind
|
||||
VALGRINDFLAGS := --leak-check=full --show-leak-kinds=all --track-origins=yes \
|
||||
--sigill-diagnostics=yes --quiet --show-error-list=yes
|
||||
|
||||
|
||||
TIME := \time -f "\ttime: %E real, %U user, %S sys\n\tcontext-switch:\t%c+%w, page-faults: %F+%R\n"
|
||||
export PATH := .:$(PATH)
|
||||
|
||||
.PHONY: clean all compile assembly memcheck memcheck1 memcheck2 part1 part2 ccls bear org
|
||||
|
||||
all: README.org ccls part1 part2
|
||||
|
||||
memcheck: memcheck1 memcheck2
|
||||
|
||||
memcheck1: aoc-c
|
||||
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 1 < $(INPUT)
|
||||
|
||||
memcheck2: aoc-c
|
||||
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 2 < $(INPUT)
|
||||
@#@valgrind -s --track-origins=yes aoc-c -p 2 < $(INPUT)
|
||||
|
||||
compile: aoc-c
|
||||
|
||||
cpp: aoc-c.i
|
||||
|
||||
assembly: aoc-c.s
|
||||
|
||||
part1: aoc-c
|
||||
@$(TIME) aoc.bash -p 1 < $(INPUT) 2>&1
|
||||
@$(TIME) aoc-c -p 1 < $(INPUT)
|
||||
|
||||
part2: aoc-c
|
||||
@$(TIME) aoc.bash -p 2 < $(INPUT) 2>&1
|
||||
@$(TIME) aoc-c -p 2 < $(INPUT)
|
||||
|
||||
ccls: $(CCLSFILE)
|
||||
|
||||
clean:
|
||||
@rm -f aoc-c core* vgcore* gmon.out aoc-c.s aoc-c.i README.html compile_commands.json
|
||||
|
||||
aoc-c: aoc-c.c common.c
|
||||
@echo compiling $<
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -I $(INCDIR) $^ $(LDLIB) -o $@
|
||||
|
||||
# generate pre-processed file (.i) and assembler (.s)
|
||||
%.i: %.c
|
||||
@echo generating $@
|
||||
@$(CC) -E $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||
|
||||
%.s: %.c
|
||||
@echo generating $@
|
||||
@$(CC) -S -fverbose-asm $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||
|
||||
# generate README.org from README.html (must cleanup !)
|
||||
org: README.org
|
||||
|
||||
%.org: %.html
|
||||
@echo generating $@. Cleanup before commit !
|
||||
@pandoc $< -o $@
|
||||
|
||||
# generate compile_commands.json
|
||||
$(CCLSFILE): aoc-c.c Makefile
|
||||
$(BEAR) -- make clean compile
|
||||
|
||||
bear: clean
|
||||
@touch .ccls-root
|
||||
@$(BEAR) -- make compile
|
||||
156
2022/day07/README.org
Normal file
156
2022/day07/README.org
Normal file
@@ -0,0 +1,156 @@
|
||||
** --- Day 7: No Space Left On Device ---
|
||||
You can hear birds chirping and raindrops hitting leaves as the
|
||||
expedition proceeds. Occasionally, you can even hear much louder sounds
|
||||
in the distance; how big do the animals get out here, anyway?
|
||||
|
||||
The device the Elves gave you has problems with more than just its
|
||||
communication system. You try to run a system update:
|
||||
|
||||
#+begin_example
|
||||
$ system-update --please --pretty-please-with-sugar-on-top
|
||||
Error: No space left on device
|
||||
#+end_example
|
||||
|
||||
Perhaps you can delete some files to make space for the update?
|
||||
|
||||
You browse around the filesystem to assess the situation and save the
|
||||
resulting terminal output (your puzzle input). For example:
|
||||
|
||||
#+begin_example
|
||||
$ cd /
|
||||
$ ls
|
||||
dir a
|
||||
14848514 b.txt
|
||||
8504156 c.dat
|
||||
dir d
|
||||
$ cd a
|
||||
$ ls
|
||||
dir e
|
||||
29116 f
|
||||
2557 g
|
||||
62596 h.lst
|
||||
$ cd e
|
||||
$ ls
|
||||
584 i
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd d
|
||||
$ ls
|
||||
4060174 j
|
||||
8033020 d.log
|
||||
5626152 d.ext
|
||||
7214296 k
|
||||
#+end_example
|
||||
|
||||
The filesystem consists of a tree of files (plain data) and directories
|
||||
(which can contain other directories or files). The outermost directory
|
||||
is called =/=. You can navigate around the filesystem, moving into or
|
||||
out of directories and listing the contents of the directory you're
|
||||
currently in.
|
||||
|
||||
Within the terminal output, lines that begin with =$= are /commands you
|
||||
executed/, very much like some modern computers:
|
||||
|
||||
- =cd= means /change directory/. This changes which directory is the
|
||||
current directory, but the specific result depends on the argument:
|
||||
- =cd x= moves /in/ one level: it looks in the current directory for
|
||||
the directory named =x= and makes it the current directory.
|
||||
- =cd ..= moves /out/ one level: it finds the directory that contains
|
||||
the current directory, then makes that directory the current
|
||||
directory.
|
||||
- =cd /= switches the current directory to the outermost directory,
|
||||
=/=.
|
||||
- =ls= means /list/. It prints out all of the files and directories
|
||||
immediately contained by the current directory:
|
||||
- =123 abc= means that the current directory contains a file named
|
||||
=abc= with size =123=.
|
||||
- =dir xyz= means that the current directory contains a directory
|
||||
named =xyz=.
|
||||
|
||||
Given the commands and output in the example above, you can determine
|
||||
that the filesystem looks visually like this:
|
||||
|
||||
#+begin_example
|
||||
- / (dir)
|
||||
- a (dir)
|
||||
- e (dir)
|
||||
- i (file, size=584)
|
||||
- f (file, size=29116)
|
||||
- g (file, size=2557)
|
||||
- h.lst (file, size=62596)
|
||||
- b.txt (file, size=14848514)
|
||||
- c.dat (file, size=8504156)
|
||||
- d (dir)
|
||||
- j (file, size=4060174)
|
||||
- d.log (file, size=8033020)
|
||||
- d.ext (file, size=5626152)
|
||||
- k (file, size=7214296)
|
||||
#+end_example
|
||||
|
||||
Here, there are four directories: =/= (the outermost directory), =a= and
|
||||
=d= (which are in =/=), and =e= (which is in =a=). These directories
|
||||
also contain files of various sizes.
|
||||
|
||||
Since the disk is full, your first step should probably be to find
|
||||
directories that are good candidates for deletion. To do this, you need
|
||||
to determine the /total size/ of each directory. The total size of a
|
||||
directory is the sum of the sizes of the files it contains, directly or
|
||||
indirectly. (Directories themselves do not count as having any intrinsic
|
||||
size.)
|
||||
|
||||
The total sizes of the directories above can be found as follows:
|
||||
|
||||
- The total size of directory =e= is /584/ because it contains a single
|
||||
file =i= of size 584 and no other directories.
|
||||
- The directory =a= has total size /94853/ because it contains files =f=
|
||||
(size 29116), =g= (size 2557), and =h.lst= (size 62596), plus file =i=
|
||||
indirectly (=a= contains =e= which contains =i=).
|
||||
- Directory =d= has total size /24933642/.
|
||||
- As the outermost directory, =/= contains every file. Its total size is
|
||||
/48381165/, the sum of the size of every file.
|
||||
|
||||
To begin, find all of the directories with a total size of /at most
|
||||
100000/, then calculate the sum of their total sizes. In the example
|
||||
above, these directories are =a= and =e=; the sum of their total sizes
|
||||
is =95437= (94853 + 584). (As in this example, this process can count
|
||||
files more than once!)
|
||||
|
||||
Find all of the directories with a total size of at most 100000. /What
|
||||
is the sum of the total sizes of those directories?/
|
||||
|
||||
Your puzzle answer was =1390824=.
|
||||
|
||||
** --- Part Two ---
|
||||
Now, you're ready to choose a directory to delete.
|
||||
|
||||
The total disk space available to the filesystem is =70000000=. To run
|
||||
the update, you need unused space of at least =30000000=. You need to
|
||||
find a directory you can delete that will /free up enough space/ to run
|
||||
the update.
|
||||
|
||||
In the example above, the total size of the outermost directory (and
|
||||
thus the total amount of used space) is =48381165=; this means that the
|
||||
size of the /unused/ space must currently be =21618835=, which isn't
|
||||
quite the =30000000= required by the update. Therefore, the update still
|
||||
requires a directory with total size of at least =8381165= to be deleted
|
||||
before it can run.
|
||||
|
||||
To achieve this, you have the following options:
|
||||
|
||||
- Delete directory =e=, which would increase unused space by =584=.
|
||||
- Delete directory =a=, which would increase unused space by =94853=.
|
||||
- Delete directory =d=, which would increase unused space by =24933642=.
|
||||
- Delete directory =/=, which would increase unused space by =48381165=.
|
||||
|
||||
Directories =e= and =a= are both too small; deleting them would not free
|
||||
up enough space. However, directories =d= and =/= are both big enough!
|
||||
Between these, choose the /smallest/: =d=, increasing unused space by
|
||||
=24933642=.
|
||||
|
||||
Find the smallest directory that, if deleted, would free up enough space
|
||||
on the filesystem to run the update. /What is the total size of that
|
||||
directory?/
|
||||
|
||||
Your puzzle answer was =7490863=.
|
||||
|
||||
Both parts of this puzzle are complete! They provide two gold stars: **
|
||||
194
2022/day07/aoc-c.c
Normal file
194
2022/day07/aoc-c.c
Normal file
@@ -0,0 +1,194 @@
|
||||
/* aoc-c.c: Advent of Code 2022, day 7
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "pool.h"
|
||||
#include "debug.h"
|
||||
#include "br.h"
|
||||
#include "aoc.h"
|
||||
#include "hashtable.h"
|
||||
#include "pjwhash-inline.h"
|
||||
|
||||
/* we will totally ignore the tree structure here and only keep a hashtable
|
||||
* to keep directories sizes.
|
||||
*/
|
||||
#define HBITS 9 /* 9 bits: size is 512 */
|
||||
#define DIRNAME_SIZE 128
|
||||
|
||||
DEFINE_HASHTABLE(hasht_dir, HBITS);
|
||||
|
||||
typedef struct dir {
|
||||
char name[DIRNAME_SIZE];
|
||||
uint namelen;
|
||||
uint hash;
|
||||
int size;
|
||||
struct hlist_node hlist;
|
||||
} dir_t;
|
||||
|
||||
static pool_t *pool_dirs;
|
||||
|
||||
/**
|
||||
* find_dir - find entry in an hashtable bucket
|
||||
*/
|
||||
static dir_t *find_dir(struct hlist_head *head, uint hash, char *dir, uint len)
|
||||
{
|
||||
dir_t *cur;
|
||||
|
||||
hlist_for_each_entry(cur, head, hlist)
|
||||
if (cur->hash == hash && cur->namelen == len && !memcmp(cur->name, dir, len))
|
||||
return cur;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static dir_t *find_dirname(char *name, uint len)
|
||||
{
|
||||
uint hash = pjwhash(name, len);
|
||||
uint bucket = hash_32(hash, HBITS);
|
||||
|
||||
return find_dir(&hasht_dir[bucket], hash, name, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* parent_dir - get new len of parent directory
|
||||
*/
|
||||
static int parent_dir(char *dir, uint len)
|
||||
{
|
||||
for (--len; len && *(dir + len) != '/'; --len)
|
||||
;
|
||||
return len? len: 1;
|
||||
}
|
||||
|
||||
static void adjust_dirsize(dir_t *dir, uint size)
|
||||
{
|
||||
dir_t *cur = dir;
|
||||
uint len = cur->namelen;
|
||||
|
||||
while (len > 1) {
|
||||
cur = find_dirname(dir->name, len);
|
||||
if (!cur) {
|
||||
log(1, "FATAL hash issue");
|
||||
exit(1);
|
||||
}
|
||||
cur->size +=size;
|
||||
len = parent_dir(dir->name, len);
|
||||
};
|
||||
cur = find_dirname("/", 1); /* do not forget "/" */
|
||||
cur->size += size;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_dir - add an entry in hashtable
|
||||
*/
|
||||
static struct dir *add_dir(char *dir, uint len)
|
||||
{
|
||||
uint hash = pjwhash(dir, len);
|
||||
uint bucket = hash_32(hash, HBITS);
|
||||
dir_t *new = pool_get(pool_dirs);
|
||||
|
||||
memcpy(new->name, dir, len);
|
||||
new->namelen = len;
|
||||
new->hash = hash;
|
||||
new->size = 0;
|
||||
hlist_add_head(&new->hlist, &hasht_dir[bucket]);
|
||||
return new;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_dir_maybe - add an entry in hashtable if it does not exist
|
||||
*/
|
||||
static struct dir *add_dir_maybe(char *dir, int len)
|
||||
{
|
||||
dir_t *new = find_dirname(dir, len);
|
||||
return new? new: add_dir(dir, len);
|
||||
}
|
||||
|
||||
static struct dir *cd(struct dir *dir, char *to, uint tolen)
|
||||
{
|
||||
char *newname = dir->name;
|
||||
int newlen, add_slash = 0;
|
||||
|
||||
if (!dir)
|
||||
return add_dir_maybe(to, tolen);
|
||||
if (dir->namelen + tolen + 1 > DIRNAME_SIZE) /* conservative (think / or ..) */
|
||||
return NULL;
|
||||
if (*to == '.') { /* .. = parent dir */
|
||||
newlen = parent_dir(dir->name, dir->namelen);
|
||||
} else if (*to == '/') { /* root */
|
||||
newname = to;
|
||||
newlen = tolen;
|
||||
} else { /* subdir */
|
||||
newlen = dir->namelen + tolen;
|
||||
if (dir->namelen > 1) { /* add '/' separator */
|
||||
dir->name[dir->namelen] = '/';
|
||||
add_slash = 1;
|
||||
newlen++;
|
||||
}
|
||||
memcpy(dir->name + dir->namelen + add_slash, to, tolen);
|
||||
}
|
||||
return add_dir_maybe(newname, newlen);
|
||||
}
|
||||
|
||||
#define CDLEN (sizeof("$ cd ") - 1)
|
||||
|
||||
static void parse()
|
||||
{
|
||||
dir_t *curdir = NULL;
|
||||
size_t alloc = 0;
|
||||
char *buf = NULL, *tok;
|
||||
ssize_t buflen;
|
||||
|
||||
while ((buflen = getline(&buf, &alloc, stdin)) > 0) {
|
||||
buf[--buflen] = 0;
|
||||
tok = buf;
|
||||
if (*tok == '$' &&*(tok+2) == 'c') /* ignore "ls"" */
|
||||
curdir = cd(curdir, tok + CDLEN, buflen - CDLEN);
|
||||
else if (isdigit(*tok)) /* ignore "dir" keyword */
|
||||
adjust_dirsize(curdir, atoi(tok));
|
||||
}
|
||||
free(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
static int solve(int part)
|
||||
{
|
||||
ulong bucket;
|
||||
dir_t *cur;
|
||||
int res = 0, needed;
|
||||
|
||||
if (part == 1) {
|
||||
hash_for_each(hasht_dir, bucket, cur, hlist)
|
||||
if (cur->size <= 100000)
|
||||
res += cur->size;
|
||||
} else {
|
||||
res = find_dirname("/", 1)->size;
|
||||
needed = res - (70000000-30000000);
|
||||
hash_for_each(hasht_dir, bucket, cur, hlist)
|
||||
if (cur->size >= needed && cur->size < res)
|
||||
res = cur->size;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int main(int ac, char **av)
|
||||
{
|
||||
int part = parseargs(ac, av);
|
||||
pool_dirs = pool_create("dirs", 128, sizeof(dir_t));
|
||||
|
||||
parse();
|
||||
printf("%s: res=%d\n", *av, solve(part));
|
||||
pool_destroy(pool_dirs);
|
||||
exit(0);
|
||||
}
|
||||
102
2022/day07/aoc.bash
Executable file
102
2022/day07/aoc.bash
Executable file
@@ -0,0 +1,102 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# aoc.bash: Advent of Code 2022, day 7
|
||||
#
|
||||
# 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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
|
||||
. common.bash
|
||||
|
||||
declare -A sizes=() # file size
|
||||
declare -A dirs=() # directories
|
||||
declare -a lines # shell lines
|
||||
declare -i curline=0 # current line in shell
|
||||
declare curdir
|
||||
|
||||
do_cd() {
|
||||
local dir="$1"
|
||||
case "$dir" in
|
||||
"..")
|
||||
curdir=${curdir%/*}
|
||||
[[ -z $curdir ]] && curdir="/"
|
||||
;;
|
||||
"/")
|
||||
curdir="/"
|
||||
;;
|
||||
*)
|
||||
[[ $curdir != "/" ]] && curdir+="/"
|
||||
curdir+="$dir"
|
||||
esac
|
||||
dirs[$curdir]="$curdir"
|
||||
}
|
||||
|
||||
do_ls() {
|
||||
local remain
|
||||
local -i size
|
||||
((curline++))
|
||||
while [[ $curline -lt ${#lines[@]} && ${lines[$curline]:0:1} != "\$" ]]; do
|
||||
if [[ "${lines[$curline]}" != dir* ]]; then
|
||||
size=${lines[$curline]% *}
|
||||
remain="$curdir"
|
||||
while [[ -n $remain ]]; do # recurse up curdir and adjust sizes
|
||||
((sizes[$remain] += size))
|
||||
remain=${remain%/*}
|
||||
done
|
||||
(( sizes["/"] += size ))
|
||||
fi
|
||||
((curline++))
|
||||
done
|
||||
((curline--))
|
||||
}
|
||||
|
||||
parse() {
|
||||
readarray -t lines
|
||||
curline=0
|
||||
declare -a line
|
||||
|
||||
while ((curline < ${#lines[@]})); do
|
||||
read -ra line <<< "${lines[$curline]}"
|
||||
case "${line[1]}" in
|
||||
"cd")
|
||||
do_cd "${line[2]}"
|
||||
;;
|
||||
"ls")
|
||||
do_ls
|
||||
;;
|
||||
esac
|
||||
((curline++))
|
||||
done
|
||||
}
|
||||
|
||||
solve() {
|
||||
declare -ig res
|
||||
local part="$1" dir mindir="/"
|
||||
local -i needed
|
||||
|
||||
if ((part == 1)); then
|
||||
for dir in "${dirs[@]}"; do
|
||||
((sizes[$dir] <= 100000 )) && ((res+=sizes[$dir]))
|
||||
done
|
||||
else
|
||||
(( res = sizes["/"] ))
|
||||
(( needed = sizes["/"] - (70000000-30000000) ))
|
||||
for dir in "${!dirs[@]}"; do
|
||||
if (( sizes[$dir] >= needed )); then
|
||||
if (( sizes[$dir] <= res )); then
|
||||
mindir=$dir
|
||||
((res = sizes[$mindir]))
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
fi
|
||||
}
|
||||
|
||||
main "$@"
|
||||
exit 0
|
||||
17
2022/day07/aoc.h
Normal file
17
2022/day07/aoc.h
Normal file
@@ -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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
#ifndef _AOC_H_
|
||||
#define _AOC_H_
|
||||
|
||||
extern int parseargs(int ac, char**av);
|
||||
|
||||
#endif /* _AOC_H_ */
|
||||
68
2022/day07/common.bash
Executable file
68
2022/day07/common.bash
Executable file
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# common.bash: Advent of Code 2022, common bash 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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
|
||||
# shellcheck disable=2034
|
||||
export cmdname=${0##*/}
|
||||
export debug=0
|
||||
export res
|
||||
export LANG=C
|
||||
|
||||
shopt -s extglob
|
||||
set -o noglob
|
||||
|
||||
usage() {
|
||||
printf "usage: %s [-d DEBUG] [-p PART]\n" "$cmdname"
|
||||
exit 1
|
||||
}
|
||||
|
||||
checkargs() {
|
||||
local part=1
|
||||
while getopts p:d: todo; do
|
||||
case "$todo" in
|
||||
d)
|
||||
if [[ "$OPTARG" =~ ^[[:digit:]+]$ ]]; then
|
||||
debug="$OPTARG"
|
||||
else
|
||||
printf "%s: illegal [%s] debug level.\n" "$CMD" "$OPTARG"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
p)
|
||||
if [[ "$OPTARG" =~ ^[12]$ ]]; then
|
||||
part="$OPTARG"
|
||||
else
|
||||
printf "%s: illegal [%s] part.\n" "$CMD" "$OPTARG"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
# Now check remaining argument (backup directory)
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
(( $# > 1 )) && usage
|
||||
return "$part"
|
||||
}
|
||||
|
||||
main() {
|
||||
local -i part
|
||||
|
||||
checkargs "$@"
|
||||
part=$?
|
||||
parse "$part"
|
||||
solve "$part"
|
||||
printf "%s: res=%s\n" "$cmdname" "$res"
|
||||
}
|
||||
49
2022/day07/common.c
Normal file
49
2022/day07/common.c
Normal file
@@ -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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
23
2022/day07/input/example.txt
Normal file
23
2022/day07/input/example.txt
Normal file
@@ -0,0 +1,23 @@
|
||||
$ cd /
|
||||
$ ls
|
||||
dir a
|
||||
14848514 b.txt
|
||||
8504156 c.dat
|
||||
dir d
|
||||
$ cd a
|
||||
$ ls
|
||||
dir e
|
||||
29116 f
|
||||
2557 g
|
||||
62596 h.lst
|
||||
$ cd e
|
||||
$ ls
|
||||
584 i
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd d
|
||||
$ ls
|
||||
4060174 j
|
||||
8033020 d.log
|
||||
5626152 d.ext
|
||||
7214296 k
|
||||
950
2022/day07/input/input.txt
Normal file
950
2022/day07/input/input.txt
Normal file
@@ -0,0 +1,950 @@
|
||||
$ cd /
|
||||
$ ls
|
||||
dir cvt
|
||||
4967 hcqbmwc.gts
|
||||
5512 hsbhwb.clj
|
||||
dir hvfvt
|
||||
dir phwgv
|
||||
277125 pwgswq.fld
|
||||
42131 qdzr.btl
|
||||
dir svw
|
||||
144372 vmbnlzgb.wbd
|
||||
dir zft
|
||||
$ cd cvt
|
||||
$ ls
|
||||
dir bbgsthsd
|
||||
146042 bcqrmp.czf
|
||||
dir chhdjtlw
|
||||
dir cpcfcc
|
||||
dir dch
|
||||
dir djb
|
||||
dir djfww
|
||||
dir drdf
|
||||
dir fgbqtjlj
|
||||
dir hjsmmj
|
||||
243293 hvfvt.qtb
|
||||
245795 lrpb
|
||||
dir msptbrl
|
||||
181756 qlqqmndd.zcb
|
||||
18658 rtfzt.tjp
|
||||
dir slpc
|
||||
$ cd bbgsthsd
|
||||
$ ls
|
||||
236957 djfww.fcb
|
||||
112286 hcqbmwc.gts
|
||||
106102 qggjrzts
|
||||
$ cd ..
|
||||
$ cd chhdjtlw
|
||||
$ ls
|
||||
226927 cpcfcc
|
||||
309815 djfww
|
||||
117933 hcqbmwc.gts
|
||||
dir mbdrgfzs
|
||||
dir pbmcnpzf
|
||||
131558 pwgswq.fld
|
||||
298691 qlqqmndd.zcb
|
||||
$ cd mbdrgfzs
|
||||
$ ls
|
||||
164331 hvfvt.dvq
|
||||
$ cd ..
|
||||
$ cd pbmcnpzf
|
||||
$ ls
|
||||
102120 bjgg.cqd
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd cpcfcc
|
||||
$ ls
|
||||
15756 ddc
|
||||
dir dqc
|
||||
dir glm
|
||||
dir jbszm
|
||||
200345 pwgswq.fld
|
||||
145508 qlqqmndd.zcb
|
||||
dir vcptbw
|
||||
dir zrtm
|
||||
$ cd dqc
|
||||
$ ls
|
||||
dir cpcfcc
|
||||
92063 mzp
|
||||
dir qmhnvmh
|
||||
dir snqqcjlw
|
||||
8423 zdjwr.blc
|
||||
$ cd cpcfcc
|
||||
$ ls
|
||||
dir hvfvt
|
||||
$ cd hvfvt
|
||||
$ ls
|
||||
289372 pwgswq.fld
|
||||
307397 qlqqmndd.zcb
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd qmhnvmh
|
||||
$ ls
|
||||
274778 jczjwdl.smd
|
||||
194322 ngrrfm
|
||||
$ cd ..
|
||||
$ cd snqqcjlw
|
||||
$ ls
|
||||
182851 nprvrgd.tbb
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd glm
|
||||
$ ls
|
||||
188702 hpq.hgm
|
||||
$ cd ..
|
||||
$ cd jbszm
|
||||
$ ls
|
||||
187645 pwgswq.fld
|
||||
$ cd ..
|
||||
$ cd vcptbw
|
||||
$ ls
|
||||
dir mgqd
|
||||
$ cd mgqd
|
||||
$ ls
|
||||
157695 rhldvntj.jzm
|
||||
268696 rjnngctw
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd zrtm
|
||||
$ ls
|
||||
218820 bcqrmp.czf
|
||||
172319 czpsl.dnf
|
||||
180114 hcqbmwc.gts
|
||||
165216 hvfvt.nnw
|
||||
dir zft
|
||||
$ cd zft
|
||||
$ ls
|
||||
161245 dtqjg.czv
|
||||
249888 hpq.hgm
|
||||
192037 zft
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd dch
|
||||
$ ls
|
||||
dir djfww
|
||||
dir fzqgwwnf
|
||||
dir hqvmq
|
||||
dir mmcrzqc
|
||||
42136 qlqqmndd.zcb
|
||||
dir vdtlh
|
||||
dir wfltm
|
||||
271200 zrtm
|
||||
$ cd djfww
|
||||
$ ls
|
||||
37427 dct
|
||||
204401 hcqbmwc.gts
|
||||
283140 jmq
|
||||
dir lbrhbc
|
||||
154148 pncb.bmp
|
||||
53366 vzt.cnn
|
||||
$ cd lbrhbc
|
||||
$ ls
|
||||
dir djfww
|
||||
153648 djfww.pps
|
||||
308911 mvtjzp.btg
|
||||
219150 ncmc
|
||||
253604 wqft.ggb
|
||||
293759 zft
|
||||
$ cd djfww
|
||||
$ ls
|
||||
24794 hcqbmwc.gts
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd fzqgwwnf
|
||||
$ ls
|
||||
233720 scdd.pwr
|
||||
$ cd ..
|
||||
$ cd hqvmq
|
||||
$ ls
|
||||
dir cdld
|
||||
dir cpcfcc
|
||||
dir djfww
|
||||
85564 hpq.hgm
|
||||
dir qnc
|
||||
81509 wtnl.crs
|
||||
$ cd cdld
|
||||
$ ls
|
||||
293421 llpltsgn.tqb
|
||||
$ cd ..
|
||||
$ cd cpcfcc
|
||||
$ ls
|
||||
230813 cglljgv
|
||||
178203 qlqqmndd.zcb
|
||||
186410 zrtm.tbt
|
||||
$ cd ..
|
||||
$ cd djfww
|
||||
$ ls
|
||||
201830 zrtm
|
||||
$ cd ..
|
||||
$ cd qnc
|
||||
$ ls
|
||||
305356 bdf.jrh
|
||||
dir zrtm
|
||||
$ cd zrtm
|
||||
$ ls
|
||||
dir bdhdrr
|
||||
$ cd bdhdrr
|
||||
$ ls
|
||||
dir nffdrnb
|
||||
$ cd nffdrnb
|
||||
$ ls
|
||||
301601 nbrjz
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd mmcrzqc
|
||||
$ ls
|
||||
dir cpcfcc
|
||||
264271 hpq.hgm
|
||||
208744 tzsjrf.zdc
|
||||
274096 zft
|
||||
$ cd cpcfcc
|
||||
$ ls
|
||||
226054 cpcfcc
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd vdtlh
|
||||
$ ls
|
||||
84229 bzlg.crn
|
||||
58668 cpcfcc.zqw
|
||||
141409 hpq.hgm
|
||||
dir mdgst
|
||||
37090 pstsh.qwv
|
||||
40357 qlqqmndd.zcb
|
||||
dir smr
|
||||
dir sqbgcsgh
|
||||
dir trp
|
||||
$ cd mdgst
|
||||
$ ls
|
||||
151033 fsmvbpsl.nqr
|
||||
$ cd ..
|
||||
$ cd smr
|
||||
$ ls
|
||||
140764 cpcfcc.dpg
|
||||
$ cd ..
|
||||
$ cd sqbgcsgh
|
||||
$ ls
|
||||
dir djfww
|
||||
263783 dvm
|
||||
105219 hpq.hgm
|
||||
29647 hwcgv.gvg
|
||||
162537 lwjhgh.wmt
|
||||
235511 nlw
|
||||
dir zwddrdfz
|
||||
$ cd djfww
|
||||
$ ls
|
||||
260084 vcgpvpd
|
||||
$ cd ..
|
||||
$ cd zwddrdfz
|
||||
$ ls
|
||||
225632 bhrzzw
|
||||
269756 cqq.vrz
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd trp
|
||||
$ ls
|
||||
233192 vqwngcs
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd wfltm
|
||||
$ ls
|
||||
140990 djfww
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd djb
|
||||
$ ls
|
||||
213191 cjwrs.prd
|
||||
dir dhvpqt
|
||||
dir gtgftm
|
||||
dir hvfvt
|
||||
208325 jwhp
|
||||
301446 qlqqmndd.zcb
|
||||
dir qnlbgvf
|
||||
dir tps
|
||||
dir zft
|
||||
dir zrtm
|
||||
dir zwnlm
|
||||
$ cd dhvpqt
|
||||
$ ls
|
||||
dir sbcj
|
||||
$ cd sbcj
|
||||
$ ls
|
||||
20611 ggt
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd gtgftm
|
||||
$ ls
|
||||
179526 qcqbtmvq
|
||||
$ cd ..
|
||||
$ cd hvfvt
|
||||
$ ls
|
||||
dir djstcnrt
|
||||
dir hggpvn
|
||||
dir hvfvt
|
||||
63889 hvfvt.tjm
|
||||
265836 qlqqmndd.zcb
|
||||
105663 zft
|
||||
223582 zft.llg
|
||||
26037 zzwwg.lqh
|
||||
$ cd djstcnrt
|
||||
$ ls
|
||||
201498 hcqbmwc.gts
|
||||
139156 hpq.hgm
|
||||
277342 pshgz.rtp
|
||||
dir rjb
|
||||
257294 rqrb.lhh
|
||||
dir tqnbfnt
|
||||
313308 zft.dvc
|
||||
$ cd rjb
|
||||
$ ls
|
||||
268438 hpq.hgm
|
||||
dir hvfvt
|
||||
dir hvwpb
|
||||
161024 mzbcgqc.nvw
|
||||
137875 pwgswq.fld
|
||||
260008 pzzcww
|
||||
283261 wnvlrg.tmn
|
||||
$ cd hvfvt
|
||||
$ ls
|
||||
dir dvwqqt
|
||||
163397 hcqbmwc.gts
|
||||
265154 pwgswq.fld
|
||||
dir trsh
|
||||
dir vnf
|
||||
$ cd dvwqqt
|
||||
$ ls
|
||||
315187 hcqbmwc.gts
|
||||
$ cd ..
|
||||
$ cd trsh
|
||||
$ ls
|
||||
dir ssrdpg
|
||||
$ cd ssrdpg
|
||||
$ ls
|
||||
dir vjdc
|
||||
$ cd vjdc
|
||||
$ ls
|
||||
dir srvdrhdq
|
||||
$ cd srvdrhdq
|
||||
$ ls
|
||||
74145 djfww
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd vnf
|
||||
$ ls
|
||||
dir djfww
|
||||
$ cd djfww
|
||||
$ ls
|
||||
184018 pwgswq.fld
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd hvwpb
|
||||
$ ls
|
||||
dir jwpjrcvs
|
||||
$ cd jwpjrcvs
|
||||
$ ls
|
||||
dir cpcfcc
|
||||
$ cd cpcfcc
|
||||
$ ls
|
||||
52191 sdlv
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd tqnbfnt
|
||||
$ ls
|
||||
dir djfww
|
||||
206341 fmpb.lnp
|
||||
dir fpsjg
|
||||
4589 hcqbmwc.gts
|
||||
dir hvfvt
|
||||
8796 hvfvt.hdz
|
||||
238364 tgcdpjc.fjm
|
||||
dir zrtm
|
||||
40577 zrtm.fsr
|
||||
$ cd djfww
|
||||
$ ls
|
||||
217182 djfww.rbf
|
||||
$ cd ..
|
||||
$ cd fpsjg
|
||||
$ ls
|
||||
52456 djfww
|
||||
$ cd ..
|
||||
$ cd hvfvt
|
||||
$ ls
|
||||
dir rqhzvb
|
||||
275026 szwgzm.qjd
|
||||
dir zbmtstj
|
||||
$ cd rqhzvb
|
||||
$ ls
|
||||
8395 gcmzsd.jzf
|
||||
$ cd ..
|
||||
$ cd zbmtstj
|
||||
$ ls
|
||||
39691 qlqqmndd.zcb
|
||||
dir qqcdss
|
||||
180676 rwl.zwr
|
||||
$ cd qqcdss
|
||||
$ ls
|
||||
106297 zrtm.nsl
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd zrtm
|
||||
$ ls
|
||||
153478 ldhvt
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd hggpvn
|
||||
$ ls
|
||||
19109 cpcfcc.fbh
|
||||
249168 fnqjc
|
||||
207420 qgzsh.pfs
|
||||
135472 qlqqmndd.zcb
|
||||
$ cd ..
|
||||
$ cd hvfvt
|
||||
$ ls
|
||||
dir djfww
|
||||
213659 hcqbmwc.gts
|
||||
dir jzdwq
|
||||
204021 nvbgf
|
||||
185328 qlqqmndd.zcb
|
||||
dir zrtm
|
||||
$ cd djfww
|
||||
$ ls
|
||||
180713 rwmm.gjt
|
||||
$ cd ..
|
||||
$ cd jzdwq
|
||||
$ ls
|
||||
57424 djfww.qtm
|
||||
104960 slq.bfp
|
||||
174906 svc
|
||||
$ cd ..
|
||||
$ cd zrtm
|
||||
$ ls
|
||||
dir mrtvhht
|
||||
$ cd mrtvhht
|
||||
$ ls
|
||||
188512 djfww.fvm
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd qnlbgvf
|
||||
$ ls
|
||||
dir fjrhtssv
|
||||
46767 jhbnml.lpq
|
||||
$ cd fjrhtssv
|
||||
$ ls
|
||||
198664 fgcc
|
||||
245142 tsc.rsd
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd tps
|
||||
$ ls
|
||||
dir fmlwghjv
|
||||
146731 gwch.ttr
|
||||
dir jjzmdd
|
||||
dir rtltrng
|
||||
191609 wff.mqt
|
||||
$ cd fmlwghjv
|
||||
$ ls
|
||||
189227 zrtm.vgg
|
||||
$ cd ..
|
||||
$ cd jjzmdd
|
||||
$ ls
|
||||
dir hvfvt
|
||||
178057 mpdfrrm
|
||||
49493 pwgswq.fld
|
||||
220129 sqgfb.flm
|
||||
231012 zrmsnmr
|
||||
$ cd hvfvt
|
||||
$ ls
|
||||
dir lbndbhc
|
||||
12602 mnclbss
|
||||
746 ppw
|
||||
$ cd lbndbhc
|
||||
$ ls
|
||||
49601 cdqvs.gwc
|
||||
158670 wvjpchjg
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd rtltrng
|
||||
$ ls
|
||||
dir cpgh
|
||||
115613 hvfvt
|
||||
59441 zfs
|
||||
$ cd cpgh
|
||||
$ ls
|
||||
dir djfww
|
||||
$ cd djfww
|
||||
$ ls
|
||||
dir tgt
|
||||
$ cd tgt
|
||||
$ ls
|
||||
dir vqwvqss
|
||||
$ cd vqwvqss
|
||||
$ ls
|
||||
dir bsdrhz
|
||||
$ cd bsdrhz
|
||||
$ ls
|
||||
dir pld
|
||||
$ cd pld
|
||||
$ ls
|
||||
8543 mfs.gsb
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd zft
|
||||
$ ls
|
||||
dir fhjgg
|
||||
$ cd fhjgg
|
||||
$ ls
|
||||
114494 pwgswq.fld
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd zrtm
|
||||
$ ls
|
||||
201142 tlhr.rtd
|
||||
298232 wlcztszv
|
||||
$ cd ..
|
||||
$ cd zwnlm
|
||||
$ ls
|
||||
240023 hcqbmwc.gts
|
||||
159126 hpq.hgm
|
||||
22101 hvfvt.bfw
|
||||
dir ltzl
|
||||
dir mtfr
|
||||
dir sbw
|
||||
dir sqscdjlj
|
||||
dir ssf
|
||||
$ cd ltzl
|
||||
$ ls
|
||||
260692 hpq.hgm
|
||||
204540 hvfvt
|
||||
$ cd ..
|
||||
$ cd mtfr
|
||||
$ ls
|
||||
15391 pwgswq.fld
|
||||
$ cd ..
|
||||
$ cd sbw
|
||||
$ ls
|
||||
293226 hcqbmwc.gts
|
||||
267478 htllcq
|
||||
176349 nlbhcf.vpn
|
||||
286577 zft.gds
|
||||
$ cd ..
|
||||
$ cd sqscdjlj
|
||||
$ ls
|
||||
128776 gnh
|
||||
dir qbdpvcbt
|
||||
284505 qlsn.vdq
|
||||
$ cd qbdpvcbt
|
||||
$ ls
|
||||
280709 crv.hgm
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd ssf
|
||||
$ ls
|
||||
13328 djfww.pjn
|
||||
19971 hvfvt
|
||||
dir zft
|
||||
$ cd zft
|
||||
$ ls
|
||||
97761 dnmnz
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd djfww
|
||||
$ ls
|
||||
109590 bwfnnf.wpd
|
||||
297297 cmht.ljg
|
||||
280726 hvfvt
|
||||
$ cd ..
|
||||
$ cd drdf
|
||||
$ ls
|
||||
56764 pwgswq.fld
|
||||
300547 wqqm
|
||||
210698 zrtm.jvq
|
||||
$ cd ..
|
||||
$ cd fgbqtjlj
|
||||
$ ls
|
||||
22217 vrmgsz.ctg
|
||||
$ cd ..
|
||||
$ cd hjsmmj
|
||||
$ ls
|
||||
232911 bcqrmp.czf
|
||||
164656 hcqbmwc.gts
|
||||
dir jql
|
||||
dir ntd
|
||||
dir prgm
|
||||
dir psfvhh
|
||||
dir zft
|
||||
$ cd jql
|
||||
$ ls
|
||||
212767 zhnhn.lzm
|
||||
dir zrtm
|
||||
$ cd zrtm
|
||||
$ ls
|
||||
35950 bcqrmp.czf
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd ntd
|
||||
$ ls
|
||||
dir vml
|
||||
$ cd vml
|
||||
$ ls
|
||||
60833 bcqrmp.czf
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd prgm
|
||||
$ ls
|
||||
316166 pwgswq.fld
|
||||
$ cd ..
|
||||
$ cd psfvhh
|
||||
$ ls
|
||||
152195 pwgswq.fld
|
||||
92448 qlqqmndd.zcb
|
||||
$ cd ..
|
||||
$ cd zft
|
||||
$ ls
|
||||
95808 hpq.hgm
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd msptbrl
|
||||
$ ls
|
||||
256069 hpq.hgm
|
||||
$ cd ..
|
||||
$ cd slpc
|
||||
$ ls
|
||||
dir djfww
|
||||
285380 djfww.gcm
|
||||
169898 hcqbmwc.gts
|
||||
40914 mnpnhpz
|
||||
188062 pwgswq.fld
|
||||
dir zrtm
|
||||
$ cd djfww
|
||||
$ ls
|
||||
94935 pwgswq.fld
|
||||
70655 qlqqmndd.zcb
|
||||
48528 zft.qvh
|
||||
$ cd ..
|
||||
$ cd zrtm
|
||||
$ ls
|
||||
160137 hcqbmwc.gts
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd hvfvt
|
||||
$ ls
|
||||
dir cslthslv
|
||||
129407 prwq
|
||||
dir vrzfbtt
|
||||
$ cd cslthslv
|
||||
$ ls
|
||||
dir cpcfcc
|
||||
158361 hcqbmwc.gts
|
||||
$ cd cpcfcc
|
||||
$ ls
|
||||
dir zpgnczq
|
||||
$ cd zpgnczq
|
||||
$ ls
|
||||
158414 zft
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd vrzfbtt
|
||||
$ ls
|
||||
185263 nqvvl
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd phwgv
|
||||
$ ls
|
||||
253690 bzpcj.fcj
|
||||
dir wtbr
|
||||
168025 zdsh.tnq
|
||||
157840 zsdfqb.zbd
|
||||
$ cd wtbr
|
||||
$ ls
|
||||
dir lvgdb
|
||||
$ cd lvgdb
|
||||
$ ls
|
||||
177751 cpcfcc.dzr
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd svw
|
||||
$ ls
|
||||
dir cpcfcc
|
||||
189430 hpq.hgm
|
||||
dir ntzbj
|
||||
13384 qlqqmndd.zcb
|
||||
10333 wdvqhwgl.trq
|
||||
161318 zwzp.jsn
|
||||
$ cd cpcfcc
|
||||
$ ls
|
||||
298999 hcqbmwc.gts
|
||||
290883 hpq.hgm
|
||||
dir qlnntp
|
||||
dir vpshs
|
||||
5547 wlrmg.bpc
|
||||
dir zft
|
||||
$ cd qlnntp
|
||||
$ ls
|
||||
168562 nqds.tqn
|
||||
$ cd ..
|
||||
$ cd vpshs
|
||||
$ ls
|
||||
246400 pwgswq.fld
|
||||
$ cd ..
|
||||
$ cd zft
|
||||
$ ls
|
||||
235634 hvfvt.hst
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd ntzbj
|
||||
$ ls
|
||||
98777 qlqqmndd.zcb
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd zft
|
||||
$ ls
|
||||
dir dhnzm
|
||||
299292 hvfvt.pvb
|
||||
dir ltfb
|
||||
dir mrvsjgsq
|
||||
dir ntr
|
||||
dir swmvhgd
|
||||
dir zrtm
|
||||
$ cd dhnzm
|
||||
$ ls
|
||||
267041 bbsj
|
||||
$ cd ..
|
||||
$ cd ltfb
|
||||
$ ls
|
||||
242136 bcqrmp.czf
|
||||
314862 dgdz
|
||||
203160 hcqbmwc.gts
|
||||
80422 hgvz
|
||||
dir qftjfqfv
|
||||
180815 sstl.wzg
|
||||
dir wmhm
|
||||
dir zft
|
||||
dir zszp
|
||||
$ cd qftjfqfv
|
||||
$ ls
|
||||
dir bmmw
|
||||
$ cd bmmw
|
||||
$ ls
|
||||
dir hvfvt
|
||||
318039 hvfvt.whc
|
||||
17057 pwgswq.fld
|
||||
$ cd hvfvt
|
||||
$ ls
|
||||
170348 brplf.wgv
|
||||
156783 hcqbmwc.gts
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd wmhm
|
||||
$ ls
|
||||
178474 bcqrmp.czf
|
||||
dir cmsgv
|
||||
dir dcfvrtj
|
||||
225393 htjflrs.tlm
|
||||
dir hvfvt
|
||||
dir nlrs
|
||||
273173 nsmdd.glc
|
||||
151259 pwgswq.fld
|
||||
dir ztqvwjr
|
||||
$ cd cmsgv
|
||||
$ ls
|
||||
dir flgjbjg
|
||||
$ cd flgjbjg
|
||||
$ ls
|
||||
13971 cpcfcc
|
||||
20601 qlqqmndd.zcb
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd dcfvrtj
|
||||
$ ls
|
||||
141992 djfww.djn
|
||||
118149 hpq.hgm
|
||||
dir qrmqslq
|
||||
$ cd qrmqslq
|
||||
$ ls
|
||||
105940 zrtm.vql
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd hvfvt
|
||||
$ ls
|
||||
181962 hpq.hgm
|
||||
$ cd ..
|
||||
$ cd nlrs
|
||||
$ ls
|
||||
82705 vnfwjf.hhl
|
||||
$ cd ..
|
||||
$ cd ztqvwjr
|
||||
$ ls
|
||||
98257 pwgswq.fld
|
||||
83864 scv.pbp
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd zft
|
||||
$ ls
|
||||
183072 rsbfsl.zsj
|
||||
$ cd ..
|
||||
$ cd zszp
|
||||
$ ls
|
||||
dir hvfvt
|
||||
$ cd hvfvt
|
||||
$ ls
|
||||
dir djfww
|
||||
dir dqdtgjtg
|
||||
dir hvfvt
|
||||
$ cd djfww
|
||||
$ ls
|
||||
117037 rnmbsq.zph
|
||||
259243 zrtm.znf
|
||||
$ cd ..
|
||||
$ cd dqdtgjtg
|
||||
$ ls
|
||||
dir lrbsvng
|
||||
59301 zft
|
||||
$ cd lrbsvng
|
||||
$ ls
|
||||
46301 bcqrmp.czf
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd hvfvt
|
||||
$ ls
|
||||
223277 qlqqmndd.zcb
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd mrvsjgsq
|
||||
$ ls
|
||||
160189 cpcfcc
|
||||
dir lzqf
|
||||
232626 pwgswq.fld
|
||||
dir rpmfcg
|
||||
$ cd lzqf
|
||||
$ ls
|
||||
135552 bcqrmp.czf
|
||||
48083 qlqqmndd.zcb
|
||||
dir rbg
|
||||
229086 rdswb.cjz
|
||||
204486 spbwfrwf.cmj
|
||||
$ cd rbg
|
||||
$ ls
|
||||
dir sjdwsbqq
|
||||
$ cd sjdwsbqq
|
||||
$ ls
|
||||
270621 rhv.shw
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd rpmfcg
|
||||
$ ls
|
||||
227216 bld.jtn
|
||||
dir zft
|
||||
$ cd zft
|
||||
$ ls
|
||||
43056 vzc
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd ntr
|
||||
$ ls
|
||||
dir cmtnqb
|
||||
dir djfww
|
||||
195371 wffvmql.lrv
|
||||
$ cd cmtnqb
|
||||
$ ls
|
||||
135380 pbng.vhq
|
||||
$ cd ..
|
||||
$ cd djfww
|
||||
$ ls
|
||||
dir fmvrrrq
|
||||
dir mbhrbss
|
||||
dir zrtm
|
||||
$ cd fmvrrrq
|
||||
$ ls
|
||||
dir cpcfcc
|
||||
79110 djfww
|
||||
300581 ftcdj.wcc
|
||||
$ cd cpcfcc
|
||||
$ ls
|
||||
234211 zsgsm
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd mbhrbss
|
||||
$ ls
|
||||
149184 djfww.gwh
|
||||
185815 rhgw.rmj
|
||||
$ cd ..
|
||||
$ cd zrtm
|
||||
$ ls
|
||||
dir zft
|
||||
$ cd zft
|
||||
$ ls
|
||||
310043 bnwvt.fbg
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd swmvhgd
|
||||
$ ls
|
||||
77547 djfww.jwr
|
||||
318547 drggg
|
||||
300962 pwgswq.fld
|
||||
$ cd ..
|
||||
$ cd zrtm
|
||||
$ ls
|
||||
229319 bflnffjj
|
||||
dir djfww
|
||||
142526 hvfvt
|
||||
232722 jprrf
|
||||
94024 ndmf.hdr
|
||||
dir vhdhn
|
||||
$ cd djfww
|
||||
$ ls
|
||||
30770 bcqrmp.czf
|
||||
$ cd ..
|
||||
$ cd vhdhn
|
||||
$ ls
|
||||
dir djfww
|
||||
48261 djfww.frg
|
||||
dir gqc
|
||||
316163 qlqqmndd.zcb
|
||||
$ cd djfww
|
||||
$ ls
|
||||
104095 cvjlthn.cfl
|
||||
223454 hgqwzh
|
||||
24715 pwgswq.fld
|
||||
283499 qlqqmndd.zcb
|
||||
dir zft
|
||||
224574 zlnwn
|
||||
$ cd zft
|
||||
$ ls
|
||||
100941 pwgswq.fld
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd gqc
|
||||
$ ls
|
||||
156273 wpgwrdl
|
||||
111
2022/day08/Makefile
Normal file
111
2022/day08/Makefile
Normal file
@@ -0,0 +1,111 @@
|
||||
# AOC daily Makefile - GNU make only.
|
||||
#
|
||||
# Copyright (C) 2021-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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
#
|
||||
|
||||
INPUT := input/input.txt
|
||||
SHELL := /bin/bash
|
||||
|
||||
CC := gcc
|
||||
BEAR := bear
|
||||
CCLSFILE:= compile_commands.json
|
||||
|
||||
LIB := aoc_$(shell uname -m)
|
||||
INCDIR := ../include
|
||||
LIBDIR := ../lib
|
||||
LDFLAGS := -L$(LIBDIR)
|
||||
#LDLIB := -l$(LIB) -lm
|
||||
LDLIB := -l$(LIB)
|
||||
|
||||
export LD_LIBRARY_PATH = $(LIBDIR)
|
||||
|
||||
CFLAGS += -std=gnu11
|
||||
CFLAGS += -O2
|
||||
CFLAGS += -g
|
||||
# for gprof
|
||||
# CFLAGS += -pg
|
||||
CFLAGS += -Wall
|
||||
CFLAGS += -Wextra
|
||||
CFLAGS += -march=native
|
||||
# Next one may be useful for valgrind (some invalid instructions)
|
||||
# CFLAGS += -mno-tbm
|
||||
CFLAGS += -Wmissing-declarations
|
||||
CFLAGS += -Wno-unused-result
|
||||
|
||||
CFLAGS += -DDEBUG_DEBUG # activate general debug (debug.c)
|
||||
CFLAGS += -DDEBUG_POOL # memory pools management
|
||||
|
||||
VALGRIND := valgrind
|
||||
VALGRINDFLAGS := --leak-check=full --show-leak-kinds=all --track-origins=yes \
|
||||
--sigill-diagnostics=yes --quiet --show-error-list=yes
|
||||
|
||||
|
||||
TIME := \time -f "\ttime: %E real, %U user, %S sys\n\tcontext-switch:\t%c+%w, page-faults: %F+%R\n"
|
||||
export PATH := .:$(PATH)
|
||||
|
||||
.PHONY: clean all compile assembly memcheck memcheck1 memcheck2 part1 part2 ccls bear org
|
||||
|
||||
all: README.org ccls part1 part2
|
||||
|
||||
memcheck: memcheck1 memcheck2
|
||||
|
||||
memcheck1: aoc-c
|
||||
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 1 < $(INPUT)
|
||||
|
||||
memcheck2: aoc-c
|
||||
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 2 < $(INPUT)
|
||||
@#@valgrind -s --track-origins=yes aoc-c -p 2 < $(INPUT)
|
||||
|
||||
compile: aoc-c
|
||||
|
||||
cpp: aoc-c.i
|
||||
|
||||
assembly: aoc-c.s
|
||||
|
||||
part1: aoc-c
|
||||
@$(TIME) aoc.bash -p 1 < $(INPUT) 2>&1
|
||||
@$(TIME) aoc-c -p 1 < $(INPUT)
|
||||
|
||||
part2: aoc-c
|
||||
@$(TIME) aoc.bash -p 2 < $(INPUT) 2>&1
|
||||
@$(TIME) aoc-c -p 2 < $(INPUT)
|
||||
|
||||
ccls: $(CCLSFILE)
|
||||
|
||||
clean:
|
||||
@rm -f aoc-c core* vgcore* gmon.out aoc-c.s aoc-c.i README.html compile_commands.json
|
||||
|
||||
aoc-c: aoc-c.c common.c
|
||||
@echo compiling $<
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -I $(INCDIR) $^ $(LDLIB) -o $@
|
||||
|
||||
# generate pre-processed file (.i) and assembler (.s)
|
||||
%.i: %.c
|
||||
@echo generating $@
|
||||
@$(CC) -E $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||
|
||||
%.s: %.c
|
||||
@echo generating $@
|
||||
@$(CC) -S -fverbose-asm $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||
|
||||
# generate README.org from README.html (must cleanup !)
|
||||
org: README.org
|
||||
|
||||
%.org: %.html
|
||||
@echo generating $@. Cleanup before commit !
|
||||
@pandoc $< -o $@
|
||||
|
||||
# generate compile_commands.json
|
||||
$(CCLSFILE): aoc-c.c Makefile
|
||||
$(BEAR) -- make clean compile
|
||||
|
||||
bear: clean
|
||||
@touch .ccls-root
|
||||
@$(BEAR) -- make compile
|
||||
122
2022/day08/README.org
Normal file
122
2022/day08/README.org
Normal file
@@ -0,0 +1,122 @@
|
||||
** --- Day 8: Treetop Tree House ---
|
||||
The expedition comes across a peculiar patch of tall trees all planted
|
||||
carefully in a grid. The Elves explain that a previous expedition
|
||||
planted these trees as a reforestation effort. Now, they're curious if
|
||||
this would be a good location for a
|
||||
[[https://en.wikipedia.org/wiki/Tree_house][tree house]].
|
||||
|
||||
First, determine whether there is enough tree cover here to keep a tree
|
||||
house /hidden/. To do this, you need to count the number of trees that
|
||||
are /visible from outside the grid/ when looking directly along a row or
|
||||
column.
|
||||
|
||||
The Elves have already launched a
|
||||
[[https://en.wikipedia.org/wiki/Quadcopter][quadcopter]] to generate a
|
||||
map with the height of each tree (your puzzle input). For example:
|
||||
|
||||
#+begin_example
|
||||
30373
|
||||
25512
|
||||
65332
|
||||
33549
|
||||
35390
|
||||
#+end_example
|
||||
|
||||
Each tree is represented as a single digit whose value is its height,
|
||||
where =0= is the shortest and =9= is the tallest.
|
||||
|
||||
A tree is /visible/ if all of the other trees between it and an edge of
|
||||
the grid are /shorter/ than it. Only consider trees in the same row or
|
||||
column; that is, only look up, down, left, or right from any given tree.
|
||||
|
||||
All of the trees around the edge of the grid are /visible/ - since they
|
||||
are already on the edge, there are no trees to block the view. In this
|
||||
example, that only leaves the /interior nine trees/ to consider:
|
||||
|
||||
- The top-left =5= is /visible/ from the left and top. (It isn't visible
|
||||
from the right or bottom since other trees of height =5= are in the
|
||||
way.)
|
||||
- The top-middle =5= is /visible/ from the top and right.
|
||||
- The top-right =1= is not visible from any direction; for it to be
|
||||
visible, there would need to only be trees of height /0/ between it
|
||||
and an edge.
|
||||
- The left-middle =5= is /visible/, but only from the right.
|
||||
- The center =3= is not visible from any direction; for it to be
|
||||
visible, there would need to be only trees of at most height =2=
|
||||
between it and an edge.
|
||||
- The right-middle =3= is /visible/ from the right.
|
||||
- In the bottom row, the middle =5= is /visible/, but the =3= and =4=
|
||||
are not.
|
||||
|
||||
With 16 trees visible on the edge and another 5 visible in the interior,
|
||||
a total of =21= trees are visible in this arrangement.
|
||||
|
||||
Consider your map; /how many trees are visible from outside the grid?/
|
||||
|
||||
Your puzzle answer was =1698=.
|
||||
|
||||
** --- Part Two ---
|
||||
Content with the amount of tree cover available, the Elves just need to
|
||||
know the best spot to build their tree house: they would like to be able
|
||||
to see a lot of /trees/.
|
||||
|
||||
To measure the viewing distance from a given tree, look up, down, left,
|
||||
and right from that tree; stop if you reach an edge or at the first tree
|
||||
that is the same height or taller than the tree under consideration. (If
|
||||
a tree is right on the edge, at least one of its viewing distances will
|
||||
be zero.)
|
||||
|
||||
The Elves don't care about distant trees taller than those found by the
|
||||
rules above; the proposed tree house has large
|
||||
[[https://en.wikipedia.org/wiki/Eaves][eaves]] to keep it dry, so they
|
||||
wouldn't be able to see higher than the tree house anyway.
|
||||
|
||||
In the example above, consider the middle =5= in the second row:
|
||||
|
||||
#+begin_example
|
||||
30373
|
||||
25512
|
||||
65332
|
||||
33549
|
||||
35390
|
||||
#+end_example
|
||||
|
||||
- Looking up, its view is not blocked; it can see =1= tree (of height
|
||||
=3=).
|
||||
- Looking left, its view is blocked immediately; it can see only =1=
|
||||
tree (of height =5=, right next to it).
|
||||
- Looking right, its view is not blocked; it can see =2= trees.
|
||||
- Looking down, its view is blocked eventually; it can see =2= trees
|
||||
(one of height =3=, then the tree of height =5= that blocks its view).
|
||||
|
||||
A tree's /scenic score/ is found by /multiplying together/ its viewing
|
||||
distance in each of the four directions. For this tree, this is =4=
|
||||
(found by multiplying =1 * 1 * 2 * 2=).
|
||||
|
||||
However, you can do even better: consider the tree of height =5= in the
|
||||
middle of the fourth row:
|
||||
|
||||
#+begin_example
|
||||
30373
|
||||
25512
|
||||
65332
|
||||
33549
|
||||
35390
|
||||
#+end_example
|
||||
|
||||
- Looking up, its view is blocked at =2= trees (by another tree with a
|
||||
height of =5=).
|
||||
- Looking left, its view is not blocked; it can see =2= trees.
|
||||
- Looking down, its view is also not blocked; it can see =1= tree.
|
||||
- Looking right, its view is blocked at =2= trees (by a massive tree of
|
||||
height =9=).
|
||||
|
||||
This tree's scenic score is =8= (=2 * 2 * 1 * 2=); this is the ideal
|
||||
spot for the tree house.
|
||||
|
||||
Consider each tree on your map. /What is the highest scenic score
|
||||
possible for any tree?/
|
||||
|
||||
Your puzzle answer was =672280=.
|
||||
|
||||
Both parts of this puzzle are complete! They provide two gold stars: **
|
||||
159
2022/day08/aoc-c.c
Normal file
159
2022/day08/aoc-c.c
Normal file
@@ -0,0 +1,159 @@
|
||||
/* aoc-c.c: Advent of Code 2022, day 8
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "bits.h"
|
||||
#include "aoc.h"
|
||||
|
||||
typedef struct tree {
|
||||
u16 size;
|
||||
char *h; /* heigts */
|
||||
char *v; /* visible (part 1) */
|
||||
} tree_t;
|
||||
|
||||
#define HEIGHT(t, x, y) (((t)->h[((t)->size * (y)) + (x)]))
|
||||
#define VISIBLE(t, x, y) (((t)->v[((t)->size * (y)) + (x)]))
|
||||
|
||||
static tree_t *parse(tree_t *trees)
|
||||
{
|
||||
size_t alloc = 0;
|
||||
char *buf = NULL;
|
||||
ssize_t buflen;
|
||||
|
||||
buflen = getline(&buf, &alloc, stdin);
|
||||
buf[--buflen] = 0;
|
||||
trees->size = buflen;
|
||||
trees->h = malloc((buflen * buflen) * sizeof(char) + 1);
|
||||
memcpy(trees->h, buf, buflen); /* store first line */
|
||||
free(buf);
|
||||
|
||||
for (buf = trees->h + buflen; ; buf += buflen) {
|
||||
if (scanf("%s", buf) <= 0)
|
||||
break;
|
||||
}
|
||||
trees->v = calloc(buflen * buflen, sizeof (char));
|
||||
return trees;
|
||||
}
|
||||
|
||||
static int visible(tree_t *t, int *max, int x, int y)
|
||||
{
|
||||
int h = HEIGHT(t, x, y);
|
||||
if (h > *max) {
|
||||
VISIBLE(t, x, y) = 1;
|
||||
if ((*max = h) == '9') {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int check_tree(tree_t *t, int x, int y)
|
||||
{
|
||||
int i, h = HEIGHT(t, x, y), res = 1, size = t->size, tmp;
|
||||
|
||||
for (tmp = 0, i = x + 1; i < size ; ++i) { /* east */
|
||||
tmp++;
|
||||
if (HEIGHT(t, i, y) >= h)
|
||||
break;
|
||||
}
|
||||
res *= tmp;
|
||||
for (tmp = 0, i = x - 1; i >= 0; --i) { /* west */
|
||||
tmp++;
|
||||
if (HEIGHT(t, i, y) >= h)
|
||||
break;
|
||||
}
|
||||
res *= tmp;
|
||||
for (tmp = 0, i = y + 1; i < size; ++i) { /* south */
|
||||
tmp++;
|
||||
if (HEIGHT(t, x, i) >= h)
|
||||
break;
|
||||
}
|
||||
res *= tmp;
|
||||
for (tmp = 0, i = y - 1; i >= 0; --i) { /* north */
|
||||
tmp++;
|
||||
if (HEIGHT(t, x, i) >= h)
|
||||
break;
|
||||
}
|
||||
res *= tmp;
|
||||
return res;
|
||||
}
|
||||
|
||||
static int part1(tree_t *t)
|
||||
{
|
||||
int x, y, max, res = 0, size = t->size;
|
||||
|
||||
for (y = 1; y < size -1; ++y) { /* to east */
|
||||
if ((max = HEIGHT(t, 0, y)) < '9') {
|
||||
for (x = 1; x < size -1; ++x) {
|
||||
if (visible (t, &max, x, y))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (y = 1; y < size -1; ++y) { /* to west */
|
||||
if ((max = HEIGHT(t, size - 1, y)) < '9') {
|
||||
for (x = size - 2; x > 0; --x) {
|
||||
if (visible (t, &max, x, y)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (x = 1; x < size -1; ++x) { /* to south */
|
||||
if ((max = HEIGHT(t, x, 0)) < '9') {
|
||||
for (y = 1; y < size -1; ++y) {
|
||||
if (visible (t, &max, x, y))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (x = 1; x < size -1; ++x) { /* to north */
|
||||
if ((max = HEIGHT(t, x, size - 1)) < '9') {
|
||||
for (y = size - 2; y > 0; --y) {
|
||||
if (visible (t, &max, x, y))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (y = 0; y < size; ++y)
|
||||
for (x = 0; x < size; ++x)
|
||||
if (VISIBLE(t, x, y))
|
||||
res++;
|
||||
return res + size * 4 - 4;
|
||||
}
|
||||
|
||||
static int part2(tree_t *t)
|
||||
{
|
||||
int res = 0, tmp, size = t->size;
|
||||
|
||||
for (int y = 1; y < size - 1; ++y) {
|
||||
for (int x = 1; x < size - 1; ++x) {
|
||||
tmp = check_tree(t, x, y);
|
||||
if (tmp > res)
|
||||
res = tmp;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int main(int ac, char **av)
|
||||
{
|
||||
int part = parseargs(ac, av);
|
||||
tree_t trees;
|
||||
|
||||
parse(&trees);
|
||||
printf("%s: res=%d\n", *av, part == 1? part1(&trees): part2(&trees));
|
||||
exit(0);
|
||||
}
|
||||
135
2022/day08/aoc.bash
Executable file
135
2022/day08/aoc.bash
Executable file
@@ -0,0 +1,135 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# aoc.bash: Advent of Code 2022, day 8
|
||||
#
|
||||
# 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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
|
||||
. common.bash
|
||||
|
||||
declare -a trees=() # trees height
|
||||
declare -Ai visible=() # visible if set
|
||||
declare -i size
|
||||
|
||||
parse() {
|
||||
readarray -t trees
|
||||
size=${#trees[@]}
|
||||
}
|
||||
|
||||
# height - return height of a tree
|
||||
# $1: reference of return value
|
||||
# $2, $3: x, y
|
||||
# x is column, y is row
|
||||
height() {
|
||||
local -n _ret="$1"
|
||||
_ret=${trees[$3]:$2:1}
|
||||
}
|
||||
|
||||
check_visible() {
|
||||
local -n _max="$1"
|
||||
local -i _x="$2" _y="$3" _c
|
||||
|
||||
height _c "$x" "y"
|
||||
if (( _c > _max )); then
|
||||
(( visible[$x-$y]++, _max=_c ))
|
||||
(( _max == 9 )) && return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
part1() {
|
||||
declare -ig res
|
||||
local -i x y max
|
||||
|
||||
for ((y = 1; y < size -1; ++y)); do # to east
|
||||
height max 0 "$y"
|
||||
(( max == 9 )) && continue
|
||||
for ((x = 1; x < size -1; ++x)); do
|
||||
check_visible max "$x" "$y" || break
|
||||
done
|
||||
done
|
||||
for ((y = 1; y < size -1; ++y)); do # to west
|
||||
height max $((size - 1)) "$y"
|
||||
(( max == 9 )) && continue
|
||||
for ((x = size - 2; x > 0; --x)); do
|
||||
check_visible max "$x" "$y" || break
|
||||
done
|
||||
done
|
||||
for ((x = 1; x < size -1; ++x)); do # to south
|
||||
height max "$x" 0
|
||||
(( max == 9 )) && continue
|
||||
for ((y = 1; y < size -1; ++y)); do
|
||||
check_visible max "$x" "$y" || break
|
||||
done
|
||||
done
|
||||
for ((x = 1; x < size -1; ++x)); do # to north
|
||||
height max "$x" $((size - 1))
|
||||
(( max == 9 )) && continue
|
||||
for ((y = size - 2; y > 0; --y)); do
|
||||
check_visible max "$x" "$y" || break
|
||||
done
|
||||
done
|
||||
(( res = ${#visible[@]} + size * 4 - 4 ))
|
||||
}
|
||||
|
||||
check_tree() {
|
||||
local -n res=$1
|
||||
local -i X="$2" Y="$3" c x y h
|
||||
local -ai vis=()
|
||||
|
||||
height h "$X" "$Y"
|
||||
for ((x = X + 1; x < size ; ++x)); do # east
|
||||
height c "$x" "Y"
|
||||
(( vis[0]++ ))
|
||||
((c >= h)) && break
|
||||
done
|
||||
for ((x = X - 1; x >= 0; --x)); do # west
|
||||
height c "$x" "Y"
|
||||
(( vis[1]++ ))
|
||||
((c >= h)) && break
|
||||
done
|
||||
for ((y = Y + 1; y < size; ++y)); do # south
|
||||
height c "$X" "$y"
|
||||
(( vis[2]++ ))
|
||||
((c >= h)) && break
|
||||
done
|
||||
for ((y = Y - 1; y >= 0; --y)); do # north
|
||||
height c "$X" "$y"
|
||||
(( vis[3]++ ))
|
||||
((c >= h)) && break
|
||||
done
|
||||
# shellcheck disable=1102
|
||||
res=$(( "${vis[@]/%/ *}" 1))
|
||||
}
|
||||
|
||||
|
||||
part2() {
|
||||
local -ig res=0
|
||||
local -i tmp=1 x y
|
||||
|
||||
for ((x = 1; x < size - 1; ++x)); do
|
||||
for ((y = 1; y < size - 1; ++y)); do
|
||||
check_tree tmp "$x" "$y"
|
||||
if ((tmp > res)); then
|
||||
((res = tmp))
|
||||
fi
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
solve() {
|
||||
if ((part == 1)); then
|
||||
part1
|
||||
else
|
||||
part2
|
||||
fi
|
||||
}
|
||||
|
||||
main "$@"
|
||||
exit 0
|
||||
17
2022/day08/aoc.h
Normal file
17
2022/day08/aoc.h
Normal file
@@ -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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
#ifndef _AOC_H_
|
||||
#define _AOC_H_
|
||||
|
||||
extern int parseargs(int ac, char**av);
|
||||
|
||||
#endif /* _AOC_H_ */
|
||||
68
2022/day08/common.bash
Executable file
68
2022/day08/common.bash
Executable file
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# common.bash: Advent of Code 2022, common bash 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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
|
||||
# shellcheck disable=2034
|
||||
export cmdname=${0##*/}
|
||||
export debug=0
|
||||
export res
|
||||
export LANG=C
|
||||
|
||||
shopt -s extglob
|
||||
set -o noglob
|
||||
|
||||
usage() {
|
||||
printf "usage: %s [-d DEBUG] [-p PART]\n" "$cmdname"
|
||||
exit 1
|
||||
}
|
||||
|
||||
checkargs() {
|
||||
local part=1
|
||||
while getopts p:d: todo; do
|
||||
case "$todo" in
|
||||
d)
|
||||
if [[ "$OPTARG" =~ ^[[:digit:]+]$ ]]; then
|
||||
debug="$OPTARG"
|
||||
else
|
||||
printf "%s: illegal [%s] debug level.\n" "$CMD" "$OPTARG"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
p)
|
||||
if [[ "$OPTARG" =~ ^[12]$ ]]; then
|
||||
part="$OPTARG"
|
||||
else
|
||||
printf "%s: illegal [%s] part.\n" "$CMD" "$OPTARG"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
# Now check remaining argument (backup directory)
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
(( $# > 1 )) && usage
|
||||
return "$part"
|
||||
}
|
||||
|
||||
main() {
|
||||
local -i part
|
||||
|
||||
checkargs "$@"
|
||||
part=$?
|
||||
parse "$part"
|
||||
solve "$part"
|
||||
printf "%s: res=%s\n" "$cmdname" "$res"
|
||||
}
|
||||
49
2022/day08/common.c
Normal file
49
2022/day08/common.c
Normal file
@@ -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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
5
2022/day08/input/example.txt
Normal file
5
2022/day08/input/example.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
30373
|
||||
25512
|
||||
65332
|
||||
33549
|
||||
35390
|
||||
99
2022/day08/input/input.txt
Normal file
99
2022/day08/input/input.txt
Normal file
@@ -0,0 +1,99 @@
|
||||
002100030222341303232115221524311502200403234452204125251345024423544443305142410110142101223120110
|
||||
102030322341143330244233013052025453422005415304655426206452251310214055314024034341233110302320003
|
||||
003012203404011430120134554314552441635001641050211406204621114102021543144514102510421243314102033
|
||||
330313423002034140035001210441156554545625042262651356556544202500446121455112434243313013430141203
|
||||
331203121131230002055113430244610062654034520106363462155201210355601153542301323442223310134324300
|
||||
232201231021003254355411402310326206625011564114125202263504451451212600155351424154310240411213431
|
||||
033033333301011523544023206136145505304224325606020360006206455564513553512054354124523232201230441
|
||||
132201032234334044251334220345360402456541662253556375754662323265201641514121105025300453041111234
|
||||
314322341322104402235020206565044225363527617767574524475421763504341061551154250344125514014234344
|
||||
101323043023430543342440532324326413655657527215661116623455613664321005134300223542510253102211310
|
||||
320404242514122111525043444530625417656773117247512712444315767422412130351505513231104322032421303
|
||||
221204123205133142044056245654205231734371546616753217321556472223654044043612554152141554333102034
|
||||
340310155225452152216635634352712541366312326272262143522347111166646736001360102010220214000133002
|
||||
012404003515002416422500163244271366252711531615333437352461454777311142132000140205630042305222013
|
||||
332434552302203445503543424523327464362526657251687634745536521746523154717531643250132300541053000
|
||||
020130312425316362611130462217125425435545265467725256332777233137141524314631100051153314314343032
|
||||
112115124512002346011342433146124542356845483862756322785545283652723747276776403131622540014001524
|
||||
332354013101003031053022245431274627654677343638672643442563448782737464337546541546630431125021330
|
||||
220315320142064161406534365262377268373743527784575246325564676238816733767331345114363612344051535
|
||||
102041153526000601402325625766534543527882476653366727573448727775677146365732431425225562043130034
|
||||
350054114310533002426654125166575285757827422257872378766383267543484865317252532765440216543555512
|
||||
222440404353016144747347457368562668586285847553578732435887584463446862116134751240360645225435344
|
||||
554234546163262630313431762248876668663352436888374587856263343842526635237314231451062036605442520
|
||||
525531324662660356256614344438373575732699988366775989976447384338336827686445577222030363631240512
|
||||
055541261042533424177375756738443482846986979788978997559377679255463858237757327464422026230510130
|
||||
514123221240250442457744728347386637684953574546455344754548333793233865436751231314653541223102202
|
||||
355454250661114645144551785724753237378345375493453967559796675839837444334776625552412552302431302
|
||||
202445234333206767744653874724276586973668878949653473947686567565487325864733735677672241416513452
|
||||
445415223211061633767433865252483574744685974593334963668983745643354885658423263536531213102544202
|
||||
201405464251164654177385783224666473975674643767946648464678958969336335638578275154116223152222102
|
||||
401423140356441654745572266848965593553995667644648964747884544439493545472454437715336645303346422
|
||||
154440323240741427732867467564957336394985859766644495658985963583496399736552632162756445212536404
|
||||
441663663062661372122867364584655388977474857585778686889578799644949733463423826715534215154065204
|
||||
422036122016243651174663588693898583374968974778579585977478599643389537573534354622377452555411315
|
||||
430412403362272513348763673566578945645997454758694486758844958569786758359475575577532661126532300
|
||||
503653020441267422765353469867998339764449596776968996449777464644846938866332635583727771665263026
|
||||
006252631541331635768754753357384754988659585857956567666645975599653466655333342485345762600032403
|
||||
215205542775713732868842389885585646884858449858579777975997584997463698339932263363162431251615251
|
||||
342224450731115175762626546538955447796468885776778879697695699945446388444478355347827635732006646
|
||||
045011110226211633623658548365544498466468766878699597655897586488555435934935526883851537736604133
|
||||
440352212243431376382869634434568447654566895897796875679759667598898849334873844583742271767024403
|
||||
566632367121414762272448784755746799985759966559657989697977677955455754549393784586875275341562621
|
||||
004131167135757426882464486773699786789959957795985595559587775554479945637849747667752242212324244
|
||||
022411031432724262533554794664597446479869568767598899669969588984864457535986725263473577457413134
|
||||
036415005331162527346577487593798458668976888776888766856699598847776567686579476836656723623111342
|
||||
504001302331545267684439554776894957999788577876688969865558955547965687556849786463457244355044511
|
||||
464266074264126575276833864784546697885788878967966988678696686685576789843676844576623242451411411
|
||||
660130573642326366362654785549676574587876888769689696798799988678648554635745724364273772474666502
|
||||
413511521313437652422664948645649566979966676679778669968777776786958464356797545247763267365643645
|
||||
455033174473274564484285387995879595555686569997977698868769855686564847593489668858847744131410225
|
||||
560316675532344635443349663994499869866598568889798868967976679655597494679336978524332246567265361
|
||||
121053163342234352453837754569968465557968697766766888969966667796479457384444468264837376474515455
|
||||
604062313527642634768255846899648545559665886668966887999959659769978495794795825775373713613231451
|
||||
041031112622754332842439776736966994677888699898679988967779696758849589365579766676242256227420364
|
||||
630161363126476778455475799658545955598576568877768698668579988799596866465635488284555252726211044
|
||||
455563641427127283364758796475975894658677688789777769876667978747955677573575525588444241765111511
|
||||
256420063532645225542863884958844496596759999769769687678888788875449888945958948378756476127155054
|
||||
523256165217547362636325547686549767698957967985968987897777685866576744344388256886854362647342110
|
||||
205224606764556763544234874676659474468968576879668558856675855668779847849738247387744421321145610
|
||||
022651355615653552468486676459694744747575877656886776677858584988944678787576556747724125467333305
|
||||
526313424324717126486746644643397589664468865599858886996669788566489473798387676766873216657521426
|
||||
426530404522411762572567697375959747975669667958685679878659587764977658398697353283563215312244014
|
||||
023510245741131775436864579684699874979976567776557765866775469587757498544476554753722641656303654
|
||||
211341433442225414565332887899363678699495567888998675657659688744458493387343842346747477252626250
|
||||
406543152154335614758277748595836896786654948759999978569588555764838686653647362854723163226456101
|
||||
333640633617315535456525364849458558744656899855554897897568844446533866457545654847562377442214226
|
||||
040003053246534354438748723933365934878485997458955574785966996653353969666867276761661111124104550
|
||||
405602516206264365157378627495546935658594587869579958969686766986836687348285865231616336232000100
|
||||
304131030254233641578272475868953446545577766644956989679964489688554398956223433417637732661500540
|
||||
131164662225325441733366324345477954639475997658684766465487974699579665344326248136151472051130445
|
||||
452312154206174654138684277376889449945746954689646875777596486949365968888456226732332263263420000
|
||||
003010154551246223274282454345355673349967689986885795449989359633496728553885221437611730454554455
|
||||
131435126460017635544785754344874379695379366384573934357795398633967475353836864461424146264354142
|
||||
350154544045013352533173566257757787385448697484997454578735937499665628425542376452563635450224022
|
||||
302420224365163651765264446875287359533637498445639443969586466433384346337722662774436566624454214
|
||||
415242456321105173655733744886343826548944666338683876383973497998744488687446541256724244661531431
|
||||
155303206134314124372553618623857237346567857564464797593393675563536467777317174625640132203003240
|
||||
335521544652523624641575451785635352333587957647598535633948867838652636686573137515062356442045153
|
||||
235314500244636615342325346277256685653838226755493858683465683736283367654226655456541546644313125
|
||||
252520511531061305614364671212856473625642477732845278766573642425286572562373137446456005011330433
|
||||
241525455120116046543737642325543677623243884242534423327827446383376441727657314343125403632434002
|
||||
301045223551220356167117621755325772252845222546246588464784874685774676163655131632622146412415515
|
||||
011150133311336614251435416453632383454327534367288242328746537673543714263674263262001132354544412
|
||||
314104033000306256531666256433553535833538337463847277453476563227672715617272601302551120422305504
|
||||
104211442013141664402363645617163435245556228235337864656673626354151416721375243323635625100210424
|
||||
413422313502535362615054171511431775335574748526574728747453724472157632635263350024552502052340024
|
||||
131225301023304456424150404525765416565572272321835377167235317312551645334432406536160545434122120
|
||||
342131052232413325301451041516716541737346252413667115612642227312572433104525003114240240141232002
|
||||
244421101354005430232434420344323273421374225635551363463245561271743411452116466311034334101231020
|
||||
232404402304311415164151401553463731147111147752141732625152553615361046133341313265525232544143442
|
||||
201321033520133414312301326330253041267251614477322566645472656414545035321106361434351501123314104
|
||||
211232034442524242313453325046331353174352335422752364775746537513333534355120322320404054014303124
|
||||
224032233240430510135541652065052415154147565656231651653327511443424113100543020223335130010141400
|
||||
004110101133543440511523265424013341433043655022512172622140322434116104552043413352211021312421433
|
||||
000304433232402410151205333526613043463556021413402141634154404530112303306244402221312522221004042
|
||||
200204441020135232033032541516232550445221141520665016336536052063115335040344025054213324400312303
|
||||
300211022440310123055510053251505226452265556365100101014044645236505213550201425252404100302413231
|
||||
310312413210032422053242024243343060135340422313312403505631104430120233112324204414021331012401232
|
||||
132020341330304022053503522313342026211133610000020554213662244142551253124302245242110111033101203
|
||||
111
2022/day09/Makefile
Normal file
111
2022/day09/Makefile
Normal file
@@ -0,0 +1,111 @@
|
||||
# AOC daily Makefile - GNU make only.
|
||||
#
|
||||
# Copyright (C) 2021-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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
#
|
||||
|
||||
INPUT := input/input.txt
|
||||
SHELL := /bin/bash
|
||||
|
||||
CC := gcc
|
||||
BEAR := bear
|
||||
CCLSFILE:= compile_commands.json
|
||||
|
||||
LIB := aoc_$(shell uname -m)
|
||||
INCDIR := ../include
|
||||
LIBDIR := ../lib
|
||||
LDFLAGS := -L$(LIBDIR)
|
||||
#LDLIB := -l$(LIB) -lm
|
||||
LDLIB := -l$(LIB)
|
||||
|
||||
export LD_LIBRARY_PATH = $(LIBDIR)
|
||||
|
||||
CFLAGS += -std=gnu11
|
||||
CFLAGS += -O2
|
||||
CFLAGS += -g
|
||||
# for gprof
|
||||
# CFLAGS += -pg
|
||||
CFLAGS += -Wall
|
||||
CFLAGS += -Wextra
|
||||
CFLAGS += -march=native
|
||||
# Next one may be useful for valgrind (some invalid instructions)
|
||||
# CFLAGS += -mno-tbm
|
||||
CFLAGS += -Wmissing-declarations
|
||||
CFLAGS += -Wno-unused-result
|
||||
|
||||
CFLAGS += -DDEBUG_DEBUG # activate general debug (debug.c)
|
||||
CFLAGS += -DDEBUG_POOL # memory pools management
|
||||
|
||||
VALGRIND := valgrind
|
||||
VALGRINDFLAGS := --leak-check=full --show-leak-kinds=all --track-origins=yes \
|
||||
--sigill-diagnostics=yes --quiet --show-error-list=yes
|
||||
|
||||
|
||||
TIME := \time -f "\ttime: %E real, %U user, %S sys\n\tcontext-switch:\t%c+%w, page-faults: %F+%R\n"
|
||||
export PATH := .:$(PATH)
|
||||
|
||||
.PHONY: clean all compile assembly memcheck memcheck1 memcheck2 part1 part2 ccls bear org
|
||||
|
||||
all: README.org ccls part1 part2
|
||||
|
||||
memcheck: memcheck1 memcheck2
|
||||
|
||||
memcheck1: aoc-c
|
||||
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 1 < $(INPUT)
|
||||
|
||||
memcheck2: aoc-c
|
||||
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 2 < $(INPUT)
|
||||
@#@valgrind -s --track-origins=yes aoc-c -p 2 < $(INPUT)
|
||||
|
||||
compile: aoc-c
|
||||
|
||||
cpp: aoc-c.i
|
||||
|
||||
assembly: aoc-c.s
|
||||
|
||||
part1: aoc-c
|
||||
@$(TIME) aoc.bash -p 1 < $(INPUT) 2>&1
|
||||
@$(TIME) aoc-c -p 1 < $(INPUT)
|
||||
|
||||
part2: aoc-c
|
||||
@$(TIME) aoc.bash -p 2 < $(INPUT) 2>&1
|
||||
@$(TIME) aoc-c -p 2 < $(INPUT)
|
||||
|
||||
ccls: $(CCLSFILE)
|
||||
|
||||
clean:
|
||||
@rm -f aoc-c core* vgcore* gmon.out aoc-c.s aoc-c.i README.html compile_commands.json
|
||||
|
||||
aoc-c: aoc-c.c common.c
|
||||
@echo compiling $<
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -I $(INCDIR) $^ $(LDLIB) -o $@
|
||||
|
||||
# generate pre-processed file (.i) and assembler (.s)
|
||||
%.i: %.c
|
||||
@echo generating $@
|
||||
@$(CC) -E $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||
|
||||
%.s: %.c
|
||||
@echo generating $@
|
||||
@$(CC) -S -fverbose-asm $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||
|
||||
# generate README.org from README.html (must cleanup !)
|
||||
org: README.org
|
||||
|
||||
%.org: %.html
|
||||
@echo generating $@. Cleanup before commit !
|
||||
@pandoc $< -o $@
|
||||
|
||||
# generate compile_commands.json
|
||||
$(CCLSFILE): aoc-c.c Makefile
|
||||
$(BEAR) -- make clean compile
|
||||
|
||||
bear: clean
|
||||
@touch .ccls-root
|
||||
@$(BEAR) -- make compile
|
||||
747
2022/day09/README.org
Normal file
747
2022/day09/README.org
Normal file
@@ -0,0 +1,747 @@
|
||||
** --- Day 9: Rope Bridge ---
|
||||
This rope bridge creaks as you walk along it. You aren't sure how old it
|
||||
is, or whether it can even support your weight.
|
||||
|
||||
It seems to support the Elves just fine, though. The bridge spans a
|
||||
gorge which was carved out by the massive river far below you.
|
||||
|
||||
You step carefully; as you do, the ropes stretch and twist. You decide
|
||||
to distract yourself by modeling rope physics; maybe you can even figure
|
||||
out where /not/ to step.
|
||||
|
||||
Consider a rope with a knot at each end; these knots mark the /head/ and
|
||||
the /tail/ of the rope. If the head moves far enough away from the tail,
|
||||
the tail is pulled toward the head.
|
||||
|
||||
Due to nebulous reasoning involving
|
||||
[[https://en.wikipedia.org/wiki/Planck_units#Planck_length][Planck
|
||||
lengths]], you should be able to model the positions of the knots on a
|
||||
two-dimensional grid. Then, by following a hypothetical /series of
|
||||
motions/ (your puzzle input) for the head, you can determine how the
|
||||
tail will move.
|
||||
|
||||
Due to the aforementioned Planck lengths, the rope must be quite short;
|
||||
in fact, the head (=H=) and tail (=T=) must /always be touching/
|
||||
(diagonally adjacent and even overlapping both count as touching):
|
||||
|
||||
#+begin_example
|
||||
....
|
||||
.TH.
|
||||
....
|
||||
|
||||
....
|
||||
.H..
|
||||
..T.
|
||||
....
|
||||
|
||||
...
|
||||
.H. (H covers T)
|
||||
...
|
||||
#+end_example
|
||||
|
||||
If the head is ever two steps directly up, down, left, or right from the
|
||||
tail, the tail must also move one step in that direction so it remains
|
||||
close enough:
|
||||
|
||||
#+begin_example
|
||||
..... ..... .....
|
||||
.TH.. -> .T.H. -> ..TH.
|
||||
..... ..... .....
|
||||
|
||||
... ... ...
|
||||
.T. .T. ...
|
||||
.H. -> ... -> .T.
|
||||
... .H. .H.
|
||||
... ... ...
|
||||
#+end_example
|
||||
|
||||
Otherwise, if the head and tail aren't touching and aren't in the same
|
||||
row or column, the tail always moves one step diagonally to keep up:
|
||||
|
||||
#+begin_example
|
||||
..... ..... .....
|
||||
..... ..H.. ..H..
|
||||
..H.. -> ..... -> ..T..
|
||||
.T... .T... .....
|
||||
..... ..... .....
|
||||
|
||||
..... ..... .....
|
||||
..... ..... .....
|
||||
..H.. -> ...H. -> ..TH.
|
||||
.T... .T... .....
|
||||
..... ..... .....
|
||||
#+end_example
|
||||
|
||||
You just need to work out where the tail goes as the head follows a
|
||||
series of motions. Assume the head and the tail both start at the same
|
||||
position, overlapping.
|
||||
|
||||
For example:
|
||||
|
||||
#+begin_example
|
||||
R 4
|
||||
U 4
|
||||
L 3
|
||||
D 1
|
||||
R 4
|
||||
D 1
|
||||
L 5
|
||||
R 2
|
||||
#+end_example
|
||||
|
||||
This series of motions moves the head /right/ four steps, then /up/ four
|
||||
steps, then /left/ three steps, then /down/ one step, and so on. After
|
||||
each step, you'll need to update the position of the tail if the step
|
||||
means the head is no longer adjacent to the tail. Visually, these
|
||||
motions occur as follows (=s= marks the starting position as a reference
|
||||
point):
|
||||
|
||||
#+begin_example
|
||||
== Initial State ==
|
||||
|
||||
......
|
||||
......
|
||||
......
|
||||
......
|
||||
H..... (H covers T, s)
|
||||
|
||||
== R 4 ==
|
||||
|
||||
......
|
||||
......
|
||||
......
|
||||
......
|
||||
TH.... (T covers s)
|
||||
|
||||
......
|
||||
......
|
||||
......
|
||||
......
|
||||
sTH...
|
||||
|
||||
......
|
||||
......
|
||||
......
|
||||
......
|
||||
s.TH..
|
||||
|
||||
......
|
||||
......
|
||||
......
|
||||
......
|
||||
s..TH.
|
||||
|
||||
== U 4 ==
|
||||
|
||||
......
|
||||
......
|
||||
......
|
||||
....H.
|
||||
s..T..
|
||||
|
||||
......
|
||||
......
|
||||
....H.
|
||||
....T.
|
||||
s.....
|
||||
|
||||
......
|
||||
....H.
|
||||
....T.
|
||||
......
|
||||
s.....
|
||||
|
||||
....H.
|
||||
....T.
|
||||
......
|
||||
......
|
||||
s.....
|
||||
|
||||
== L 3 ==
|
||||
|
||||
...H..
|
||||
....T.
|
||||
......
|
||||
......
|
||||
s.....
|
||||
|
||||
..HT..
|
||||
......
|
||||
......
|
||||
......
|
||||
s.....
|
||||
|
||||
.HT...
|
||||
......
|
||||
......
|
||||
......
|
||||
s.....
|
||||
|
||||
== D 1 ==
|
||||
|
||||
..T...
|
||||
.H....
|
||||
......
|
||||
......
|
||||
s.....
|
||||
|
||||
== R 4 ==
|
||||
|
||||
..T...
|
||||
..H...
|
||||
......
|
||||
......
|
||||
s.....
|
||||
|
||||
..T...
|
||||
...H..
|
||||
......
|
||||
......
|
||||
s.....
|
||||
|
||||
......
|
||||
...TH.
|
||||
......
|
||||
......
|
||||
s.....
|
||||
|
||||
......
|
||||
....TH
|
||||
......
|
||||
......
|
||||
s.....
|
||||
|
||||
== D 1 ==
|
||||
|
||||
......
|
||||
....T.
|
||||
.....H
|
||||
......
|
||||
s.....
|
||||
|
||||
== L 5 ==
|
||||
|
||||
......
|
||||
....T.
|
||||
....H.
|
||||
......
|
||||
s.....
|
||||
|
||||
......
|
||||
....T.
|
||||
...H..
|
||||
......
|
||||
s.....
|
||||
|
||||
......
|
||||
......
|
||||
..HT..
|
||||
......
|
||||
s.....
|
||||
|
||||
......
|
||||
......
|
||||
.HT...
|
||||
......
|
||||
s.....
|
||||
|
||||
......
|
||||
......
|
||||
HT....
|
||||
......
|
||||
s.....
|
||||
|
||||
== R 2 ==
|
||||
|
||||
......
|
||||
......
|
||||
.H.... (H covers T)
|
||||
......
|
||||
s.....
|
||||
|
||||
......
|
||||
......
|
||||
.TH...
|
||||
......
|
||||
s.....
|
||||
#+end_example
|
||||
|
||||
After simulating the rope, you can count up all of the positions the
|
||||
/tail visited at least once/. In this diagram, =s= again marks the
|
||||
starting position (which the tail also visited) and =#= marks other
|
||||
positions the tail visited:
|
||||
|
||||
#+begin_example
|
||||
..##..
|
||||
...##.
|
||||
.####.
|
||||
....#.
|
||||
s###..
|
||||
#+end_example
|
||||
|
||||
So, there are =13= positions the tail visited at least once.
|
||||
|
||||
Simulate your complete hypothetical series of motions. /How many
|
||||
positions does the tail of the rope visit at least once?/
|
||||
|
||||
Your puzzle answer was =5619=.
|
||||
|
||||
** --- Part Two ---
|
||||
A rope snaps! Suddenly, the river is getting a lot closer than you
|
||||
remember. The bridge is still there, but some of the ropes that broke
|
||||
are now whipping toward you as you fall through the air!
|
||||
|
||||
The ropes are moving too quickly to grab; you only have a few seconds to
|
||||
choose how to arch your body to avoid being hit. Fortunately, your
|
||||
simulation can be extended to support longer ropes.
|
||||
|
||||
Rather than two knots, you now must simulate a rope consisting of /ten/
|
||||
knots. One knot is still the head of the rope and moves according to the
|
||||
series of motions. Each knot further down the rope follows the knot in
|
||||
front of it using the same rules as before.
|
||||
|
||||
Using the same series of motions as the above example, but with the
|
||||
knots marked =H=, =1=, =2=, ..., =9=, the motions now occur as follows:
|
||||
|
||||
#+begin_example
|
||||
== Initial State ==
|
||||
|
||||
......
|
||||
......
|
||||
......
|
||||
......
|
||||
H..... (H covers 1, 2, 3, 4, 5, 6, 7, 8, 9, s)
|
||||
|
||||
== R 4 ==
|
||||
|
||||
......
|
||||
......
|
||||
......
|
||||
......
|
||||
1H.... (1 covers 2, 3, 4, 5, 6, 7, 8, 9, s)
|
||||
|
||||
......
|
||||
......
|
||||
......
|
||||
......
|
||||
21H... (2 covers 3, 4, 5, 6, 7, 8, 9, s)
|
||||
|
||||
......
|
||||
......
|
||||
......
|
||||
......
|
||||
321H.. (3 covers 4, 5, 6, 7, 8, 9, s)
|
||||
|
||||
......
|
||||
......
|
||||
......
|
||||
......
|
||||
4321H. (4 covers 5, 6, 7, 8, 9, s)
|
||||
|
||||
== U 4 ==
|
||||
|
||||
......
|
||||
......
|
||||
......
|
||||
....H.
|
||||
4321.. (4 covers 5, 6, 7, 8, 9, s)
|
||||
|
||||
......
|
||||
......
|
||||
....H.
|
||||
.4321.
|
||||
5..... (5 covers 6, 7, 8, 9, s)
|
||||
|
||||
......
|
||||
....H.
|
||||
....1.
|
||||
.432..
|
||||
5..... (5 covers 6, 7, 8, 9, s)
|
||||
|
||||
....H.
|
||||
....1.
|
||||
..432.
|
||||
.5....
|
||||
6..... (6 covers 7, 8, 9, s)
|
||||
|
||||
== L 3 ==
|
||||
|
||||
...H..
|
||||
....1.
|
||||
..432.
|
||||
.5....
|
||||
6..... (6 covers 7, 8, 9, s)
|
||||
|
||||
..H1..
|
||||
...2..
|
||||
..43..
|
||||
.5....
|
||||
6..... (6 covers 7, 8, 9, s)
|
||||
|
||||
.H1...
|
||||
...2..
|
||||
..43..
|
||||
.5....
|
||||
6..... (6 covers 7, 8, 9, s)
|
||||
|
||||
== D 1 ==
|
||||
|
||||
..1...
|
||||
.H.2..
|
||||
..43..
|
||||
.5....
|
||||
6..... (6 covers 7, 8, 9, s)
|
||||
|
||||
== R 4 ==
|
||||
|
||||
..1...
|
||||
..H2..
|
||||
..43..
|
||||
.5....
|
||||
6..... (6 covers 7, 8, 9, s)
|
||||
|
||||
..1...
|
||||
...H.. (H covers 2)
|
||||
..43..
|
||||
.5....
|
||||
6..... (6 covers 7, 8, 9, s)
|
||||
|
||||
......
|
||||
...1H. (1 covers 2)
|
||||
..43..
|
||||
.5....
|
||||
6..... (6 covers 7, 8, 9, s)
|
||||
|
||||
......
|
||||
...21H
|
||||
..43..
|
||||
.5....
|
||||
6..... (6 covers 7, 8, 9, s)
|
||||
|
||||
== D 1 ==
|
||||
|
||||
......
|
||||
...21.
|
||||
..43.H
|
||||
.5....
|
||||
6..... (6 covers 7, 8, 9, s)
|
||||
|
||||
== L 5 ==
|
||||
|
||||
......
|
||||
...21.
|
||||
..43H.
|
||||
.5....
|
||||
6..... (6 covers 7, 8, 9, s)
|
||||
|
||||
......
|
||||
...21.
|
||||
..4H.. (H covers 3)
|
||||
.5....
|
||||
6..... (6 covers 7, 8, 9, s)
|
||||
|
||||
......
|
||||
...2..
|
||||
..H1.. (H covers 4; 1 covers 3)
|
||||
.5....
|
||||
6..... (6 covers 7, 8, 9, s)
|
||||
|
||||
......
|
||||
...2..
|
||||
.H13.. (1 covers 4)
|
||||
.5....
|
||||
6..... (6 covers 7, 8, 9, s)
|
||||
|
||||
......
|
||||
......
|
||||
H123.. (2 covers 4)
|
||||
.5....
|
||||
6..... (6 covers 7, 8, 9, s)
|
||||
|
||||
== R 2 ==
|
||||
|
||||
......
|
||||
......
|
||||
.H23.. (H covers 1; 2 covers 4)
|
||||
.5....
|
||||
6..... (6 covers 7, 8, 9, s)
|
||||
|
||||
......
|
||||
......
|
||||
.1H3.. (H covers 2, 4)
|
||||
.5....
|
||||
6..... (6 covers 7, 8, 9, s)
|
||||
#+end_example
|
||||
|
||||
Now, you need to keep track of the positions the new tail, =9=, visits.
|
||||
In this example, the tail never moves, and so it only visits =1=
|
||||
position. However, /be careful/: more types of motion are possible than
|
||||
before, so you might want to visually compare your simulated rope to the
|
||||
one above.
|
||||
|
||||
Here's a larger example:
|
||||
|
||||
#+begin_example
|
||||
R 5
|
||||
U 8
|
||||
L 8
|
||||
D 3
|
||||
R 17
|
||||
D 10
|
||||
L 25
|
||||
U 20
|
||||
#+end_example
|
||||
|
||||
These motions occur as follows (individual steps are not shown):
|
||||
|
||||
#+begin_example
|
||||
== Initial State ==
|
||||
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
...........H.............. (H covers 1, 2, 3, 4, 5, 6, 7, 8, 9, s)
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
|
||||
== R 5 ==
|
||||
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
...........54321H......... (5 covers 6, 7, 8, 9, s)
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
|
||||
== U 8 ==
|
||||
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
................H.........
|
||||
................1.........
|
||||
................2.........
|
||||
................3.........
|
||||
...............54.........
|
||||
..............6...........
|
||||
.............7............
|
||||
............8.............
|
||||
...........9.............. (9 covers s)
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
|
||||
== L 8 ==
|
||||
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
........H1234.............
|
||||
............5.............
|
||||
............6.............
|
||||
............7.............
|
||||
............8.............
|
||||
............9.............
|
||||
..........................
|
||||
..........................
|
||||
...........s..............
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
|
||||
== D 3 ==
|
||||
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
.........2345.............
|
||||
........1...6.............
|
||||
........H...7.............
|
||||
............8.............
|
||||
............9.............
|
||||
..........................
|
||||
..........................
|
||||
...........s..............
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
|
||||
== R 17 ==
|
||||
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
................987654321H
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
...........s..............
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
|
||||
== D 10 ==
|
||||
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
...........s.........98765
|
||||
.........................4
|
||||
.........................3
|
||||
.........................2
|
||||
.........................1
|
||||
.........................H
|
||||
|
||||
== L 25 ==
|
||||
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
...........s..............
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
H123456789................
|
||||
|
||||
== U 20 ==
|
||||
|
||||
H.........................
|
||||
1.........................
|
||||
2.........................
|
||||
3.........................
|
||||
4.........................
|
||||
5.........................
|
||||
6.........................
|
||||
7.........................
|
||||
8.........................
|
||||
9.........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
...........s..............
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
#+end_example
|
||||
|
||||
Now, the tail (=9=) visits =36= positions (including =s=) at least once:
|
||||
|
||||
#+begin_example
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
..........................
|
||||
#.........................
|
||||
#.............###.........
|
||||
#............#...#........
|
||||
.#..........#.....#.......
|
||||
..#..........#.....#......
|
||||
...#........#.......#.....
|
||||
....#......s.........#....
|
||||
.....#..............#.....
|
||||
......#............#......
|
||||
.......#..........#.......
|
||||
........#........#........
|
||||
.........########.........
|
||||
#+end_example
|
||||
|
||||
Simulate your complete series of motions on a larger rope with ten
|
||||
knots. /How many positions does the tail of the rope visit at least
|
||||
once?/
|
||||
|
||||
Your puzzle answer was =2376=.
|
||||
|
||||
Both parts of this puzzle are complete! They provide two gold stars: **
|
||||
200
2022/day09/aoc-c.c
Normal file
200
2022/day09/aoc-c.c
Normal file
@@ -0,0 +1,200 @@
|
||||
/* aoc-c.c: Advent of Code 2022, day 9
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "aoc.h"
|
||||
|
||||
#include "br.h"
|
||||
#include "debug.h"
|
||||
#include "pool.h"
|
||||
#include "list.h"
|
||||
#include "hashtable.h"
|
||||
#include "pjwhash-inline.h"
|
||||
|
||||
#define HBITS 12 /* 12 bits: 4096 buckets */
|
||||
|
||||
typedef struct pos {
|
||||
int x;
|
||||
int y;
|
||||
} pos_t;
|
||||
|
||||
typedef struct visited {
|
||||
uint hash;
|
||||
pos_t coord;
|
||||
short nvisits;
|
||||
struct hlist_node hlist;
|
||||
} visited_t;
|
||||
|
||||
enum dir {
|
||||
D = 'D',
|
||||
L = 'L',
|
||||
R = 'R',
|
||||
U = 'U'
|
||||
};
|
||||
|
||||
typedef struct move {
|
||||
enum dir dir;
|
||||
int nmoves;
|
||||
struct list_head list;
|
||||
} move_t;
|
||||
|
||||
DEFINE_HASHTABLE(h_visited, HBITS);
|
||||
LIST_HEAD(moves);
|
||||
|
||||
static pool_t *pool_visited;
|
||||
static pool_t *pool_move;
|
||||
|
||||
/**
|
||||
* find_visited - find entry in an hashtable bucket
|
||||
*/
|
||||
static visited_t *find_visited(struct hlist_head *bucket, uint hash, pos_t *pos)
|
||||
{
|
||||
visited_t *cur;
|
||||
|
||||
hlist_for_each_entry(cur, bucket, hlist)
|
||||
if (cur->hash == hash && cur->coord.x == pos->x && cur->coord.y == pos->y)
|
||||
return cur;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static visited_t *add_visited(pos_t *pos, uint hash, uint bucket)
|
||||
{
|
||||
visited_t *new = pool_get(pool_visited);
|
||||
|
||||
new->hash = hash;
|
||||
new->coord.x = pos->x;
|
||||
new->coord.y = pos->y;
|
||||
hlist_add_head(&new->hlist, &h_visited[bucket]);
|
||||
return new;
|
||||
}
|
||||
|
||||
static int add_visited_maybe(pos_t *pos)
|
||||
{
|
||||
uint hash = pjwhash(pos, sizeof (*pos));
|
||||
uint bucket = hash_32(hash, HBITS);
|
||||
if (! find_visited(h_visited + bucket, hash, pos)) {
|
||||
add_visited(pos, hash, bucket);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int move_tails(pos_t *pos, int ntails)
|
||||
{
|
||||
int i;
|
||||
pos_t *cur, *next;
|
||||
int didmove = 1;
|
||||
|
||||
for (i = 0; i < ntails && didmove; ++i) {
|
||||
didmove = 0;
|
||||
pos_t diff;
|
||||
cur = pos + i;
|
||||
next = cur + 1;
|
||||
diff.x = cur->x - next->x;
|
||||
diff.y = cur->y - next->y;
|
||||
if (abs(diff.x) > 1 || abs(diff.y) > 1) { /* do move */
|
||||
if (diff.x)
|
||||
next->x += diff.x / abs(diff.x);
|
||||
if (diff.y)
|
||||
next->y += diff.y / abs(diff.y);
|
||||
didmove = 1;
|
||||
}
|
||||
}
|
||||
return didmove? add_visited_maybe(pos+ntails): 0;
|
||||
}
|
||||
|
||||
static void move_head(pos_t *pos, move_t *move)
|
||||
{
|
||||
log_f(3, "(%d,%d,%c) -> ", pos->x, pos->y, move->dir);
|
||||
switch (move->dir) {
|
||||
case U:
|
||||
pos->y++;
|
||||
break;
|
||||
case R:
|
||||
pos->x++;
|
||||
break;
|
||||
case D:
|
||||
pos->y--;
|
||||
break;
|
||||
case L:
|
||||
pos->x--;
|
||||
break;
|
||||
default:
|
||||
log(3, "ERR=%x ", move->dir);
|
||||
}
|
||||
log_f(3, "(%d,%d)\n", pos->x, pos->y);
|
||||
}
|
||||
|
||||
static pos_t *part1(int *ntails)
|
||||
{
|
||||
static pos_t nodes[] = { [0 ... 1] = {.x = 0, .y = 0}};
|
||||
*ntails = ARRAY_SIZE(nodes) - 1;
|
||||
return nodes;
|
||||
}
|
||||
|
||||
static pos_t *part2(int *ntails)
|
||||
{
|
||||
static pos_t nodes[] = { [0 ... 9] = {.x = 0, .y = 0}};
|
||||
*ntails = ARRAY_SIZE(nodes) - 1;
|
||||
return nodes;
|
||||
}
|
||||
|
||||
static int solve(int part)
|
||||
{
|
||||
int ntails;
|
||||
pos_t *nodes = part == 1? part1(&ntails): part2(&ntails);
|
||||
move_t *move;
|
||||
int res = 1; /* for (0,0) */
|
||||
|
||||
add_visited_maybe( &(pos_t) {0, 0});
|
||||
list_for_each_entry(move, &moves, list) {
|
||||
for (int i = 0; i < move->nmoves; ++i) {
|
||||
move_head(nodes, move);
|
||||
res += move_tails(nodes, ntails);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static int parse()
|
||||
{
|
||||
char dir;
|
||||
int nmoves;
|
||||
int count = 0;
|
||||
move_t *move;
|
||||
|
||||
while (scanf(" %c %d", &dir, &nmoves) == 2) {
|
||||
move = pool_get(pool_move);
|
||||
move->dir = dir;
|
||||
move->nmoves = nmoves;
|
||||
list_add_tail(&move->list, &moves);
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
int main(int ac, char **av)
|
||||
{
|
||||
int part = parseargs(ac, av);
|
||||
pool_visited = pool_create("visited", 128, sizeof(visited_t));
|
||||
pool_move = pool_create("dirs", 128, sizeof(move_t));
|
||||
|
||||
parse();
|
||||
printf("%s: res=%d\n", *av, solve(part));
|
||||
pool_destroy(pool_visited);
|
||||
pool_destroy(pool_move);
|
||||
exit(0);
|
||||
}
|
||||
63
2022/day09/aoc.bash
Executable file
63
2022/day09/aoc.bash
Executable file
@@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# aoc.bash: Advent of Code 2022, day 9
|
||||
#
|
||||
# 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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
|
||||
. common.bash
|
||||
|
||||
declare -a h{0..10} # h0 is head
|
||||
declare -A visited=() # keep count of visited
|
||||
declare -i last=1 # tail (last knot)
|
||||
|
||||
move() {
|
||||
local -i _dx="$1" _dy="$2" _m="$3" _i _n
|
||||
local -i __dx __dy __sx __sy
|
||||
local -n _l="h$last"
|
||||
|
||||
for ((_i = 0; _i < _m; ++_i)); do # for each move
|
||||
(( h0[0] += _dx, h0[1] += _dy )) # head move
|
||||
for (( _n = 0; _n < last; ++_n )); do # for each other node
|
||||
local -n _h="h$_n" _t="h$((_n+1))"
|
||||
(( __dx = _h[0] - _t[0], __dy = _h[1] - _t[1] ))
|
||||
(( __sx = __dx? __dx > 0? 1: -1 : 0 ))
|
||||
(( __sy = __dy? __dy > 0? 1: -1 : 0 ))
|
||||
if (( __sx * __dx > 1 || __sy * __dy > 1)); then
|
||||
(( _t[0] += __sx ))
|
||||
(( _t[1] += __sy ))
|
||||
fi
|
||||
done
|
||||
visited["${_l[0]}"/"${_l[1]}"]=1
|
||||
done
|
||||
}
|
||||
|
||||
parse() {
|
||||
local dir moves dx dy
|
||||
|
||||
(( $1 == 2)) && last=9
|
||||
while read -r dir moves; do
|
||||
dx=0
|
||||
dy=0
|
||||
case "$dir" in
|
||||
L) dx=-1 ;;
|
||||
R) dx=1 ;;
|
||||
U) dy=1 ;;
|
||||
D) dy=-1 ;;
|
||||
esac
|
||||
move "$dx" "$dy" "$moves"
|
||||
done
|
||||
}
|
||||
|
||||
solve() {
|
||||
res=${#visited[@]}
|
||||
}
|
||||
|
||||
main "$@"
|
||||
exit 0
|
||||
17
2022/day09/aoc.h
Normal file
17
2022/day09/aoc.h
Normal file
@@ -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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
#ifndef _AOC_H_
|
||||
#define _AOC_H_
|
||||
|
||||
extern int parseargs(int ac, char**av);
|
||||
|
||||
#endif /* _AOC_H_ */
|
||||
68
2022/day09/common.bash
Executable file
68
2022/day09/common.bash
Executable file
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# common.bash: Advent of Code 2022, common bash 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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
|
||||
# shellcheck disable=2034
|
||||
export cmdname=${0##*/}
|
||||
export debug=0
|
||||
export res
|
||||
export LANG=C
|
||||
|
||||
shopt -s extglob
|
||||
set -o noglob
|
||||
|
||||
usage() {
|
||||
printf "usage: %s [-d DEBUG] [-p PART]\n" "$cmdname"
|
||||
exit 1
|
||||
}
|
||||
|
||||
checkargs() {
|
||||
local part=1
|
||||
while getopts p:d: todo; do
|
||||
case "$todo" in
|
||||
d)
|
||||
if [[ "$OPTARG" =~ ^[[:digit:]+]$ ]]; then
|
||||
debug="$OPTARG"
|
||||
else
|
||||
printf "%s: illegal [%s] debug level.\n" "$CMD" "$OPTARG"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
p)
|
||||
if [[ "$OPTARG" =~ ^[12]$ ]]; then
|
||||
part="$OPTARG"
|
||||
else
|
||||
printf "%s: illegal [%s] part.\n" "$CMD" "$OPTARG"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
# Now check remaining argument (backup directory)
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
(( $# > 1 )) && usage
|
||||
return "$part"
|
||||
}
|
||||
|
||||
main() {
|
||||
local -i part
|
||||
|
||||
checkargs "$@"
|
||||
part=$?
|
||||
parse "$part"
|
||||
solve "$part"
|
||||
printf "%s: res=%s\n" "$cmdname" "$res"
|
||||
}
|
||||
49
2022/day09/common.c
Normal file
49
2022/day09/common.c
Normal file
@@ -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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
8
2022/day09/input/example.txt
Normal file
8
2022/day09/input/example.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
R 4
|
||||
U 4
|
||||
L 3
|
||||
D 1
|
||||
R 4
|
||||
D 1
|
||||
L 5
|
||||
R 2
|
||||
8
2022/day09/input/example2.txt
Normal file
8
2022/day09/input/example2.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
R 5
|
||||
U 8
|
||||
L 8
|
||||
D 3
|
||||
R 17
|
||||
D 10
|
||||
L 25
|
||||
U 20
|
||||
2000
2022/day09/input/input.txt
Normal file
2000
2022/day09/input/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
111
2022/day10/Makefile
Normal file
111
2022/day10/Makefile
Normal file
@@ -0,0 +1,111 @@
|
||||
# AOC daily Makefile - GNU make only.
|
||||
#
|
||||
# Copyright (C) 2021-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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
#
|
||||
|
||||
INPUT := input/input.txt
|
||||
SHELL := /bin/bash
|
||||
|
||||
CC := gcc
|
||||
BEAR := bear
|
||||
CCLSFILE:= compile_commands.json
|
||||
|
||||
LIB := aoc_$(shell uname -m)
|
||||
INCDIR := ../include
|
||||
LIBDIR := ../lib
|
||||
LDFLAGS := -L$(LIBDIR)
|
||||
#LDLIB := -l$(LIB) -lm
|
||||
LDLIB := -l$(LIB)
|
||||
|
||||
export LD_LIBRARY_PATH = $(LIBDIR)
|
||||
|
||||
CFLAGS += -std=gnu11
|
||||
CFLAGS += -O2
|
||||
CFLAGS += -g
|
||||
# for gprof
|
||||
# CFLAGS += -pg
|
||||
CFLAGS += -Wall
|
||||
CFLAGS += -Wextra
|
||||
CFLAGS += -march=native
|
||||
# Next one may be useful for valgrind (some invalid instructions)
|
||||
# CFLAGS += -mno-tbm
|
||||
CFLAGS += -Wmissing-declarations
|
||||
CFLAGS += -Wno-unused-result
|
||||
|
||||
CFLAGS += -DDEBUG_DEBUG # activate general debug (debug.c)
|
||||
CFLAGS += -DDEBUG_POOL # memory pools management
|
||||
|
||||
VALGRIND := valgrind
|
||||
VALGRINDFLAGS := --leak-check=full --show-leak-kinds=all --track-origins=yes \
|
||||
--sigill-diagnostics=yes --quiet --show-error-list=yes
|
||||
|
||||
|
||||
TIME := \time -f "\ttime: %E real, %U user, %S sys\n\tcontext-switch:\t%c+%w, page-faults: %F+%R\n"
|
||||
export PATH := .:$(PATH)
|
||||
|
||||
.PHONY: clean all compile assembly memcheck memcheck1 memcheck2 part1 part2 ccls bear org
|
||||
|
||||
all: README.org ccls part1 part2
|
||||
|
||||
memcheck: memcheck1 memcheck2
|
||||
|
||||
memcheck1: aoc-c
|
||||
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 1 < $(INPUT)
|
||||
|
||||
memcheck2: aoc-c
|
||||
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 2 < $(INPUT)
|
||||
@#@valgrind -s --track-origins=yes aoc-c -p 2 < $(INPUT)
|
||||
|
||||
compile: aoc-c
|
||||
|
||||
cpp: aoc-c.i
|
||||
|
||||
assembly: aoc-c.s
|
||||
|
||||
part1: aoc-c
|
||||
@$(TIME) aoc.bash -p 1 < $(INPUT) 2>&1
|
||||
@$(TIME) aoc-c -p 1 < $(INPUT)
|
||||
|
||||
part2: aoc-c
|
||||
@$(TIME) aoc.bash -p 2 < $(INPUT) 2>&1
|
||||
@$(TIME) aoc-c -p 2 < $(INPUT)
|
||||
|
||||
ccls: $(CCLSFILE)
|
||||
|
||||
clean:
|
||||
@rm -f aoc-c core* vgcore* gmon.out aoc-c.s aoc-c.i README.html compile_commands.json
|
||||
|
||||
aoc-c: aoc-c.c common.c
|
||||
@echo compiling $<
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -I $(INCDIR) $^ $(LDLIB) -o $@
|
||||
|
||||
# generate pre-processed file (.i) and assembler (.s)
|
||||
%.i: %.c
|
||||
@echo generating $@
|
||||
@$(CC) -E $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||
|
||||
%.s: %.c
|
||||
@echo generating $@
|
||||
@$(CC) -S -fverbose-asm $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||
|
||||
# generate README.org from README.html (must cleanup !)
|
||||
org: README.org
|
||||
|
||||
%.org: %.html
|
||||
@echo generating $@. Cleanup before commit !
|
||||
@pandoc $< -o $@
|
||||
|
||||
# generate compile_commands.json
|
||||
$(CCLSFILE): aoc-c.c Makefile
|
||||
$(BEAR) -- make clean compile
|
||||
|
||||
bear: clean
|
||||
@touch .ccls-root
|
||||
@$(BEAR) -- make compile
|
||||
389
2022/day10/README.org
Normal file
389
2022/day10/README.org
Normal file
@@ -0,0 +1,389 @@
|
||||
** --- Day 10: Cathode-Ray Tube ---
|
||||
You avoid the ropes, plunge into the river, and swim to shore.
|
||||
|
||||
The Elves yell something about meeting back up with them upriver, but
|
||||
the river is too loud to tell exactly what they're saying. They finish
|
||||
crossing the bridge and disappear from view.
|
||||
|
||||
Situations like this must be why the Elves prioritized getting the
|
||||
communication system on your handheld device working. You pull it out of
|
||||
your pack, but the amount of water slowly draining from a big crack in
|
||||
its screen tells you it probably won't be of much immediate use.
|
||||
|
||||
/Unless/, that is, you can design a replacement for the device's video
|
||||
system! It seems to be some kind of
|
||||
[[https://en.wikipedia.org/wiki/Cathode-ray_tube][cathode-ray tube]]
|
||||
screen and simple CPU that are both driven by a precise /clock circuit/.
|
||||
The clock circuit ticks at a constant rate; each tick is called a
|
||||
/cycle/.
|
||||
|
||||
Start by figuring out the signal being sent by the CPU. The CPU has a
|
||||
single register, =X=, which starts with the value =1=. It supports only
|
||||
two instructions:
|
||||
|
||||
- =addx V= takes /two cycles/ to complete. /After/ two cycles, the =X=
|
||||
register is increased by the value =V=. (=V= can be negative.)
|
||||
- =noop= takes /one cycle/ to complete. It has no other effect.
|
||||
|
||||
The CPU uses these instructions in a program (your puzzle input) to,
|
||||
somehow, tell the screen what to draw.
|
||||
|
||||
Consider the following small program:
|
||||
|
||||
#+begin_example
|
||||
noop
|
||||
addx 3
|
||||
addx -5
|
||||
#+end_example
|
||||
|
||||
Execution of this program proceeds as follows:
|
||||
|
||||
- At the start of the first cycle, the =noop= instruction begins
|
||||
execution. During the first cycle, =X= is =1=. After the first cycle,
|
||||
the =noop= instruction finishes execution, doing nothing.
|
||||
- At the start of the second cycle, the =addx 3= instruction begins
|
||||
execution. During the second cycle, =X= is still =1=.
|
||||
- During the third cycle, =X= is still =1=. After the third cycle, the
|
||||
=addx 3= instruction finishes execution, setting =X= to =4=.
|
||||
- At the start of the fourth cycle, the =addx -5= instruction begins
|
||||
execution. During the fourth cycle, =X= is still =4=.
|
||||
- During the fifth cycle, =X= is still =4=. After the fifth cycle, the
|
||||
=addx -5= instruction finishes execution, setting =X= to =-1=.
|
||||
|
||||
Maybe you can learn something by looking at the value of the =X=
|
||||
register throughout execution. For now, consider the /signal strength/
|
||||
(the cycle number multiplied by the value of the =X= register) /during/
|
||||
the 20th cycle and every 40 cycles after that (that is, during the 20th,
|
||||
60th, 100th, 140th, 180th, and 220th cycles).
|
||||
|
||||
For example, consider this larger program:
|
||||
|
||||
#+begin_example
|
||||
addx 15
|
||||
addx -11
|
||||
addx 6
|
||||
addx -3
|
||||
addx 5
|
||||
addx -1
|
||||
addx -8
|
||||
addx 13
|
||||
addx 4
|
||||
noop
|
||||
addx -1
|
||||
addx 5
|
||||
addx -1
|
||||
addx 5
|
||||
addx -1
|
||||
addx 5
|
||||
addx -1
|
||||
addx 5
|
||||
addx -1
|
||||
addx -35
|
||||
addx 1
|
||||
addx 24
|
||||
addx -19
|
||||
addx 1
|
||||
addx 16
|
||||
addx -11
|
||||
noop
|
||||
noop
|
||||
addx 21
|
||||
addx -15
|
||||
noop
|
||||
noop
|
||||
addx -3
|
||||
addx 9
|
||||
addx 1
|
||||
addx -3
|
||||
addx 8
|
||||
addx 1
|
||||
addx 5
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx -36
|
||||
noop
|
||||
addx 1
|
||||
addx 7
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx 2
|
||||
addx 6
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx 1
|
||||
noop
|
||||
noop
|
||||
addx 7
|
||||
addx 1
|
||||
noop
|
||||
addx -13
|
||||
addx 13
|
||||
addx 7
|
||||
noop
|
||||
addx 1
|
||||
addx -33
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx 2
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx 8
|
||||
noop
|
||||
addx -1
|
||||
addx 2
|
||||
addx 1
|
||||
noop
|
||||
addx 17
|
||||
addx -9
|
||||
addx 1
|
||||
addx 1
|
||||
addx -3
|
||||
addx 11
|
||||
noop
|
||||
noop
|
||||
addx 1
|
||||
noop
|
||||
addx 1
|
||||
noop
|
||||
noop
|
||||
addx -13
|
||||
addx -19
|
||||
addx 1
|
||||
addx 3
|
||||
addx 26
|
||||
addx -30
|
||||
addx 12
|
||||
addx -1
|
||||
addx 3
|
||||
addx 1
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx -9
|
||||
addx 18
|
||||
addx 1
|
||||
addx 2
|
||||
noop
|
||||
noop
|
||||
addx 9
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx -1
|
||||
addx 2
|
||||
addx -37
|
||||
addx 1
|
||||
addx 3
|
||||
noop
|
||||
addx 15
|
||||
addx -21
|
||||
addx 22
|
||||
addx -6
|
||||
addx 1
|
||||
noop
|
||||
addx 2
|
||||
addx 1
|
||||
noop
|
||||
addx -10
|
||||
noop
|
||||
noop
|
||||
addx 20
|
||||
addx 1
|
||||
addx 2
|
||||
addx 2
|
||||
addx -6
|
||||
addx -11
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
#+end_example
|
||||
|
||||
The interesting signal strengths can be determined as follows:
|
||||
|
||||
- During the 20th cycle, register =X= has the value =21=, so the signal
|
||||
strength is 20 * 21 = /420/. (The 20th cycle occurs in the middle of
|
||||
the second =addx -1=, so the value of register =X= is the starting
|
||||
value, =1=, plus all of the other =addx= values up to that point: 1 +
|
||||
15 - 11 + 6 - 3 + 5 - 1 - 8 + 13 + 4 = 21.)
|
||||
- During the 60th cycle, register =X= has the value =19=, so the signal
|
||||
strength is 60 * 19 = =1140=.
|
||||
- During the 100th cycle, register =X= has the value =18=, so the signal
|
||||
strength is 100 * 18 = =1800=.
|
||||
- During the 140th cycle, register =X= has the value =21=, so the signal
|
||||
strength is 140 * 21 = =2940=.
|
||||
- During the 180th cycle, register =X= has the value =16=, so the signal
|
||||
strength is 180 * 16 = =2880=.
|
||||
- During the 220th cycle, register =X= has the value =18=, so the signal
|
||||
strength is 220 * 18 = =3960=.
|
||||
|
||||
The sum of these signal strengths is =13140=.
|
||||
|
||||
Find the signal strength during the 20th, 60th, 100th, 140th, 180th, and
|
||||
220th cycles. /What is the sum of these six signal strengths?/
|
||||
|
||||
Your puzzle answer was =13220=.
|
||||
|
||||
** --- Part Two ---
|
||||
It seems like the =X= register controls the horizontal position of a
|
||||
[[https://en.wikipedia.org/wiki/Sprite_(computer_graphics)][sprite]].
|
||||
Specifically, the sprite is 3 pixels wide, and the =X= register sets the
|
||||
horizontal position of the /middle/ of that sprite. (In this system,
|
||||
there is no such thing as "vertical position": if the sprite's
|
||||
horizontal position puts its pixels where the CRT is currently drawing,
|
||||
then those pixels will be drawn.)
|
||||
|
||||
You count the pixels on the CRT: 40 wide and 6 high. This CRT screen
|
||||
draws the top row of pixels left-to-right, then the row below that, and
|
||||
so on. The left-most pixel in each row is in position =0=, and the
|
||||
right-most pixel in each row is in position =39=.
|
||||
|
||||
Like the CPU, the CRT is tied closely to the clock circuit: the CRT
|
||||
draws /a single pixel during each cycle/. Representing each pixel of the
|
||||
screen as a =#=, here are the cycles during which the first and last
|
||||
pixel in each row are drawn:
|
||||
|
||||
#+begin_example
|
||||
Cycle 1 -> ######################################## <- Cycle 40
|
||||
Cycle 41 -> ######################################## <- Cycle 80
|
||||
Cycle 81 -> ######################################## <- Cycle 120
|
||||
Cycle 121 -> ######################################## <- Cycle 160
|
||||
Cycle 161 -> ######################################## <- Cycle 200
|
||||
Cycle 201 -> ######################################## <- Cycle 240
|
||||
#+end_example
|
||||
|
||||
So, by [[https://en.wikipedia.org/wiki/Racing_the_Beam][carefully]]
|
||||
[[https://www.youtube.com/watch?v=sJFnWZH5FXc][timing]] the CPU
|
||||
instructions and the CRT drawing operations, you should be able to
|
||||
determine whether the sprite is visible the instant each pixel is drawn.
|
||||
If the sprite is positioned such that one of its three pixels is the
|
||||
pixel currently being drawn, the screen produces a /lit/ pixel (=#=);
|
||||
otherwise, the screen leaves the pixel /dark/ (=.=).
|
||||
|
||||
The first few pixels from the larger example above are drawn as follows:
|
||||
|
||||
#+begin_example
|
||||
Sprite position: ###.....................................
|
||||
|
||||
Start cycle 1: begin executing addx 15
|
||||
During cycle 1: CRT draws pixel in position 0
|
||||
Current CRT row: #
|
||||
|
||||
During cycle 2: CRT draws pixel in position 1
|
||||
Current CRT row: ##
|
||||
End of cycle 2: finish executing addx 15 (Register X is now 16)
|
||||
Sprite position: ...............###......................
|
||||
|
||||
Start cycle 3: begin executing addx -11
|
||||
During cycle 3: CRT draws pixel in position 2
|
||||
Current CRT row: ##.
|
||||
|
||||
During cycle 4: CRT draws pixel in position 3
|
||||
Current CRT row: ##..
|
||||
End of cycle 4: finish executing addx -11 (Register X is now 5)
|
||||
Sprite position: ....###.................................
|
||||
|
||||
Start cycle 5: begin executing addx 6
|
||||
During cycle 5: CRT draws pixel in position 4
|
||||
Current CRT row: ##..#
|
||||
|
||||
During cycle 6: CRT draws pixel in position 5
|
||||
Current CRT row: ##..##
|
||||
End of cycle 6: finish executing addx 6 (Register X is now 11)
|
||||
Sprite position: ..........###...........................
|
||||
|
||||
Start cycle 7: begin executing addx -3
|
||||
During cycle 7: CRT draws pixel in position 6
|
||||
Current CRT row: ##..##.
|
||||
|
||||
During cycle 8: CRT draws pixel in position 7
|
||||
Current CRT row: ##..##..
|
||||
End of cycle 8: finish executing addx -3 (Register X is now 8)
|
||||
Sprite position: .......###..............................
|
||||
|
||||
Start cycle 9: begin executing addx 5
|
||||
During cycle 9: CRT draws pixel in position 8
|
||||
Current CRT row: ##..##..#
|
||||
|
||||
During cycle 10: CRT draws pixel in position 9
|
||||
Current CRT row: ##..##..##
|
||||
End of cycle 10: finish executing addx 5 (Register X is now 13)
|
||||
Sprite position: ............###.........................
|
||||
|
||||
Start cycle 11: begin executing addx -1
|
||||
During cycle 11: CRT draws pixel in position 10
|
||||
Current CRT row: ##..##..##.
|
||||
|
||||
During cycle 12: CRT draws pixel in position 11
|
||||
Current CRT row: ##..##..##..
|
||||
End of cycle 12: finish executing addx -1 (Register X is now 12)
|
||||
Sprite position: ...........###..........................
|
||||
|
||||
Start cycle 13: begin executing addx -8
|
||||
During cycle 13: CRT draws pixel in position 12
|
||||
Current CRT row: ##..##..##..#
|
||||
|
||||
During cycle 14: CRT draws pixel in position 13
|
||||
Current CRT row: ##..##..##..##
|
||||
End of cycle 14: finish executing addx -8 (Register X is now 4)
|
||||
Sprite position: ...###..................................
|
||||
|
||||
Start cycle 15: begin executing addx 13
|
||||
During cycle 15: CRT draws pixel in position 14
|
||||
Current CRT row: ##..##..##..##.
|
||||
|
||||
During cycle 16: CRT draws pixel in position 15
|
||||
Current CRT row: ##..##..##..##..
|
||||
End of cycle 16: finish executing addx 13 (Register X is now 17)
|
||||
Sprite position: ................###.....................
|
||||
|
||||
Start cycle 17: begin executing addx 4
|
||||
During cycle 17: CRT draws pixel in position 16
|
||||
Current CRT row: ##..##..##..##..#
|
||||
|
||||
During cycle 18: CRT draws pixel in position 17
|
||||
Current CRT row: ##..##..##..##..##
|
||||
End of cycle 18: finish executing addx 4 (Register X is now 21)
|
||||
Sprite position: ....................###.................
|
||||
|
||||
Start cycle 19: begin executing noop
|
||||
During cycle 19: CRT draws pixel in position 18
|
||||
Current CRT row: ##..##..##..##..##.
|
||||
End of cycle 19: finish executing noop
|
||||
|
||||
Start cycle 20: begin executing addx -1
|
||||
During cycle 20: CRT draws pixel in position 19
|
||||
Current CRT row: ##..##..##..##..##..
|
||||
|
||||
During cycle 21: CRT draws pixel in position 20
|
||||
Current CRT row: ##..##..##..##..##..#
|
||||
End of cycle 21: finish executing addx -1 (Register X is now 20)
|
||||
Sprite position: ...................###..................
|
||||
#+end_example
|
||||
|
||||
Allowing the program to run to completion causes the CRT to produce the
|
||||
following image:
|
||||
|
||||
#+begin_example
|
||||
##..##..##..##..##..##..##..##..##..##..
|
||||
###...###...###...###...###...###...###.
|
||||
####....####....####....####....####....
|
||||
#####.....#####.....#####.....#####.....
|
||||
######......######......######......####
|
||||
#######.......#######.......#######.....
|
||||
#+end_example
|
||||
|
||||
Render the image given by your program. /What eight capital letters
|
||||
appear on your CRT?/
|
||||
|
||||
Your puzzle answer was =RUAKHBEK=.
|
||||
|
||||
Both parts of this puzzle are complete! They provide two gold stars: **
|
||||
167
2022/day10/aoc-c.c
Normal file
167
2022/day10/aoc-c.c
Normal file
@@ -0,0 +1,167 @@
|
||||
/* aoc-c.c: Advent of Code 2022, day 10
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "br.h"
|
||||
#include "debug.h"
|
||||
|
||||
#include "aoc.h"
|
||||
|
||||
#define MAXARGS 1 /* max arguments to opcode */
|
||||
|
||||
typedef enum opcode { /* available opcodes */
|
||||
ERR = -1,
|
||||
NOOP = 0,
|
||||
ADDX
|
||||
} opcode_t;
|
||||
|
||||
typedef struct hw { /* hardware */
|
||||
int tick; /* clock */
|
||||
int regx; /* x register */
|
||||
int signal; /* signal strength */
|
||||
int alrm; /* next tick signal */
|
||||
int rearm; /* rearm signal value */
|
||||
void (* tickfct)(struct hw *hw); /* tick function */
|
||||
void (* alrmfct)(struct hw *hw); /* signal function */
|
||||
int part; /* puzzle part */
|
||||
} hw_t;
|
||||
|
||||
typedef struct op { /* operators indormation */
|
||||
char *mnemo;
|
||||
opcode_t opcode;
|
||||
int ticks;
|
||||
void (* fct)(hw_t *hw, int *);
|
||||
int nargs;
|
||||
} op_t;
|
||||
|
||||
static inline void alarm1(hw_t *hw)
|
||||
{
|
||||
hw->signal += hw->tick * hw->regx;
|
||||
hw->alrm = hw->rearm;
|
||||
}
|
||||
|
||||
static inline void alarm2(hw_t *hw)
|
||||
{
|
||||
putchar('\n'); /* '.' fixes last column garbage */
|
||||
hw->alrm = hw->rearm;
|
||||
}
|
||||
|
||||
static inline void tick1(__unused hw_t *hw)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void tick2(hw_t *hw)
|
||||
{
|
||||
int pos = abs(hw->tick % 40 - hw->regx - 1);
|
||||
putchar(pos < 2? '#': '.');
|
||||
}
|
||||
|
||||
static void bootstrap(hw_t *hw, int part)
|
||||
{
|
||||
hw->tick = 0;
|
||||
hw->regx = 1;
|
||||
hw->signal = 0;
|
||||
hw->alrm = part == 1? 20: 40;
|
||||
hw->rearm = 40;
|
||||
hw->alrmfct = part == 1? alarm1: alarm2;
|
||||
hw->tickfct = part == 1? tick1: tick2;
|
||||
hw->part = part;
|
||||
}
|
||||
|
||||
static inline void tick(hw_t *hw)
|
||||
{
|
||||
hw->tick++;
|
||||
hw->alrm--;
|
||||
hw->tickfct(hw);
|
||||
if (!hw->alrm)
|
||||
hw->alrmfct(hw);
|
||||
}
|
||||
|
||||
static inline void ticks(hw_t *hw, int ticks)
|
||||
{
|
||||
for (int i = 0; i < ticks; ++i)
|
||||
tick(hw);
|
||||
}
|
||||
|
||||
static void do_noop(__unused hw_t *hw, __unused int *args)
|
||||
{
|
||||
}
|
||||
|
||||
static void do_addx(hw_t *hw, int *args)
|
||||
{
|
||||
hw->regx += *args;
|
||||
}
|
||||
|
||||
static op_t opcodes[] = {
|
||||
{ "noop", NOOP, 1, do_noop, 0 },
|
||||
{ "addx", ADDX, 2, do_addx, 1 }
|
||||
};
|
||||
|
||||
#define NOPS ARRAY_SIZE(opcodes)
|
||||
|
||||
static op_t *getop(const char *mnemo)
|
||||
{
|
||||
for (ulong i = 0; i < NOPS; ++i)
|
||||
if (!strcmp(mnemo, opcodes[i].mnemo))
|
||||
return opcodes + i;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int part1(hw_t *hw)
|
||||
{
|
||||
return hw->signal;
|
||||
}
|
||||
|
||||
static int part2(hw_t *hw)
|
||||
{
|
||||
return hw->signal;
|
||||
}
|
||||
|
||||
static int parse(hw_t *hw)
|
||||
{
|
||||
size_t alloc = 0;
|
||||
char *buf = NULL;
|
||||
ssize_t buflen;
|
||||
char *token;
|
||||
op_t *op;
|
||||
int args[MAXARGS];
|
||||
|
||||
while ((buflen = getline(&buf, &alloc, stdin)) > 0) {
|
||||
buf[--buflen] = 0;
|
||||
if ((token = strtok(buf, " "))) {
|
||||
if ((op = getop(token))) {
|
||||
ticks(hw, op->ticks);
|
||||
for (int i = 0; i < op->nargs; ++i)
|
||||
args[i] = atoi(strtok(NULL, " "));
|
||||
op->fct(hw, args);
|
||||
} else {
|
||||
fprintf(stderr, "Fatal: opcode [%s] not found\n", token);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int ac, char **av)
|
||||
{
|
||||
int part = parseargs(ac, av);
|
||||
hw_t hw;
|
||||
|
||||
bootstrap(&hw, part);
|
||||
parse(&hw);
|
||||
printf("%s: res=%d\n", *av, part == 1? part1(&hw): part2(&hw));
|
||||
exit(0);
|
||||
}
|
||||
67
2022/day10/aoc.bash
Executable file
67
2022/day10/aoc.bash
Executable file
@@ -0,0 +1,67 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# aoc.bash: Advent of Code 2022, day 10
|
||||
#
|
||||
# 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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
|
||||
. common.bash
|
||||
|
||||
declare -i cycle=0 regx=1
|
||||
|
||||
draw() {
|
||||
local -i pos
|
||||
|
||||
(( pos = cycle % 40 - regx - 1, pos = pos < 0? -pos: pos ))
|
||||
(( pos < 2 )) && res+="#" || res+="."
|
||||
if ! (( cycle % 40 )); then
|
||||
res+=$'\n'
|
||||
fi
|
||||
}
|
||||
|
||||
tick() {
|
||||
(( cycle ++ ))
|
||||
if (( part == 1 )); then
|
||||
(( (cycle + 20) % 40 )) || (( res += cycle * regx ))
|
||||
else
|
||||
draw
|
||||
fi
|
||||
}
|
||||
|
||||
do_noop() {
|
||||
tick
|
||||
}
|
||||
|
||||
do_add() {
|
||||
tick
|
||||
tick
|
||||
(( regx += $1 ))
|
||||
}
|
||||
|
||||
parse() {
|
||||
while read -r instr value; do
|
||||
# not too hacky, to prepare for next puzzles ;-)
|
||||
case "$instr" in
|
||||
"addx")
|
||||
do_add "$value"
|
||||
;;
|
||||
"noop")
|
||||
do_noop
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
solve() {
|
||||
# remove last '\n', add starting '\n'
|
||||
(( part == 2 )) && res=$'\n'${res::-1}
|
||||
}
|
||||
|
||||
main "$@"
|
||||
exit 0
|
||||
17
2022/day10/aoc.h
Normal file
17
2022/day10/aoc.h
Normal file
@@ -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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
#ifndef _AOC_H_
|
||||
#define _AOC_H_
|
||||
|
||||
extern int parseargs(int ac, char**av);
|
||||
|
||||
#endif /* _AOC_H_ */
|
||||
68
2022/day10/common.bash
Executable file
68
2022/day10/common.bash
Executable file
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# common.bash: Advent of Code 2022, common bash 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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
|
||||
# shellcheck disable=2034
|
||||
export cmdname=${0##*/}
|
||||
export debug=0
|
||||
export res
|
||||
export LANG=C
|
||||
|
||||
shopt -s extglob
|
||||
set -o noglob
|
||||
|
||||
usage() {
|
||||
printf "usage: %s [-d DEBUG] [-p PART]\n" "$cmdname"
|
||||
exit 1
|
||||
}
|
||||
|
||||
checkargs() {
|
||||
local part=1
|
||||
while getopts p:d: todo; do
|
||||
case "$todo" in
|
||||
d)
|
||||
if [[ "$OPTARG" =~ ^[[:digit:]+]$ ]]; then
|
||||
debug="$OPTARG"
|
||||
else
|
||||
printf "%s: illegal [%s] debug level.\n" "$CMD" "$OPTARG"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
p)
|
||||
if [[ "$OPTARG" =~ ^[12]$ ]]; then
|
||||
part="$OPTARG"
|
||||
else
|
||||
printf "%s: illegal [%s] part.\n" "$CMD" "$OPTARG"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
# Now check remaining argument (backup directory)
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
(( $# > 1 )) && usage
|
||||
return "$part"
|
||||
}
|
||||
|
||||
main() {
|
||||
local -i part
|
||||
|
||||
checkargs "$@"
|
||||
part=$?
|
||||
parse "$part"
|
||||
solve "$part"
|
||||
printf "%s: res=%s\n" "$cmdname" "$res"
|
||||
}
|
||||
49
2022/day10/common.c
Normal file
49
2022/day10/common.c
Normal file
@@ -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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
146
2022/day10/input/example.txt
Normal file
146
2022/day10/input/example.txt
Normal file
@@ -0,0 +1,146 @@
|
||||
addx 15
|
||||
addx -11
|
||||
addx 6
|
||||
addx -3
|
||||
addx 5
|
||||
addx -1
|
||||
addx -8
|
||||
addx 13
|
||||
addx 4
|
||||
noop
|
||||
addx -1
|
||||
addx 5
|
||||
addx -1
|
||||
addx 5
|
||||
addx -1
|
||||
addx 5
|
||||
addx -1
|
||||
addx 5
|
||||
addx -1
|
||||
addx -35
|
||||
addx 1
|
||||
addx 24
|
||||
addx -19
|
||||
addx 1
|
||||
addx 16
|
||||
addx -11
|
||||
noop
|
||||
noop
|
||||
addx 21
|
||||
addx -15
|
||||
noop
|
||||
noop
|
||||
addx -3
|
||||
addx 9
|
||||
addx 1
|
||||
addx -3
|
||||
addx 8
|
||||
addx 1
|
||||
addx 5
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx -36
|
||||
noop
|
||||
addx 1
|
||||
addx 7
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx 2
|
||||
addx 6
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx 1
|
||||
noop
|
||||
noop
|
||||
addx 7
|
||||
addx 1
|
||||
noop
|
||||
addx -13
|
||||
addx 13
|
||||
addx 7
|
||||
noop
|
||||
addx 1
|
||||
addx -33
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx 2
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx 8
|
||||
noop
|
||||
addx -1
|
||||
addx 2
|
||||
addx 1
|
||||
noop
|
||||
addx 17
|
||||
addx -9
|
||||
addx 1
|
||||
addx 1
|
||||
addx -3
|
||||
addx 11
|
||||
noop
|
||||
noop
|
||||
addx 1
|
||||
noop
|
||||
addx 1
|
||||
noop
|
||||
noop
|
||||
addx -13
|
||||
addx -19
|
||||
addx 1
|
||||
addx 3
|
||||
addx 26
|
||||
addx -30
|
||||
addx 12
|
||||
addx -1
|
||||
addx 3
|
||||
addx 1
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx -9
|
||||
addx 18
|
||||
addx 1
|
||||
addx 2
|
||||
noop
|
||||
noop
|
||||
addx 9
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx -1
|
||||
addx 2
|
||||
addx -37
|
||||
addx 1
|
||||
addx 3
|
||||
noop
|
||||
addx 15
|
||||
addx -21
|
||||
addx 22
|
||||
addx -6
|
||||
addx 1
|
||||
noop
|
||||
addx 2
|
||||
addx 1
|
||||
noop
|
||||
addx -10
|
||||
noop
|
||||
noop
|
||||
addx 20
|
||||
addx 1
|
||||
addx 2
|
||||
addx 2
|
||||
addx -6
|
||||
addx -11
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
3
2022/day10/input/example2.txt
Normal file
3
2022/day10/input/example2.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
noop
|
||||
addx 3
|
||||
addx -5
|
||||
137
2022/day10/input/input.txt
Normal file
137
2022/day10/input/input.txt
Normal file
@@ -0,0 +1,137 @@
|
||||
noop
|
||||
noop
|
||||
addx 5
|
||||
addx 3
|
||||
addx -2
|
||||
noop
|
||||
addx 5
|
||||
addx 4
|
||||
noop
|
||||
addx 3
|
||||
noop
|
||||
addx 2
|
||||
addx -17
|
||||
addx 18
|
||||
addx 3
|
||||
addx 1
|
||||
noop
|
||||
addx 5
|
||||
noop
|
||||
addx 1
|
||||
addx 2
|
||||
addx 5
|
||||
addx -40
|
||||
noop
|
||||
addx 5
|
||||
addx 2
|
||||
addx 3
|
||||
noop
|
||||
addx 2
|
||||
addx 3
|
||||
addx -2
|
||||
addx 2
|
||||
addx 2
|
||||
noop
|
||||
addx 3
|
||||
addx 5
|
||||
addx 2
|
||||
addx 3
|
||||
addx -2
|
||||
addx 2
|
||||
addx -24
|
||||
addx 31
|
||||
addx 2
|
||||
addx -33
|
||||
addx -6
|
||||
addx 5
|
||||
addx 2
|
||||
addx 3
|
||||
noop
|
||||
addx 2
|
||||
addx 3
|
||||
noop
|
||||
addx 2
|
||||
addx -1
|
||||
addx 6
|
||||
noop
|
||||
noop
|
||||
addx 1
|
||||
addx 4
|
||||
noop
|
||||
noop
|
||||
addx -15
|
||||
addx 20
|
||||
noop
|
||||
addx -23
|
||||
addx 27
|
||||
noop
|
||||
addx -35
|
||||
addx 1
|
||||
noop
|
||||
noop
|
||||
addx 5
|
||||
addx 11
|
||||
addx -10
|
||||
addx 4
|
||||
addx 1
|
||||
noop
|
||||
addx 2
|
||||
addx 2
|
||||
noop
|
||||
addx 3
|
||||
noop
|
||||
addx 3
|
||||
addx 2
|
||||
noop
|
||||
addx 3
|
||||
addx 2
|
||||
addx 11
|
||||
addx -4
|
||||
addx 2
|
||||
addx -38
|
||||
addx -1
|
||||
addx 2
|
||||
noop
|
||||
addx 3
|
||||
addx 5
|
||||
addx 2
|
||||
addx -7
|
||||
addx 8
|
||||
addx 2
|
||||
addx 2
|
||||
noop
|
||||
addx 3
|
||||
addx 5
|
||||
addx 2
|
||||
addx -25
|
||||
addx 26
|
||||
addx 2
|
||||
addx 8
|
||||
addx -1
|
||||
addx 2
|
||||
addx -2
|
||||
addx -37
|
||||
addx 5
|
||||
addx 3
|
||||
addx -1
|
||||
addx 5
|
||||
noop
|
||||
addx 22
|
||||
addx -21
|
||||
addx 2
|
||||
addx 5
|
||||
addx 2
|
||||
addx 13
|
||||
addx -12
|
||||
addx 4
|
||||
noop
|
||||
noop
|
||||
addx 5
|
||||
addx 1
|
||||
noop
|
||||
noop
|
||||
addx 2
|
||||
noop
|
||||
addx 3
|
||||
noop
|
||||
noop
|
||||
111
2022/day11/Makefile
Normal file
111
2022/day11/Makefile
Normal file
@@ -0,0 +1,111 @@
|
||||
# AOC daily Makefile - GNU make only.
|
||||
#
|
||||
# Copyright (C) 2021-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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
#
|
||||
|
||||
INPUT := input/input.txt
|
||||
SHELL := /bin/bash
|
||||
|
||||
CC := gcc
|
||||
BEAR := bear
|
||||
CCLSFILE:= compile_commands.json
|
||||
|
||||
LIB := aoc_$(shell uname -m)
|
||||
INCDIR := ../include
|
||||
LIBDIR := ../lib
|
||||
LDFLAGS := -L$(LIBDIR)
|
||||
#LDLIB := -l$(LIB) -lm
|
||||
LDLIB := -l$(LIB)
|
||||
|
||||
export LD_LIBRARY_PATH = $(LIBDIR)
|
||||
|
||||
CFLAGS += -std=gnu11
|
||||
CFLAGS += -O2
|
||||
CFLAGS += -g
|
||||
# for gprof
|
||||
# CFLAGS += -pg
|
||||
CFLAGS += -Wall
|
||||
CFLAGS += -Wextra
|
||||
CFLAGS += -march=native
|
||||
# Next one may be useful for valgrind (some invalid instructions)
|
||||
# CFLAGS += -mno-tbm
|
||||
CFLAGS += -Wmissing-declarations
|
||||
CFLAGS += -Wno-unused-result
|
||||
|
||||
CFLAGS += -DDEBUG_DEBUG # activate general debug (debug.c)
|
||||
CFLAGS += -DDEBUG_POOL # memory pools management
|
||||
|
||||
VALGRIND := valgrind
|
||||
VALGRINDFLAGS := --leak-check=full --show-leak-kinds=all --track-origins=yes \
|
||||
--sigill-diagnostics=yes --quiet --show-error-list=yes
|
||||
|
||||
|
||||
TIME := \time -f "\ttime: %E real, %U user, %S sys\n\tcontext-switch:\t%c+%w, page-faults: %F+%R\n"
|
||||
export PATH := .:$(PATH)
|
||||
|
||||
.PHONY: clean all compile assembly memcheck memcheck1 memcheck2 part1 part2 ccls bear org
|
||||
|
||||
all: README.org ccls part1 part2
|
||||
|
||||
memcheck: memcheck1 memcheck2
|
||||
|
||||
memcheck1: aoc-c
|
||||
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 1 < $(INPUT)
|
||||
|
||||
memcheck2: aoc-c
|
||||
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 2 < $(INPUT)
|
||||
@#@valgrind -s --track-origins=yes aoc-c -p 2 < $(INPUT)
|
||||
|
||||
compile: aoc-c
|
||||
|
||||
cpp: aoc-c.i
|
||||
|
||||
assembly: aoc-c.s
|
||||
|
||||
part1: aoc-c
|
||||
@$(TIME) aoc.bash -p 1 < $(INPUT) 2>&1
|
||||
@$(TIME) aoc-c -p 1 < $(INPUT)
|
||||
|
||||
part2: aoc-c
|
||||
@$(TIME) aoc.bash -p 2 < $(INPUT) 2>&1
|
||||
@$(TIME) aoc-c -p 2 < $(INPUT)
|
||||
|
||||
ccls: $(CCLSFILE)
|
||||
|
||||
clean:
|
||||
@rm -f aoc-c core* vgcore* gmon.out aoc-c.s aoc-c.i README.html compile_commands.json
|
||||
|
||||
aoc-c: aoc-c.c common.c
|
||||
@echo compiling $<
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -I $(INCDIR) $^ $(LDLIB) -o $@
|
||||
|
||||
# generate pre-processed file (.i) and assembler (.s)
|
||||
%.i: %.c
|
||||
@echo generating $@
|
||||
@$(CC) -E $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||
|
||||
%.s: %.c
|
||||
@echo generating $@
|
||||
@$(CC) -S -fverbose-asm $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||
|
||||
# generate README.org from README.html (must cleanup !)
|
||||
org: README.org
|
||||
|
||||
%.org: %.html
|
||||
@echo generating $@. Cleanup before commit !
|
||||
@pandoc $< -o $@
|
||||
|
||||
# generate compile_commands.json
|
||||
$(CCLSFILE): aoc-c.c Makefile
|
||||
$(BEAR) -- make clean compile
|
||||
|
||||
bear: clean
|
||||
@touch .ccls-root
|
||||
@$(BEAR) -- make compile
|
||||
364
2022/day11/README.org
Normal file
364
2022/day11/README.org
Normal file
@@ -0,0 +1,364 @@
|
||||
** --- Day 11: Monkey in the Middle ---
|
||||
As you finally start making your way upriver, you realize your pack is
|
||||
much lighter than you remember. Just then, one of the items from your
|
||||
pack goes flying overhead. Monkeys are playing
|
||||
[[https://en.wikipedia.org/wiki/Keep_away][Keep Away]] with your missing
|
||||
things!
|
||||
|
||||
To get your stuff back, you need to be able to predict where the monkeys
|
||||
will throw your items. After some careful observation, you realize the
|
||||
monkeys operate based on /how worried you are about each item/.
|
||||
|
||||
You take some notes (your puzzle input) on the items each monkey
|
||||
currently has, how worried you are about those items, and how the monkey
|
||||
makes decisions based on your worry level. For example:
|
||||
|
||||
#+begin_example
|
||||
Monkey 0:
|
||||
Starting items: 79, 98
|
||||
Operation: new = old * 19
|
||||
Test: divisible by 23
|
||||
If true: throw to monkey 2
|
||||
If false: throw to monkey 3
|
||||
|
||||
Monkey 1:
|
||||
Starting items: 54, 65, 75, 74
|
||||
Operation: new = old + 6
|
||||
Test: divisible by 19
|
||||
If true: throw to monkey 2
|
||||
If false: throw to monkey 0
|
||||
|
||||
Monkey 2:
|
||||
Starting items: 79, 60, 97
|
||||
Operation: new = old * old
|
||||
Test: divisible by 13
|
||||
If true: throw to monkey 1
|
||||
If false: throw to monkey 3
|
||||
|
||||
Monkey 3:
|
||||
Starting items: 74
|
||||
Operation: new = old + 3
|
||||
Test: divisible by 17
|
||||
If true: throw to monkey 0
|
||||
If false: throw to monkey 1
|
||||
#+end_example
|
||||
|
||||
Each monkey has several attributes:
|
||||
|
||||
- =Starting items= lists your /worry level/ for each item the monkey is
|
||||
currently holding in the order they will be inspected.
|
||||
- =Operation= shows how your worry level changes as that monkey inspects
|
||||
an item. (An operation like =new = old * 5= means that your worry
|
||||
level after the monkey inspected the item is five times whatever your
|
||||
worry level was before inspection.)
|
||||
- =Test= shows how the monkey uses your worry level to decide where to
|
||||
throw an item next.
|
||||
- =If true= shows what happens with an item if the =Test= was true.
|
||||
- =If false= shows what happens with an item if the =Test= was false.
|
||||
|
||||
After each monkey inspects an item but before it tests your worry level,
|
||||
your relief that the monkey's inspection didn't damage the item causes
|
||||
your worry level to be /divided by three/ and rounded down to the
|
||||
nearest integer.
|
||||
|
||||
The monkeys take turns inspecting and throwing items. On a single
|
||||
monkey's /turn/, it inspects and throws all of the items it is holding
|
||||
one at a time and in the order listed. Monkey =0= goes first, then
|
||||
monkey =1=, and so on until each monkey has had one turn. The process of
|
||||
each monkey taking a single turn is called a /round/.
|
||||
|
||||
When a monkey throws an item to another monkey, the item goes on the
|
||||
/end/ of the recipient monkey's list. A monkey that starts a round with
|
||||
no items could end up inspecting and throwing many items by the time its
|
||||
turn comes around. If a monkey is holding no items at the start of its
|
||||
turn, its turn ends.
|
||||
|
||||
In the above example, the first round proceeds as follows:
|
||||
|
||||
#+begin_example
|
||||
Monkey 0:
|
||||
Monkey inspects an item with a worry level of 79.
|
||||
Worry level is multiplied by 19 to 1501.
|
||||
Monkey gets bored with item. Worry level is divided by 3 to 500.
|
||||
Current worry level is not divisible by 23.
|
||||
Item with worry level 500 is thrown to monkey 3.
|
||||
Monkey inspects an item with a worry level of 98.
|
||||
Worry level is multiplied by 19 to 1862.
|
||||
Monkey gets bored with item. Worry level is divided by 3 to 620.
|
||||
Current worry level is not divisible by 23.
|
||||
Item with worry level 620 is thrown to monkey 3.
|
||||
Monkey 1:
|
||||
Monkey inspects an item with a worry level of 54.
|
||||
Worry level increases by 6 to 60.
|
||||
Monkey gets bored with item. Worry level is divided by 3 to 20.
|
||||
Current worry level is not divisible by 19.
|
||||
Item with worry level 20 is thrown to monkey 0.
|
||||
Monkey inspects an item with a worry level of 65.
|
||||
Worry level increases by 6 to 71.
|
||||
Monkey gets bored with item. Worry level is divided by 3 to 23.
|
||||
Current worry level is not divisible by 19.
|
||||
Item with worry level 23 is thrown to monkey 0.
|
||||
Monkey inspects an item with a worry level of 75.
|
||||
Worry level increases by 6 to 81.
|
||||
Monkey gets bored with item. Worry level is divided by 3 to 27.
|
||||
Current worry level is not divisible by 19.
|
||||
Item with worry level 27 is thrown to monkey 0.
|
||||
Monkey inspects an item with a worry level of 74.
|
||||
Worry level increases by 6 to 80.
|
||||
Monkey gets bored with item. Worry level is divided by 3 to 26.
|
||||
Current worry level is not divisible by 19.
|
||||
Item with worry level 26 is thrown to monkey 0.
|
||||
Monkey 2:
|
||||
Monkey inspects an item with a worry level of 79.
|
||||
Worry level is multiplied by itself to 6241.
|
||||
Monkey gets bored with item. Worry level is divided by 3 to 2080.
|
||||
Current worry level is divisible by 13.
|
||||
Item with worry level 2080 is thrown to monkey 1.
|
||||
Monkey inspects an item with a worry level of 60.
|
||||
Worry level is multiplied by itself to 3600.
|
||||
Monkey gets bored with item. Worry level is divided by 3 to 1200.
|
||||
Current worry level is not divisible by 13.
|
||||
Item with worry level 1200 is thrown to monkey 3.
|
||||
Monkey inspects an item with a worry level of 97.
|
||||
Worry level is multiplied by itself to 9409.
|
||||
Monkey gets bored with item. Worry level is divided by 3 to 3136.
|
||||
Current worry level is not divisible by 13.
|
||||
Item with worry level 3136 is thrown to monkey 3.
|
||||
Monkey 3:
|
||||
Monkey inspects an item with a worry level of 74.
|
||||
Worry level increases by 3 to 77.
|
||||
Monkey gets bored with item. Worry level is divided by 3 to 25.
|
||||
Current worry level is not divisible by 17.
|
||||
Item with worry level 25 is thrown to monkey 1.
|
||||
Monkey inspects an item with a worry level of 500.
|
||||
Worry level increases by 3 to 503.
|
||||
Monkey gets bored with item. Worry level is divided by 3 to 167.
|
||||
Current worry level is not divisible by 17.
|
||||
Item with worry level 167 is thrown to monkey 1.
|
||||
Monkey inspects an item with a worry level of 620.
|
||||
Worry level increases by 3 to 623.
|
||||
Monkey gets bored with item. Worry level is divided by 3 to 207.
|
||||
Current worry level is not divisible by 17.
|
||||
Item with worry level 207 is thrown to monkey 1.
|
||||
Monkey inspects an item with a worry level of 1200.
|
||||
Worry level increases by 3 to 1203.
|
||||
Monkey gets bored with item. Worry level is divided by 3 to 401.
|
||||
Current worry level is not divisible by 17.
|
||||
Item with worry level 401 is thrown to monkey 1.
|
||||
Monkey inspects an item with a worry level of 3136.
|
||||
Worry level increases by 3 to 3139.
|
||||
Monkey gets bored with item. Worry level is divided by 3 to 1046.
|
||||
Current worry level is not divisible by 17.
|
||||
Item with worry level 1046 is thrown to monkey 1.
|
||||
#+end_example
|
||||
|
||||
After round 1, the monkeys are holding items with these worry levels:
|
||||
|
||||
#+begin_example
|
||||
Monkey 0: 20, 23, 27, 26
|
||||
Monkey 1: 2080, 25, 167, 207, 401, 1046
|
||||
Monkey 2:
|
||||
Monkey 3:
|
||||
#+end_example
|
||||
|
||||
Monkeys 2 and 3 aren't holding any items at the end of the round; they
|
||||
both inspected items during the round and threw them all before the
|
||||
round ended.
|
||||
|
||||
This process continues for a few more rounds:
|
||||
|
||||
#+begin_example
|
||||
After round 2, the monkeys are holding items with these worry levels:
|
||||
Monkey 0: 695, 10, 71, 135, 350
|
||||
Monkey 1: 43, 49, 58, 55, 362
|
||||
Monkey 2:
|
||||
Monkey 3:
|
||||
|
||||
After round 3, the monkeys are holding items with these worry levels:
|
||||
Monkey 0: 16, 18, 21, 20, 122
|
||||
Monkey 1: 1468, 22, 150, 286, 739
|
||||
Monkey 2:
|
||||
Monkey 3:
|
||||
|
||||
After round 4, the monkeys are holding items with these worry levels:
|
||||
Monkey 0: 491, 9, 52, 97, 248, 34
|
||||
Monkey 1: 39, 45, 43, 258
|
||||
Monkey 2:
|
||||
Monkey 3:
|
||||
|
||||
After round 5, the monkeys are holding items with these worry levels:
|
||||
Monkey 0: 15, 17, 16, 88, 1037
|
||||
Monkey 1: 20, 110, 205, 524, 72
|
||||
Monkey 2:
|
||||
Monkey 3:
|
||||
|
||||
After round 6, the monkeys are holding items with these worry levels:
|
||||
Monkey 0: 8, 70, 176, 26, 34
|
||||
Monkey 1: 481, 32, 36, 186, 2190
|
||||
Monkey 2:
|
||||
Monkey 3:
|
||||
|
||||
After round 7, the monkeys are holding items with these worry levels:
|
||||
Monkey 0: 162, 12, 14, 64, 732, 17
|
||||
Monkey 1: 148, 372, 55, 72
|
||||
Monkey 2:
|
||||
Monkey 3:
|
||||
|
||||
After round 8, the monkeys are holding items with these worry levels:
|
||||
Monkey 0: 51, 126, 20, 26, 136
|
||||
Monkey 1: 343, 26, 30, 1546, 36
|
||||
Monkey 2:
|
||||
Monkey 3:
|
||||
|
||||
After round 9, the monkeys are holding items with these worry levels:
|
||||
Monkey 0: 116, 10, 12, 517, 14
|
||||
Monkey 1: 108, 267, 43, 55, 288
|
||||
Monkey 2:
|
||||
Monkey 3:
|
||||
|
||||
After round 10, the monkeys are holding items with these worry levels:
|
||||
Monkey 0: 91, 16, 20, 98
|
||||
Monkey 1: 481, 245, 22, 26, 1092, 30
|
||||
Monkey 2:
|
||||
Monkey 3:
|
||||
|
||||
...
|
||||
|
||||
After round 15, the monkeys are holding items with these worry levels:
|
||||
Monkey 0: 83, 44, 8, 184, 9, 20, 26, 102
|
||||
Monkey 1: 110, 36
|
||||
Monkey 2:
|
||||
Monkey 3:
|
||||
|
||||
...
|
||||
|
||||
After round 20, the monkeys are holding items with these worry levels:
|
||||
Monkey 0: 10, 12, 14, 26, 34
|
||||
Monkey 1: 245, 93, 53, 199, 115
|
||||
Monkey 2:
|
||||
Monkey 3:
|
||||
#+end_example
|
||||
|
||||
Chasing all of the monkeys at once is impossible; you're going to have
|
||||
to focus on the /two most active/ monkeys if you want any hope of
|
||||
getting your stuff back. Count the /total number of times each monkey
|
||||
inspects items/ over 20 rounds:
|
||||
|
||||
#+begin_example
|
||||
Monkey 0 inspected items 101 times.
|
||||
Monkey 1 inspected items 95 times.
|
||||
Monkey 2 inspected items 7 times.
|
||||
Monkey 3 inspected items 105 times.
|
||||
#+end_example
|
||||
|
||||
In this example, the two most active monkeys inspected items 101 and 105
|
||||
times. The level of /monkey business/ in this situation can be found by
|
||||
multiplying these together: =10605=.
|
||||
|
||||
Figure out which monkeys to chase by counting how many items they
|
||||
inspect over 20 rounds. /What is the level of monkey business after 20
|
||||
rounds of stuff-slinging simian shenanigans?/
|
||||
|
||||
Your puzzle answer was =54253=.
|
||||
|
||||
** --- Part Two ---
|
||||
You're worried you might not ever get your items back. So worried, in
|
||||
fact, that your relief that a monkey's inspection didn't damage an item
|
||||
/no longer causes your worry level to be divided by three/.
|
||||
|
||||
Unfortunately, that relief was all that was keeping your worry levels
|
||||
from reaching /ridiculous levels/. You'll need to /find another way to
|
||||
keep your worry levels manageable/.
|
||||
|
||||
At this rate, you might be putting up with these monkeys for a /very
|
||||
long time/ - possibly /=10000= rounds/!
|
||||
|
||||
With these new rules, you can still figure out the monkey business after
|
||||
10000 rounds. Using the same example above:
|
||||
|
||||
#+begin_example
|
||||
== After round 1 ==
|
||||
Monkey 0 inspected items 2 times.
|
||||
Monkey 1 inspected items 4 times.
|
||||
Monkey 2 inspected items 3 times.
|
||||
Monkey 3 inspected items 6 times.
|
||||
|
||||
== After round 20 ==
|
||||
Monkey 0 inspected items 99 times.
|
||||
Monkey 1 inspected items 97 times.
|
||||
Monkey 2 inspected items 8 times.
|
||||
Monkey 3 inspected items 103 times.
|
||||
|
||||
== After round 1000 ==
|
||||
Monkey 0 inspected items 5204 times.
|
||||
Monkey 1 inspected items 4792 times.
|
||||
Monkey 2 inspected items 199 times.
|
||||
Monkey 3 inspected items 5192 times.
|
||||
|
||||
== After round 2000 ==
|
||||
Monkey 0 inspected items 10419 times.
|
||||
Monkey 1 inspected items 9577 times.
|
||||
Monkey 2 inspected items 392 times.
|
||||
Monkey 3 inspected items 10391 times.
|
||||
|
||||
== After round 3000 ==
|
||||
Monkey 0 inspected items 15638 times.
|
||||
Monkey 1 inspected items 14358 times.
|
||||
Monkey 2 inspected items 587 times.
|
||||
Monkey 3 inspected items 15593 times.
|
||||
|
||||
== After round 4000 ==
|
||||
Monkey 0 inspected items 20858 times.
|
||||
Monkey 1 inspected items 19138 times.
|
||||
Monkey 2 inspected items 780 times.
|
||||
Monkey 3 inspected items 20797 times.
|
||||
|
||||
== After round 5000 ==
|
||||
Monkey 0 inspected items 26075 times.
|
||||
Monkey 1 inspected items 23921 times.
|
||||
Monkey 2 inspected items 974 times.
|
||||
Monkey 3 inspected items 26000 times.
|
||||
|
||||
== After round 6000 ==
|
||||
Monkey 0 inspected items 31294 times.
|
||||
Monkey 1 inspected items 28702 times.
|
||||
Monkey 2 inspected items 1165 times.
|
||||
Monkey 3 inspected items 31204 times.
|
||||
|
||||
== After round 7000 ==
|
||||
Monkey 0 inspected items 36508 times.
|
||||
Monkey 1 inspected items 33488 times.
|
||||
Monkey 2 inspected items 1360 times.
|
||||
Monkey 3 inspected items 36400 times.
|
||||
|
||||
== After round 8000 ==
|
||||
Monkey 0 inspected items 41728 times.
|
||||
Monkey 1 inspected items 38268 times.
|
||||
Monkey 2 inspected items 1553 times.
|
||||
Monkey 3 inspected items 41606 times.
|
||||
|
||||
== After round 9000 ==
|
||||
Monkey 0 inspected items 46945 times.
|
||||
Monkey 1 inspected items 43051 times.
|
||||
Monkey 2 inspected items 1746 times.
|
||||
Monkey 3 inspected items 46807 times.
|
||||
|
||||
== After round 10000 ==
|
||||
Monkey 0 inspected items 52166 times.
|
||||
Monkey 1 inspected items 47830 times.
|
||||
Monkey 2 inspected items 1938 times.
|
||||
Monkey 3 inspected items 52013 times.
|
||||
#+end_example
|
||||
|
||||
After 10000 rounds, the two most active monkeys inspected items 52166
|
||||
and 52013 times. Multiplying these together, the level of /monkey
|
||||
business/ in this situation is now =2713310158=.
|
||||
|
||||
Worry levels are no longer divided by three after each item is
|
||||
inspected; you'll need to find another way to keep your worry levels
|
||||
manageable. Starting again from the initial state in your puzzle input,
|
||||
/what is the level of monkey business after 10000 rounds?/
|
||||
|
||||
Your puzzle answer was =13119526120=.
|
||||
|
||||
Both parts of this puzzle are complete! They provide two gold stars: **
|
||||
164
2022/day11/aoc-c.c
Normal file
164
2022/day11/aoc-c.c
Normal file
@@ -0,0 +1,164 @@
|
||||
/* aoc-c.c: Advent of Code 2022, day 11
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "br.h"
|
||||
#include "debug.h"
|
||||
#include "list.h"
|
||||
#include "pool.h"
|
||||
|
||||
#include "aoc.h"
|
||||
|
||||
#define MAXMONKEYS 8
|
||||
|
||||
typedef struct monkey {
|
||||
char op; /* '+' or '*' */
|
||||
long values[2]; /* formula operands */
|
||||
uint visits; /* total visits */
|
||||
int div; /* divisor */
|
||||
struct list_head *dest[2]; /* destination monkey */
|
||||
struct list_head items; /* monkey items */
|
||||
} monkey_t;
|
||||
|
||||
typedef struct item {
|
||||
long item;
|
||||
struct list_head list;
|
||||
} item_t;
|
||||
|
||||
static pool_t *pool_item;
|
||||
|
||||
/* TODO: the following 3 variables should not be global
|
||||
*/
|
||||
static monkey_t monkeys[MAXMONKEYS];
|
||||
static int nmonkeys;
|
||||
static u64 lcm = 1;
|
||||
|
||||
static char *getnth(char *buf, int n)
|
||||
{
|
||||
char *ret;
|
||||
for (; n >= 0; n--) {
|
||||
ret = strtok(buf, " ,\n");
|
||||
buf = NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char *getnext()
|
||||
{
|
||||
return strtok(NULL, " ,\n");
|
||||
}
|
||||
|
||||
static int parse()
|
||||
{
|
||||
size_t alloc = 0;
|
||||
char *buf = NULL, *tok;
|
||||
monkey_t *m = monkeys;
|
||||
|
||||
while (getline(&buf, &alloc, stdin) > 0) {
|
||||
INIT_LIST_HEAD(&m->items);
|
||||
|
||||
getline(&buf, &alloc, stdin); /* starting items */
|
||||
tok = getnth(buf, 2);
|
||||
while (tok) {
|
||||
item_t *item = pool_get(pool_item);
|
||||
item->item = atoi(tok);
|
||||
list_add_tail(&item->list, &m->items);
|
||||
tok = getnext();
|
||||
}
|
||||
|
||||
getline(&buf, &alloc, stdin); /* operation */
|
||||
tok = getnth(buf, 3);
|
||||
m->values[0] = (*tok == 'o') ? -1: atoi(tok); /* first operand */
|
||||
m->op = *getnext(); /* operator */
|
||||
tok = getnext();
|
||||
m->values[1] = *tok == 'o' ? -1: atoi(tok); /* second operand */
|
||||
|
||||
getline(&buf, &alloc, stdin); /* divisible */
|
||||
m->div = atoi(getnth(buf, 3));
|
||||
lcm *= m->div;
|
||||
|
||||
getline(&buf, &alloc, stdin); /* true */
|
||||
m->dest[0] = &(monkeys + atoi(getnth(buf, 5)))->items;
|
||||
|
||||
getline(&buf, &alloc, stdin); /* false */
|
||||
m->dest[1] = &(monkeys + atoi(getnth(buf, 5)))->items;
|
||||
|
||||
getline(&buf, &alloc, stdin); /* skip empty line */
|
||||
|
||||
nmonkeys++;
|
||||
m++;
|
||||
}
|
||||
free(buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static __always_inline void inspect(monkey_t *m, int divide)
|
||||
{
|
||||
item_t *item, *tmp;
|
||||
long op1, op2;
|
||||
|
||||
list_for_each_entry_safe(item, tmp, &m->items, list) {
|
||||
m->visits++;
|
||||
/* I wonder if we could not find some mathematical properties to
|
||||
* simplify the following three lines
|
||||
*/
|
||||
op1 = m->values[0] < 0 ? item->item: m->values[0];
|
||||
op2 = m->values[1] < 0 ? item->item: m->values[1];
|
||||
item->item = (((m->op == '+')? op1 + op2: op1 * op2) / divide ) % lcm;
|
||||
list_move_tail(&item->list, m->dest[!!(item->item % m->div)]);
|
||||
}
|
||||
}
|
||||
|
||||
static u64 doit(int rounds, int divide)
|
||||
{
|
||||
u64 max1 = 0, max2 = 0;
|
||||
monkey_t *m = monkeys;
|
||||
|
||||
for (int r = 0; r < rounds; ++r)
|
||||
for (int i = 0; i < nmonkeys; ++i)
|
||||
inspect(monkeys + i, divide);
|
||||
|
||||
for (int i = 0; i < nmonkeys; ++i, m++) {
|
||||
if (m->visits > max1) {
|
||||
max2 = max1;
|
||||
max1 = m->visits;
|
||||
} else if (m->visits > max2) {
|
||||
max2 = m->visits;
|
||||
}
|
||||
}
|
||||
return max1 * max2;
|
||||
}
|
||||
|
||||
static u64 part1()
|
||||
{
|
||||
return doit(20, 3);
|
||||
}
|
||||
|
||||
static u64 part2()
|
||||
{
|
||||
return doit(10000, 1);
|
||||
}
|
||||
|
||||
|
||||
int main(int ac, char **av)
|
||||
{
|
||||
int part = parseargs(ac, av);
|
||||
pool_item = pool_create("item", 64, sizeof(item_t));
|
||||
|
||||
parse();
|
||||
printf("%s: res=%lu\n", *av, part == 1? part1(): part2());
|
||||
pool_destroy(pool_item);
|
||||
exit(0);
|
||||
}
|
||||
86
2022/day11/aoc.bash
Executable file
86
2022/day11/aoc.bash
Executable file
@@ -0,0 +1,86 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# aoc.bash: Advent of Code 2022, day 11
|
||||
#
|
||||
# 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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
|
||||
. common.bash
|
||||
|
||||
declare -ai div ttrue tfalse vis
|
||||
declare -a it # (1 2) is "1 2"
|
||||
declare -a op1 op op2
|
||||
declare -i lcm=1 monks=0 divisor=3
|
||||
|
||||
calc() {
|
||||
local -n _res="$1"
|
||||
local -i _m1=0 _m2=0 _i
|
||||
|
||||
for _i in "${vis[@]}"; do # find the 2 biggest numbers
|
||||
if ((_i > _m1)); then
|
||||
((_m2 = _m1, _m1 = _i))
|
||||
elif ((_i > _m2)); then
|
||||
((_m2 = _i))
|
||||
fi
|
||||
done
|
||||
(( _res = _m1 * _m2 ))
|
||||
}
|
||||
|
||||
parse() {
|
||||
local -a _it
|
||||
|
||||
while read -r; do # ignore Monkey number
|
||||
IFS=" :," read -ra _it # starting items
|
||||
it[$monks]="${_it[*]:2}"
|
||||
IFS=" :=" read -r _ _ op1[$monks] op[$monks] op2[$monks]
|
||||
[[ ${op[$monks]} == "+" ]] && unset "op[$monks]"
|
||||
[[ ${op1[$monks]} == old ]] && unset "op1[$monks]"
|
||||
[[ ${op2[$monks]} == old ]] && unset "op2[$monks]"
|
||||
IFS=" :=" read -r _ _ _ div[$monks] # divisor
|
||||
(( lcm *= div[monks] ))
|
||||
read -r _ _ _ _ _ ttrue[$monks] # throw if true
|
||||
read -r _ _ _ _ _ tfalse[$monks]
|
||||
read -r
|
||||
(( monks++ ))
|
||||
done
|
||||
}
|
||||
|
||||
solve() {
|
||||
local -i _loops=20 round m _op1 _op2 i
|
||||
|
||||
(( part == 2 )) && (( _loops = 10000, divisor = 1 ))
|
||||
for ((round = 0; round < _loops; ++round)); do
|
||||
for ((m = 0; m < monks; ++m)); do
|
||||
_op1=${op1[$m]}
|
||||
_op2=${op2[$m]}
|
||||
|
||||
# shellcheck disable=SC2068
|
||||
for i in ${it[$m]}; do
|
||||
(( vis[m]++ ))
|
||||
[[ -v op1[$m] ]] || _op1=$i
|
||||
[[ -v op2[$m] ]] || _op2=$i
|
||||
if [[ -v op[$m] ]]; then
|
||||
(( _tmp = (_op1 * _op2) / divisor % lcm ))
|
||||
else
|
||||
(( _tmp = (_op1 + _op2) / divisor % lcm ))
|
||||
fi
|
||||
if (( _tmp % div[m] )); then
|
||||
it[${tfalse[$m]}]+=" $_tmp"
|
||||
else
|
||||
it[${ttrue[$m]}]+=" $_tmp"
|
||||
fi
|
||||
done
|
||||
it[$m]=""
|
||||
done
|
||||
done
|
||||
calc res
|
||||
}
|
||||
|
||||
main "$@"
|
||||
exit 0
|
||||
17
2022/day11/aoc.h
Normal file
17
2022/day11/aoc.h
Normal file
@@ -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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
#ifndef _AOC_H_
|
||||
#define _AOC_H_
|
||||
|
||||
extern int parseargs(int ac, char**av);
|
||||
|
||||
#endif /* _AOC_H_ */
|
||||
68
2022/day11/common.bash
Normal file
68
2022/day11/common.bash
Normal file
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# common.bash: Advent of Code 2022, common bash 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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
|
||||
# shellcheck disable=2034
|
||||
export cmdname=${0##*/}
|
||||
export debug=0
|
||||
export res
|
||||
export LANG=C
|
||||
|
||||
shopt -s extglob
|
||||
set -o noglob
|
||||
|
||||
usage() {
|
||||
printf "usage: %s [-d DEBUG] [-p PART]\n" "$cmdname"
|
||||
exit 1
|
||||
}
|
||||
|
||||
checkargs() {
|
||||
local part=1
|
||||
while getopts p:d: todo; do
|
||||
case "$todo" in
|
||||
d)
|
||||
if [[ "$OPTARG" =~ ^[[:digit:]+]$ ]]; then
|
||||
debug="$OPTARG"
|
||||
else
|
||||
printf "%s: illegal [%s] debug level.\n" "$CMD" "$OPTARG"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
p)
|
||||
if [[ "$OPTARG" =~ ^[12]$ ]]; then
|
||||
part="$OPTARG"
|
||||
else
|
||||
printf "%s: illegal [%s] part.\n" "$CMD" "$OPTARG"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
# Now check remaining argument (backup directory)
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
(( $# > 1 )) && usage
|
||||
return "$part"
|
||||
}
|
||||
|
||||
main() {
|
||||
local -i part
|
||||
|
||||
checkargs "$@"
|
||||
part=$?
|
||||
parse "$part"
|
||||
solve "$part"
|
||||
printf "%s: res=%s\n" "$cmdname" "$res"
|
||||
}
|
||||
49
2022/day11/common.c
Normal file
49
2022/day11/common.c
Normal file
@@ -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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
27
2022/day11/input/example.txt
Normal file
27
2022/day11/input/example.txt
Normal file
@@ -0,0 +1,27 @@
|
||||
Monkey 0:
|
||||
Starting items: 79, 98
|
||||
Operation: new = old * 19
|
||||
Test: divisible by 23
|
||||
If true: throw to monkey 2
|
||||
If false: throw to monkey 3
|
||||
|
||||
Monkey 1:
|
||||
Starting items: 54, 65, 75, 74
|
||||
Operation: new = old + 6
|
||||
Test: divisible by 19
|
||||
If true: throw to monkey 2
|
||||
If false: throw to monkey 0
|
||||
|
||||
Monkey 2:
|
||||
Starting items: 79, 60, 97
|
||||
Operation: new = old * old
|
||||
Test: divisible by 13
|
||||
If true: throw to monkey 1
|
||||
If false: throw to monkey 3
|
||||
|
||||
Monkey 3:
|
||||
Starting items: 74
|
||||
Operation: new = old + 3
|
||||
Test: divisible by 17
|
||||
If true: throw to monkey 0
|
||||
If false: throw to monkey 1
|
||||
55
2022/day11/input/input.txt
Normal file
55
2022/day11/input/input.txt
Normal file
@@ -0,0 +1,55 @@
|
||||
Monkey 0:
|
||||
Starting items: 98, 70, 75, 80, 84, 89, 55, 98
|
||||
Operation: new = old * 2
|
||||
Test: divisible by 11
|
||||
If true: throw to monkey 1
|
||||
If false: throw to monkey 4
|
||||
|
||||
Monkey 1:
|
||||
Starting items: 59
|
||||
Operation: new = old * old
|
||||
Test: divisible by 19
|
||||
If true: throw to monkey 7
|
||||
If false: throw to monkey 3
|
||||
|
||||
Monkey 2:
|
||||
Starting items: 77, 95, 54, 65, 89
|
||||
Operation: new = old + 6
|
||||
Test: divisible by 7
|
||||
If true: throw to monkey 0
|
||||
If false: throw to monkey 5
|
||||
|
||||
Monkey 3:
|
||||
Starting items: 71, 64, 75
|
||||
Operation: new = old + 2
|
||||
Test: divisible by 17
|
||||
If true: throw to monkey 6
|
||||
If false: throw to monkey 2
|
||||
|
||||
Monkey 4:
|
||||
Starting items: 74, 55, 87, 98
|
||||
Operation: new = old * 11
|
||||
Test: divisible by 3
|
||||
If true: throw to monkey 1
|
||||
If false: throw to monkey 7
|
||||
|
||||
Monkey 5:
|
||||
Starting items: 90, 98, 85, 52, 91, 60
|
||||
Operation: new = old + 7
|
||||
Test: divisible by 5
|
||||
If true: throw to monkey 0
|
||||
If false: throw to monkey 4
|
||||
|
||||
Monkey 6:
|
||||
Starting items: 99, 51
|
||||
Operation: new = old + 1
|
||||
Test: divisible by 13
|
||||
If true: throw to monkey 5
|
||||
If false: throw to monkey 2
|
||||
|
||||
Monkey 7:
|
||||
Starting items: 98, 94, 59, 76, 51, 65, 75
|
||||
Operation: new = old + 5
|
||||
Test: divisible by 2
|
||||
If true: throw to monkey 3
|
||||
If false: throw to monkey 6
|
||||
114
2022/day12/Makefile
Normal file
114
2022/day12/Makefile
Normal file
@@ -0,0 +1,114 @@
|
||||
# AOC daily Makefile - GNU make only.
|
||||
#
|
||||
# Copyright (C) 2021-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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
#
|
||||
|
||||
INPUT := input/input.txt
|
||||
SHELL := /bin/bash
|
||||
|
||||
CC := gcc
|
||||
BEAR := bear
|
||||
CCLSFILE:= compile_commands.json
|
||||
|
||||
LIB := aoc_$(shell uname -m)
|
||||
INCDIR := ../include
|
||||
LIBDIR := ../lib
|
||||
LDFLAGS := -L$(LIBDIR)
|
||||
#LDLIB := -l$(LIB) -lm
|
||||
LDLIB := -l$(LIB)
|
||||
|
||||
export LD_LIBRARY_PATH = $(LIBDIR)
|
||||
|
||||
CFLAGS += -std=gnu11
|
||||
CFLAGS += -O2
|
||||
#CFLAGS += -g
|
||||
# for gprof
|
||||
# CFLAGS += -pg
|
||||
CFLAGS += -Wall
|
||||
CFLAGS += -Wextra
|
||||
CFLAGS += -march=native
|
||||
# Next one may be useful for valgrind (some invalid instructions)
|
||||
# CFLAGS += -mno-tbm
|
||||
CFLAGS += -Wmissing-declarations
|
||||
CFLAGS += -Wno-unused-result
|
||||
|
||||
CFLAGS += -DDEBUG_DEBUG # activate general debug (debug.c)
|
||||
CFLAGS += -DDEBUG_POOL # memory pools management
|
||||
|
||||
VALGRIND := valgrind
|
||||
VALGRINDFLAGS := --leak-check=full --show-leak-kinds=all --track-origins=yes \
|
||||
--sigill-diagnostics=yes --quiet --show-error-list=yes
|
||||
|
||||
|
||||
TIME := \time -f "\ttime: %E real, %U user, %S sys\n\tcontext-switch:\t%c+%w, page-faults: %F+%R\n"
|
||||
export PATH := .:$(PATH)
|
||||
|
||||
.PHONY: clean cleanall all compile assembly memcheck memcheck1 memcheck2 part1 part2 ccls bear org
|
||||
|
||||
all: README.org ccls part1 part2
|
||||
|
||||
memcheck: memcheck1 memcheck2
|
||||
|
||||
memcheck1: aoc-c
|
||||
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 1 < $(INPUT)
|
||||
|
||||
memcheck2: aoc-c
|
||||
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 2 < $(INPUT)
|
||||
@#@valgrind -s --track-origins=yes aoc-c -p 2 < $(INPUT)
|
||||
|
||||
compile: aoc-c
|
||||
|
||||
cpp: aoc-c.i
|
||||
|
||||
assembly: aoc-c.s
|
||||
|
||||
part1: aoc-c
|
||||
@$(TIME) aoc.bash -p 1 < $(INPUT) 2>&1
|
||||
@$(TIME) aoc-c -p 1 < $(INPUT)
|
||||
|
||||
part2: aoc-c
|
||||
@$(TIME) aoc.bash -p 2 < $(INPUT) 2>&1
|
||||
@$(TIME) aoc-c -p 2 < $(INPUT)
|
||||
|
||||
ccls: $(CCLSFILE)
|
||||
|
||||
clean:
|
||||
@rm -f aoc-c core* vgcore* gmon.out aoc-c.s aoc-c.i README.html
|
||||
|
||||
cleanall: clean
|
||||
@rm -f compile_commands.json
|
||||
|
||||
aoc-c: aoc-c.c common.c
|
||||
@echo compiling $<
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -I $(INCDIR) $^ $(LDLIB) -o $@
|
||||
|
||||
# generate pre-processed file (.i) and assembler (.s)
|
||||
%.i: %.c
|
||||
@echo generating $@
|
||||
@$(CC) -E $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||
|
||||
%.s: %.c
|
||||
@echo generating $@
|
||||
@$(CC) -S -fverbose-asm $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||
|
||||
# generate README.org from README.html (must cleanup !)
|
||||
org: README.org
|
||||
|
||||
%.org: %.html
|
||||
@echo generating $@. Cleanup before commit !
|
||||
@pandoc $< -o $@
|
||||
|
||||
# generate compile_commands.json
|
||||
$(CCLSFILE): aoc-c.c Makefile
|
||||
$(BEAR) -- make clean compile
|
||||
|
||||
bear: clean
|
||||
@touch .ccls-root
|
||||
@$(BEAR) -- make compile
|
||||
100
2022/day12/README.org
Normal file
100
2022/day12/README.org
Normal file
@@ -0,0 +1,100 @@
|
||||
** --- Day 12: Hill Climbing Algorithm ---
|
||||
You try contacting the Elves using your handheld device, but the river
|
||||
you're following must be too low to get a decent signal.
|
||||
|
||||
You ask the device for a heightmap of the surrounding area (your puzzle
|
||||
input). The heightmap shows the local area from above broken into a
|
||||
grid; the elevation of each square of the grid is given by a single
|
||||
lowercase letter, where =a= is the lowest elevation, =b= is the
|
||||
next-lowest, and so on up to the highest elevation, =z=.
|
||||
|
||||
Also included on the heightmap are marks for your current position (=S=)
|
||||
and the location that should get the best signal (=E=). Your current
|
||||
position (=S=) has elevation =a=, and the location that should get the
|
||||
best signal (=E=) has elevation =z=.
|
||||
|
||||
You'd like to reach =E=, but to save energy, you should do it in /as few
|
||||
steps as possible/. During each step, you can move exactly one square
|
||||
up, down, left, or right. To avoid needing to get out your climbing
|
||||
gear, the elevation of the destination square can be /at most one
|
||||
higher/ than the elevation of your current square; that is, if your
|
||||
current elevation is =m=, you could step to elevation =n=, but not to
|
||||
elevation =o=. (This also means that the elevation of the destination
|
||||
square can be much lower than the elevation of your current square.)
|
||||
|
||||
For example:
|
||||
|
||||
#+begin_example
|
||||
Sabqponm
|
||||
abcryxxl
|
||||
accszExk
|
||||
acctuvwj
|
||||
abdefghi
|
||||
#+end_example
|
||||
|
||||
Here, you start in the top-left corner; your goal is near the middle.
|
||||
You could start by moving down or right, but eventually you'll need to
|
||||
head toward the =e= at the bottom. From there, you can spiral around to
|
||||
the goal:
|
||||
|
||||
#+begin_example
|
||||
v..v<<<<
|
||||
>v.vv<<^
|
||||
.>vv>E^^
|
||||
..v>>>^^
|
||||
..>>>>>^
|
||||
#+end_example
|
||||
|
||||
In the above diagram, the symbols indicate whether the path exits each
|
||||
square moving up (=^=), down (=v=), left (=<=), or right (=>=). The
|
||||
location that should get the best signal is still =E=, and =.= marks
|
||||
unvisited squares.
|
||||
|
||||
This path reaches the goal in =31= steps, the fewest possible.
|
||||
|
||||
/What is the fewest steps required to move from your current position to
|
||||
the location that should get the best signal?/
|
||||
|
||||
Your puzzle answer was =408=.
|
||||
|
||||
** --- Part Two ---
|
||||
As you walk up the hill, you suspect that the Elves will want to turn
|
||||
this into a hiking trail. The beginning isn't very scenic, though;
|
||||
perhaps you can find a better starting point.
|
||||
|
||||
To maximize exercise while hiking, the trail should start as low as
|
||||
possible: elevation =a=. The goal is still the square marked =E=.
|
||||
However, the trail should still be direct, taking the fewest steps to
|
||||
reach its goal. So, you'll need to find the shortest path from /any
|
||||
square at elevation =a=/ to the square marked =E=.
|
||||
|
||||
Again consider the example from above:
|
||||
|
||||
#+begin_example
|
||||
Sabqponm
|
||||
abcryxxl
|
||||
accszExk
|
||||
acctuvwj
|
||||
abdefghi
|
||||
#+end_example
|
||||
|
||||
Now, there are six choices for starting position (five marked =a=, plus
|
||||
the square marked =S= that counts as being at elevation =a=). If you
|
||||
start at the bottom-left square, you can reach the goal most quickly:
|
||||
|
||||
#+begin_example
|
||||
...v<<<<
|
||||
...vv<<^
|
||||
...v>E^^
|
||||
.>v>>>^^
|
||||
>^>>>>>^
|
||||
#+end_example
|
||||
|
||||
This path reaches the goal in only =29= steps, the fewest possible.
|
||||
|
||||
/What is the fewest steps required to move starting from any square with
|
||||
elevation =a= to the location that should get the best signal?/
|
||||
|
||||
Your puzzle answer was =399=.
|
||||
|
||||
Both parts of this puzzle are complete! They provide two gold stars: **
|
||||
172
2022/day12/aoc-c.c
Normal file
172
2022/day12/aoc-c.c
Normal file
@@ -0,0 +1,172 @@
|
||||
/* aoc-c.c: Advent of Code 2022, day 12
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "br.h"
|
||||
#include "list.h"
|
||||
#include "pool.h"
|
||||
|
||||
#include "aoc.h"
|
||||
|
||||
#define MAX_LINES 128 /* should be dynamic */
|
||||
|
||||
typedef struct coord {
|
||||
int x, y;
|
||||
} coord_t;
|
||||
|
||||
typedef struct square {
|
||||
char height;
|
||||
int dfs;
|
||||
coord_t coord;
|
||||
struct list_head queue;
|
||||
} square_t;
|
||||
|
||||
typedef struct grid {
|
||||
int nx, ny;
|
||||
coord_t start, end;
|
||||
|
||||
square_t **map;
|
||||
} grid_t;
|
||||
|
||||
pool_t *pool_lines;
|
||||
LIST_HEAD(dfs);
|
||||
|
||||
#define CELL(g, x, y) (&(g)->map[y][x])
|
||||
|
||||
static inline void push(square_t *s)
|
||||
{
|
||||
list_add_tail(&s->queue, &dfs);
|
||||
}
|
||||
|
||||
static inline square_t *pop()
|
||||
{
|
||||
square_t *s = list_first_entry_or_null(&dfs, square_t, queue);
|
||||
if (s)
|
||||
list_del(&s->queue);
|
||||
return s;
|
||||
}
|
||||
|
||||
static int parse(grid_t *grid)
|
||||
{
|
||||
size_t alloc = 0;
|
||||
ssize_t buflen;
|
||||
char *buf = NULL;
|
||||
int line = 0;
|
||||
square_t *pline;
|
||||
|
||||
while ((buflen = getline(&buf, &alloc, stdin)) > 0) {
|
||||
buf[--buflen] = 0;
|
||||
if (line == 0) {
|
||||
pool_lines = pool_create("lines", 128, buflen * sizeof(square_t));
|
||||
grid->nx = buflen;
|
||||
}
|
||||
grid->map[line] = pool_get(pool_lines);
|
||||
pline = grid->map[line];
|
||||
for (int i = 0; i < buflen; ++i) {
|
||||
pline[i].coord.x = i;
|
||||
pline[i].coord.y = line;
|
||||
pline[i].dfs = 0;
|
||||
if (buf[i] == 'S') {
|
||||
grid->start.x = i;
|
||||
grid->start.y = line;
|
||||
pline[i].height = 'a';
|
||||
} else if (buf[i] == 'E') {
|
||||
grid->end.x = i;
|
||||
grid->end.y = line;
|
||||
pline[i].height = 'z';
|
||||
} else {
|
||||
pline[i].height = buf[i];
|
||||
}
|
||||
}
|
||||
line++;
|
||||
}
|
||||
grid->ny = line;
|
||||
free(buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static square_t *dfs_add(grid_t *g, square_t *s, int n)
|
||||
{
|
||||
static coord_t dirs[4] = { { 0, -1 }, { 1, 0 }, { 0, 1 }, { -1, 0 } };
|
||||
int x = s->coord.x + dirs[n].x, y = s->coord.y + dirs[n].y;
|
||||
square_t *ret = NULL;
|
||||
if (x >= 0 && y >= 0 && x < g->nx && y < g->ny) {
|
||||
ret = CELL(g, x, y);
|
||||
if (!ret->dfs)
|
||||
return ret;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int part1(grid_t *g)
|
||||
{
|
||||
square_t *s, *n;
|
||||
|
||||
s = CELL(g, g->start.x, g->start.y);
|
||||
s->dfs = 1;
|
||||
push(s);
|
||||
while((s = pop())) {
|
||||
//log_f(3, "");
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (!(n = dfs_add(g, s, i)))
|
||||
continue;
|
||||
if (n->height <= s->height+1) {
|
||||
if (n->coord.x == g->end.x && n->coord.y == g->end.y)
|
||||
return s->dfs;
|
||||
n->dfs = s->dfs + 1;
|
||||
push(n);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int part2(grid_t *g)
|
||||
{
|
||||
square_t *s, *n;
|
||||
//int ret = 0;
|
||||
s = CELL(g, g->end.x, g->end.y);
|
||||
s->dfs = 1;
|
||||
push(s);
|
||||
while((s = pop())) {
|
||||
//log_f(3, "");
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (!(n = dfs_add(g, s, i)))
|
||||
continue;
|
||||
if (n->height >= s->height - 1) {
|
||||
if (n->height == 'a')
|
||||
return s->dfs;
|
||||
n->dfs = s->dfs + 1;
|
||||
push(n);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int main(int ac, char **av)
|
||||
{
|
||||
int part = parseargs(ac, av);
|
||||
square_t *board[MAX_LINES];
|
||||
grid_t grid = { 0, 0, { 0, 0 }, {0, 0}, board };
|
||||
|
||||
parse(&grid);
|
||||
printf("%s: res=%d\n", *av, part == 1? part1(&grid): part2(&grid));
|
||||
pool_destroy(pool_lines);
|
||||
exit(0);
|
||||
}
|
||||
146
2022/day12/aoc.bash
Executable file
146
2022/day12/aoc.bash
Executable file
@@ -0,0 +1,146 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# aoc.bash: Advent of Code 2022, day 12
|
||||
#
|
||||
# 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 <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
|
||||
. common.bash
|
||||
|
||||
#declare -a map map2
|
||||
declare -A height map visited
|
||||
declare -i X Y
|
||||
declare start end push=push1
|
||||
declare -a queue
|
||||
|
||||
printmap() {
|
||||
local -i x y
|
||||
for (( y = 0; y < Y; ++y )); do
|
||||
for (( x = 0; x < X; ++x )); do
|
||||
printf "%2d " "${map["$x,$y"]}"
|
||||
done
|
||||
echo
|
||||
done
|
||||
}
|
||||
|
||||
printvis() {
|
||||
local -i x y
|
||||
for (( y = 0; y < Y; ++y )); do
|
||||
for (( x = 0; x < X; ++x )); do
|
||||
printf "%2d " "${visited["$x,$y"]}"
|
||||
done
|
||||
echo
|
||||
done
|
||||
}
|
||||
|
||||
push1() { # push part 1
|
||||
local -i _d="$1" _x="$2" _y="$3" _h="$4"
|
||||
local _c="$_x,$_y"
|
||||
if (( !visited[$_c] && map[$_c] <= (_h + 1) )); then
|
||||
(( _d++ ))
|
||||
visited["$_c"]=$_d
|
||||
queue+=("$_d:$_c")
|
||||
fi
|
||||
}
|
||||
|
||||
push2() { # push part 2
|
||||
local -i _d="$1" _x="$2" _y="$3" _h="$4"
|
||||
local _c="$_x,$_y"
|
||||
if (( !visited[$_c] && map[$_c] >= (_h - 1) )); then
|
||||
(( _d++ ))
|
||||
visited["$_c"]=$_d
|
||||
queue+=("$_d:$_c")
|
||||
fi
|
||||
}
|
||||
|
||||
pop() {
|
||||
local -n _d="$1" _x="$2" _y="$3"
|
||||
local head
|
||||
((!${#queue[@]})) && echo pop: queue empty. && exit 1
|
||||
head="${queue[0]}"
|
||||
_d=${head%:*}
|
||||
head=${head#*:}
|
||||
_x=${head%,*}
|
||||
_y=${head#*,}
|
||||
unset 'queue[0]'
|
||||
queue=("${queue[@]}")
|
||||
return 0
|
||||
}
|
||||
|
||||
# initialize height values
|
||||
init() {
|
||||
declare -i i=1
|
||||
for c in {a..z}; do
|
||||
(( height[$c] = i++ ))
|
||||
done
|
||||
height[S]=1
|
||||
height[E]=26
|
||||
}
|
||||
|
||||
parse() {
|
||||
local -i part="$1"
|
||||
local -a _map
|
||||
local -i x y
|
||||
local c
|
||||
((part == 2)) && push=push2
|
||||
|
||||
init
|
||||
readarray -t _map
|
||||
X=${#_map[0]}
|
||||
Y=${#_map[@]}
|
||||
# create array map[x,y]
|
||||
for (( y = 0; y < Y; ++y )); do
|
||||
for (( x = 0; x < X; ++x )); do
|
||||
c=${_map[$y]:x:1}
|
||||
map["$x,$y"]=${height[$c]}
|
||||
case "$c" in
|
||||
S) start="$x,$y"
|
||||
((part == 1)) && $push 0 "$x" "$y" 1
|
||||
;;
|
||||
E) end="$x,$y"
|
||||
((part == 2)) && $push 0 "$x" "$y" 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
solve() {
|
||||
local -i h d x y
|
||||
|
||||
while pop d x y; do
|
||||
(( h=${map["$x,$y"]} ))
|
||||
if [[ $part == 1 ]]; then
|
||||
if [[ "$x,$y" == "$end" ]]; then
|
||||
res=$((d-1))
|
||||
return
|
||||
fi
|
||||
else
|
||||
if [[ "${map["$x,$y"]}" == 1 ]]; then
|
||||
res=$((d-1))
|
||||
return
|
||||
fi
|
||||
fi
|
||||
if ((y > 0)); then # north
|
||||
$push "$d" "$x" "$((y-1))" "$h"
|
||||
fi
|
||||
if ((x+1 < X)); then # east
|
||||
$push "$d" "$((x+1))" "$y" "$h"
|
||||
fi
|
||||
if ((y+1 < Y)); then # south
|
||||
$push "$d" "$x" "$((y+1))" "$h"
|
||||
fi
|
||||
if ((x > 0)); then # west
|
||||
$push "$d" "$((x-1))" "$y" "$h"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
main "$@"
|
||||
exit 0
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user