2022 day 7: Bash parts 1 and 2 (messy, tons of debug)
This commit is contained in:
@@ -118,10 +118,39 @@ files more than once!)
|
|||||||
Find all of the directories with a total size of at most 100000. /What
|
Find all of the directories with a total size of at most 100000. /What
|
||||||
is the sum of the total sizes of those directories?/
|
is the sum of the total sizes of those directories?/
|
||||||
|
|
||||||
To begin, [[file:7/input][get your puzzle input]].
|
Your puzzle answer was =1390824=.
|
||||||
|
|
||||||
Answer:
|
** --- Part Two ---
|
||||||
|
Now, you're ready to choose a directory to delete.
|
||||||
|
|
||||||
You can also [Shareon
|
The total disk space available to the filesystem is =70000000=. To run
|
||||||
[[https://twitter.com/intent/tweet?text=%22No+Space+Left+On+Device%22+%2D+Day+7+%2D+Advent+of+Code+2022&url=https%3A%2F%2Fadventofcode%2Ecom%2F2022%2Fday%2F7&related=ericwastl&hashtags=AdventOfCode][Twitter]]
|
the update, you need unused space of at least =30000000=. You need to
|
||||||
[[javascript:void(0);][Mastodon]]] this puzzle.
|
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: **
|
||||||
|
139
2022/day07/aoc.bash
Executable file
139
2022/day07/aoc.bash
Executable file
@@ -0,0 +1,139 @@
|
|||||||
|
#!/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 files=() # list of files in dir
|
||||||
|
declare -A sizes=() # file size
|
||||||
|
declare -A dirs=() # directories
|
||||||
|
declare -a lines # shell lines
|
||||||
|
declare -i curline=0 # current line in shell
|
||||||
|
declare curdir
|
||||||
|
|
||||||
|
print_sizes() {
|
||||||
|
local idx
|
||||||
|
echo +++++++++++++++++++
|
||||||
|
for idx in "${!sizes[@]}"; do
|
||||||
|
printf "size(%s)=%d\n" "$idx" "${sizes[$idx]}"
|
||||||
|
done
|
||||||
|
echo +++++++++++++++++++
|
||||||
|
}
|
||||||
|
|
||||||
|
do_cd() {
|
||||||
|
local dir="$1"
|
||||||
|
echo ">>> $curline ${lines[$curline]}"
|
||||||
|
case "$dir" in
|
||||||
|
"..")
|
||||||
|
echo ".. before: $curdir"
|
||||||
|
curdir=${curdir%/*}
|
||||||
|
[[ -z $curdir ]] && curdir="/"
|
||||||
|
echo ".. after: $curdir"
|
||||||
|
;;
|
||||||
|
"/")
|
||||||
|
curdir="/"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
[[ $curdir != "/" ]] && curdir+="/"
|
||||||
|
curdir+="$dir"
|
||||||
|
esac
|
||||||
|
dirs[$curdir]="$curdir"
|
||||||
|
echo "> CD $dir newdir=$curdir"
|
||||||
|
}
|
||||||
|
|
||||||
|
do_ls() {
|
||||||
|
local info file subdir remain
|
||||||
|
echo ">>> $curline ${lines[$curline]}"
|
||||||
|
((curline++))
|
||||||
|
while [[ $curline -lt ${#lines[@]} && ${lines[$curline]:0:1} != "\$" ]]; do
|
||||||
|
read -r info file <<< "${lines[$curline]}"
|
||||||
|
files[$curdir]+="$file"
|
||||||
|
if [[ $info != dir ]]; then # file
|
||||||
|
remain="$curdir/$file"
|
||||||
|
remain=${remain//+(\/)/\/}
|
||||||
|
#sizes[$fullname]=$info
|
||||||
|
# recurse up curdir and adjust sizes
|
||||||
|
#subdir=${curdir}
|
||||||
|
echo "info=$info [$remain]"
|
||||||
|
while [[ -n $remain ]]; do
|
||||||
|
echo "remain=$remain subdir=$subdir"
|
||||||
|
((sizes[$remain] += info))
|
||||||
|
remain=${remain%/*}
|
||||||
|
subdir=${remain##*/}
|
||||||
|
echo " -> remain=$remain subdir=$subdir"
|
||||||
|
done
|
||||||
|
(( sizes["/"] += info ))
|
||||||
|
fi
|
||||||
|
echo "ls: ${lines[$curline]}"
|
||||||
|
((curline++))
|
||||||
|
done
|
||||||
|
((curline--))
|
||||||
|
print_sizes
|
||||||
|
}
|
||||||
|
|
||||||
|
parse() {
|
||||||
|
readarray -t lines
|
||||||
|
curline=0
|
||||||
|
declare -a line
|
||||||
|
|
||||||
|
while ((curline < ${#lines[@]})); do
|
||||||
|
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
|
||||||
|
"cd")
|
||||||
|
do_cd "${line[2]}"
|
||||||
|
;;
|
||||||
|
"ls")
|
||||||
|
do_ls
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
((curline++))
|
||||||
|
printf "WARNING curline=%d\n lines=%d\n" "$curline" "${#lines[@]}"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
solve() {
|
||||||
|
declare -ig res
|
||||||
|
local part="$1" dir mindir="/"
|
||||||
|
local -i needed
|
||||||
|
|
||||||
|
if ((part == 1)); then
|
||||||
|
for dir in "${dirs[@]}"; do
|
||||||
|
printf "size(%s)=%d\n" "$dir" "${sizes[$dir]}"
|
||||||
|
if ((sizes[$dir] <= 100000 )); then
|
||||||
|
((res+=sizes[$dir]))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
else
|
||||||
|
(( needed = sizes["/"] - (70000000-30000000) ))
|
||||||
|
printf "remain=%d\n" "$needed"
|
||||||
|
((res = sizes["/"]))
|
||||||
|
for dir in "${!dirs[@]}"; do
|
||||||
|
#printf "size(%s)=%d\n" "$dir" "${sizes[$dir]}"
|
||||||
|
if (( sizes[$dir] >= needed )); then
|
||||||
|
printf "dir %s (%d) will free enough res=%d\n" "$dir" "${sizes[$dir]}" "$res"
|
||||||
|
if (( sizes[$dir] <= res )); then
|
||||||
|
mindir=$dir
|
||||||
|
((res = sizes[$mindir]))
|
||||||
|
printf "new mindir=%s (%d)\n" "$mindir" "$res"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
|
exit 0
|
Reference in New Issue
Block a user