2022 day 7: clean bash code & remove file size info (50% speed)

This commit is contained in:
2022-12-09 20:34:05 +01:00
parent 8b68bf4449
commit 16da47600c
2 changed files with 18 additions and 41 deletions

View File

@@ -129,3 +129,17 @@ aoc.bash: res=2260
aoc-c: res=2260 aoc-c: res=2260
time: 0:00.00 real, 0.00 user, 0.00 sys time: 0:00.00 real, 0.00 user, 0.00 sys
context-switch: 0+1, page-faults: 0+87 context-switch: 0+1, page-faults: 0+87
=========================================
================= day07 =================
=========================================
+++++++++++++++++ part 1
aoc.bash: res=1390824
time: 0:00.10 real, 0.07 user, 0.03 sys
context-switch: 8+1, page-faults: 0+312
+++++++++++++++++ part 2
aoc.bash: res=7490863
time: 0:00.10 real, 0.08 user, 0.01 sys
context-switch: 8+1, page-faults: 0+317

View File

@@ -13,31 +13,18 @@
. common.bash . common.bash
declare -A files=() # list of files in dir
declare -A sizes=() # file size declare -A sizes=() # file size
declare -A dirs=() # directories declare -A dirs=() # directories
declare -a lines # shell lines declare -a lines # shell lines
declare -i curline=0 # current line in shell declare -i curline=0 # current line in shell
declare curdir declare curdir
print_sizes() {
local idx
echo +++++++++++++++++++
for idx in "${!sizes[@]}"; do
printf "size(%s)=%d\n" "$idx" "${sizes[$idx]}"
done
echo +++++++++++++++++++
}
do_cd() { do_cd() {
local dir="$1" local dir="$1"
echo ">>> $curline ${lines[$curline]}"
case "$dir" in case "$dir" in
"..") "..")
echo ".. before: $curdir"
curdir=${curdir%/*} curdir=${curdir%/*}
[[ -z $curdir ]] && curdir="/" [[ -z $curdir ]] && curdir="/"
echo ".. after: $curdir"
;; ;;
"/") "/")
curdir="/" curdir="/"
@@ -47,37 +34,25 @@ do_cd() {
curdir+="$dir" curdir+="$dir"
esac esac
dirs[$curdir]="$curdir" dirs[$curdir]="$curdir"
echo "> CD $dir newdir=$curdir"
} }
do_ls() { do_ls() {
local info file subdir remain local info file remain
echo ">>> $curline ${lines[$curline]}"
((curline++)) ((curline++))
while [[ $curline -lt ${#lines[@]} && ${lines[$curline]:0:1} != "\$" ]]; do while [[ $curline -lt ${#lines[@]} && ${lines[$curline]:0:1} != "\$" ]]; do
read -r info file <<< "${lines[$curline]}" read -r info file <<< "${lines[$curline]}"
files[$curdir]+="$file"
if [[ $info != dir ]]; then # file if [[ $info != dir ]]; then # file
remain="$curdir/$file" remain="$curdir/$file"
remain=${remain//+(\/)/\/} remain=${remain//+(\/)/\/}
#sizes[$fullname]=$info while [[ -n $remain ]]; do # recurse up curdir and adjust sizes
# recurse up curdir and adjust sizes
#subdir=${curdir}
echo "info=$info [$remain]"
while [[ -n $remain ]]; do
echo "remain=$remain subdir=$subdir"
((sizes[$remain] += info)) ((sizes[$remain] += info))
remain=${remain%/*} remain=${remain%/*}
subdir=${remain##*/}
echo " -> remain=$remain subdir=$subdir"
done done
(( sizes["/"] += info )) (( sizes["/"] += info ))
fi fi
echo "ls: ${lines[$curline]}"
((curline++)) ((curline++))
done done
((curline--)) ((curline--))
print_sizes
} }
parse() { parse() {
@@ -87,10 +62,6 @@ parse() {
while ((curline < ${#lines[@]})); do while ((curline < ${#lines[@]})); do
read -ra line <<< "${lines[$curline]}" read -ra line <<< "${lines[$curline]}"
if [[ "${line[0]}" != "\$" ]]; then
printf "ERROR line %d = %s\n" "$curline" "${lines[$curline]}"
exit 1
fi
case "${line[1]}" in case "${line[1]}" in
"cd") "cd")
do_cd "${line[2]}" do_cd "${line[2]}"
@@ -100,7 +71,6 @@ parse() {
;; ;;
esac esac
((curline++)) ((curline++))
printf "WARNING curline=%d\n lines=%d\n" "$curline" "${#lines[@]}"
done done
} }
@@ -111,23 +81,16 @@ solve() {
if ((part == 1)); then if ((part == 1)); then
for dir in "${dirs[@]}"; do for dir in "${dirs[@]}"; do
printf "size(%s)=%d\n" "$dir" "${sizes[$dir]}" ((sizes[$dir] <= 100000 )) && ((res+=sizes[$dir]))
if ((sizes[$dir] <= 100000 )); then
((res+=sizes[$dir]))
fi
done done
else else
(( res = sizes["/"] ))
(( needed = sizes["/"] - (70000000-30000000) )) (( needed = sizes["/"] - (70000000-30000000) ))
printf "remain=%d\n" "$needed"
((res = sizes["/"]))
for dir in "${!dirs[@]}"; do for dir in "${!dirs[@]}"; do
#printf "size(%s)=%d\n" "$dir" "${sizes[$dir]}"
if (( sizes[$dir] >= needed )); then if (( sizes[$dir] >= needed )); then
printf "dir %s (%d) will free enough res=%d\n" "$dir" "${sizes[$dir]}" "$res"
if (( sizes[$dir] <= res )); then if (( sizes[$dir] <= res )); then
mindir=$dir mindir=$dir
((res = sizes[$mindir])) ((res = sizes[$mindir]))
printf "new mindir=%s (%d)\n" "$mindir" "$res"
fi fi
fi fi
done done