day 7
This commit is contained in:
parent
20defa2b62
commit
4d037bad46
26
7/README.md
Normal file
26
7/README.md
Normal file
@ -0,0 +1,26 @@
|
||||
# [Day 7](https://adventofcode.com/2022/day/7)
|
||||
:gift::gift::gift::gift::gift::gift::gift:
|
||||
|
||||
Today's language: **Bash** + **awk**
|
||||
|
||||
The way the challenge is laid out is absolutely ridiculus; both tasks could be done in one-liners on a Linux machine in any POSIX shell,
|
||||
IF the user wasn't as stupid...
|
||||
|
||||
That's why I wrote a bash script that actually creates the whole filesystem from the input-file.
|
||||
It does so (by default) in `/tmp`. The sizes for the files are only allocated so that `du` shows the filesize, no write operations are taking place.
|
||||
|
||||
The problem is, that (even empty) directories have a size, which also increases with every file and subdirectory in it.
|
||||
That's why I needed to calculate the sizes of the directories *without* the actual file sizes and subtract that from the output of `du`.
|
||||
This new output can then be piped into an `awk` one-liner. In reality, this problem wouldn't exist since you would want the total size of a directory anyway.
|
||||
|
||||
If the size of the directories themselves would not matter, the commands would be:
|
||||
```shell
|
||||
# Task 1
|
||||
du -b / | awk 'BEGIN{sum=0} {if ($1 <= 100000) {sum+=($1)}} END{print "Total size of all dirs<100000: "sum-0}'
|
||||
# Task 2: min_size = (Update size) - (file system size) - (used size)
|
||||
du -b / | awk 'BEGIN{file=""; size=99999999} {if ($1 >= min_size && $1 < size) {size=$1; file=$2}} END{print "You should delete "file" size("size")"}'
|
||||
```
|
||||
|
||||
```shell
|
||||
./day7.sh output.txt
|
||||
```
|
81
7/day7.sh
Executable file
81
7/day7.sh
Executable file
@ -0,0 +1,81 @@
|
||||
#!/bin/bash
|
||||
|
||||
# INPUT=$(pwd)/"output.txt"
|
||||
INPUT=$(pwd)/$1
|
||||
# ROOT_DIR="/tmp/test/root"
|
||||
ROOT_DIR="/tmp/day7"
|
||||
|
||||
PWD="$ROOT_DIR"
|
||||
|
||||
function pwd_() {
|
||||
echo $(pwd) | sed "s($ROOT_DIR(("
|
||||
}
|
||||
|
||||
function createFS() {
|
||||
mkdir -p "$ROOT_DIR"
|
||||
rm -r "$ROOT_DIR"
|
||||
mkdir "$ROOT_DIR"
|
||||
cd "$ROOT_DIR"
|
||||
|
||||
while read line; do
|
||||
case $line in
|
||||
"$ cd "*)
|
||||
dirname=$(echo $line | awk '{print $3}')
|
||||
if [[ $dirname == "/" ]]; then
|
||||
cd "$ROOT_DIR"
|
||||
continue
|
||||
fi
|
||||
# echo ">> cd $dirname"
|
||||
mkdir -p $dirname || exit 1
|
||||
cd $dirname
|
||||
;;
|
||||
"\$ ls")
|
||||
# echo ">> ls"
|
||||
;;
|
||||
"dir "*)
|
||||
# echo ">> dir"
|
||||
;;
|
||||
*) # output of ls
|
||||
file=$(echo $line | awk '{print $2}')
|
||||
size=$(echo $line | awk '{print $1}')
|
||||
fallocate -l $(expr $size) $file
|
||||
# touch $file
|
||||
;;
|
||||
esac
|
||||
done < $INPUT;
|
||||
}
|
||||
|
||||
FS_SIZE=70000000
|
||||
REQ_SIZE=30000000
|
||||
|
||||
function getDirsize() {
|
||||
cd "$ROOT_DIR"
|
||||
ifs=$IFS; IFS=$'\n'
|
||||
du_output=($(du -b --apparent-size .))
|
||||
# subtract the size of the directory without its contents from the total size
|
||||
# 40 for dir itself
|
||||
# 60 for each sub(sub)dir
|
||||
# 20 for each file in (sub)dir
|
||||
for (( i = 0; i < "${#du_output[@]}"; i++)) do
|
||||
line=${du_output[$i]}
|
||||
dirname=$(echo $line | awk '{print $2}')
|
||||
size=$(echo $line | awk '{print $1}')
|
||||
|
||||
dirsize=$(ls -ld $dirname | awk '{print $5}') # size of directory without its contents
|
||||
subfiles=$(find $dirname -type f | wc -l)
|
||||
subdirs=$(find $dirname -type d | wc -l)
|
||||
du_output[$i]="$(expr $size + 20 - 60 "*" $subdirs - 20 "*" - $subfiles) $dirname"
|
||||
done
|
||||
# printf '%s\n' "${du_output[@]}"
|
||||
printf '%s\n' "${du_output[@]}" | awk 'BEGIN{sum=0} {if ($1 <= 100000) {sum+=($1)}} END{print "Total size of all dirs<100000: "sum-0}'
|
||||
IFS=$ifs
|
||||
ROOT_SIZE=$(echo ${du_output[-1]} | awk '{print $1}')
|
||||
minSize=$(expr $REQ_SIZE - $FS_SIZE + $ROOT_SIZE)
|
||||
# echo "minSize $minSize"
|
||||
|
||||
printf '%s\n' "${du_output[@]}" | awk -v min_size=$minSize 'BEGIN{file=""; size=99999999} {if ($1 >= min_size && $1 < size) {size=$1; file=$2}} END{print "You should delete "file" size("size")"}'
|
||||
|
||||
}
|
||||
|
||||
createFS
|
||||
getDirsize
|
1031
7/output.txt
Normal file
1031
7/output.txt
Normal file
File diff suppressed because it is too large
Load Diff
@ -11,16 +11,18 @@ The directories for each day contain my input file, my code and a README that sh
|
||||
These are the days with to most interesting code so far:
|
||||
1. **day 4**: *x86-64 assembly* with the help of OpenAI
|
||||
2. **day 6**: *html+javascript* [check it out here](https://quintern.xyz/advent22/day6.html)
|
||||
3. **day 7**: *awk+bash*
|
||||
|
||||
Also, check out the repositories of my friends who do stuff in go, Visual Basic and php:
|
||||
Also, check out the repositories of my friends who do stuff in go, Visual Basic, php and many other languages!
|
||||
- [Daniel](https://git.quintern.xyz/TheShinyMelon/AOC_2022)
|
||||
- [Jonas](https://github.com/JonasBordewick/advent_of_code_2022)
|
||||
|
||||
## Language - Day
|
||||
- **awk**: day 1
|
||||
- **Awk**: day 1, 7
|
||||
- **Assembly, x86-64**: day 4
|
||||
- **bash**: day 1
|
||||
- **Bash**: day 1, 7
|
||||
- **C**: day 3, 4
|
||||
- **C++**: day 2
|
||||
- **Javascript**: day 6
|
||||
- **Python**: day 5
|
||||
- **VIM-Script**: day 3
|
||||
|
Loading…
Reference in New Issue
Block a user