Compare commits
No commits in common. "4d037bad46fc1d7904d629461a75118a781977fd" and "bd0aee71db97fa3f1955f68e7f17294ddec13b19" have entirely different histories.
4d037bad46
...
bd0aee71db
@ -5,7 +5,7 @@ Today's language: **gnu x86-64** (and alternatively **C**)
|
|||||||
|
|
||||||
Today I wanted to use OpenAI to solve the tasks using *gnu* **x86-64 assembly**, which I have never used before
|
Today I wanted to use OpenAI to solve the tasks using *gnu* **x86-64 assembly**, which I have never used before
|
||||||
(I did some small things in [6502-asssembly](https://github.com/MatthiasQuintern/6502), so it wasn't all new).
|
(I did some small things in [6502-asssembly](https://github.com/MatthiasQuintern/6502), so it wasn't all new).
|
||||||
The prompt can be seen in `prompt.md`, the original file in `day4-by-ai.s`.
|
The prompt can be seen in prompt.txt.
|
||||||
It did a lot of things right, however it also did a lot of things wrong:
|
It did a lot of things right, however it also did a lot of things wrong:
|
||||||
- It did generate x86 (32-bit) code because I did not specify x86-64. So I changed the `int $0x80` system calls to use `syscall` (which also meant I had to change all the registers and [syscall numbers](https://filippo.io/linux-syscall-table/))
|
- It did generate x86 (32-bit) code because I did not specify x86-64. So I changed the `int $0x80` system calls to use `syscall` (which also meant I had to change all the registers and [syscall numbers](https://filippo.io/linux-syscall-table/))
|
||||||
- It did get the argument order for `sscanf` wrong, even when I specifically asked, it told me that the buffer to read comes last
|
- It did get the argument order for `sscanf` wrong, even when I specifically asked, it told me that the buffer to read comes last
|
||||||
@ -18,7 +18,7 @@ It was still a good starting point and provided lots of help.
|
|||||||
At the end of the ~~evening~~ next morning I had successfully coded the task in x86-64 assembly! :smiley:
|
At the end of the ~~evening~~ next morning I had successfully coded the task in x86-64 assembly! :smiley:
|
||||||
|
|
||||||
I also gave it the exact same prompt again but said I wanted it in **C**.
|
I also gave it the exact same prompt again but said I wanted it in **C**.
|
||||||
It instantly produced compile-able c `day4-by-ai.c` code that gave the right answer...
|
It instantly produced compile-able c code that gave the right answer...
|
||||||
```shell
|
```shell
|
||||||
# for the assembly program
|
# for the assembly program
|
||||||
make asm
|
make asm
|
||||||
|
64
4/day4.c
64
4/day4.c
@ -1,64 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
// Structure to represent a range in the file
|
|
||||||
struct range {
|
|
||||||
int lower;
|
|
||||||
int upper;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Function to parse a line from the file and return the two ranges in the line
|
|
||||||
void parse_line(const char *line, struct range *range1, struct range *range2) {
|
|
||||||
// Parse the two ranges in the line
|
|
||||||
sscanf(line, "%d-%d,%d-%d", &range1->lower, &range1->upper, &range2->lower, &range2->upper);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
|
||||||
// Check if a filename was provided
|
|
||||||
if (argc < 2) {
|
|
||||||
fprintf(stderr, "Error: No filename provided\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open the file for reading
|
|
||||||
FILE *fp = fopen(argv[1], "r");
|
|
||||||
if (fp == NULL) {
|
|
||||||
fprintf(stderr, "Error: Unable to open file for reading\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read the file line by line
|
|
||||||
char line[256];
|
|
||||||
int contain_count = 0;
|
|
||||||
int overlap_count = 0;
|
|
||||||
while (fgets(line, sizeof(line), fp) != NULL) {
|
|
||||||
// Parse the two ranges in the line
|
|
||||||
struct range range1, range2;
|
|
||||||
parse_line(line, &range1, &range2);
|
|
||||||
|
|
||||||
// Check if one range contains the other
|
|
||||||
if (range1.lower <= range2.lower && range1.upper >= range2.upper) {
|
|
||||||
contain_count++;
|
|
||||||
}
|
|
||||||
else if (range2.lower <= range1.lower && range2.upper >= range1.upper) {
|
|
||||||
contain_count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if one range overlaps with the other
|
|
||||||
else if (range1.lower == range2.lower ||
|
|
||||||
range1.upper == range2.upper ||
|
|
||||||
(range1.lower > range2.lower && range1.lower <= range2.upper) ||
|
|
||||||
(range1.upper < range2.upper && range1.upper >= range2.lower)) { // had to fix range1.upper < range2.upper comparison
|
|
||||||
overlap_count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close the file
|
|
||||||
fclose(fp);
|
|
||||||
|
|
||||||
// Print the results
|
|
||||||
printf("The file contains %d lines where one of the two ranges contains each other\n", contain_count);
|
|
||||||
printf("The file contains %d lines where the two ranges overlap each other\n", overlap_count);
|
|
||||||
return 0;
|
|
||||||
}
|
|
26
7/README.md
26
7/README.md
@ -1,26 +0,0 @@
|
|||||||
# [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
81
7/day7.sh
@ -1,81 +0,0 @@
|
|||||||
#!/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
1031
7/output.txt
File diff suppressed because it is too large
Load Diff
@ -11,18 +11,16 @@ 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:
|
These are the days with to most interesting code so far:
|
||||||
1. **day 4**: *x86-64 assembly* with the help of OpenAI
|
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)
|
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, php and many other languages!
|
Also, check out the repositories of my friends who do stuff in go, Visual Basic and php:
|
||||||
- [Daniel](https://git.quintern.xyz/TheShinyMelon/AOC_2022)
|
- [Daniel](https://git.quintern.xyz/TheShinyMelon/AOC_2022)
|
||||||
- [Jonas](https://github.com/JonasBordewick/advent_of_code_2022)
|
- [Jonas](https://github.com/JonasBordewick/advent_of_code_2022)
|
||||||
|
|
||||||
## Language - Day
|
## Language - Day
|
||||||
- **Awk**: day 1, 7
|
- **awk**: day 1
|
||||||
- **Assembly, x86-64**: day 4
|
- **Assembly, x86-64**: day 4
|
||||||
- **Bash**: day 1, 7
|
- **bash**: day 1
|
||||||
- **C**: day 3, 4
|
- **C**: day 3, 4
|
||||||
- **C++**: day 2
|
- **C++**: day 2
|
||||||
- **Javascript**: day 6
|
- **Javascript**: day 6
|
||||||
- **Python**: day 5
|
- **Python**: day 5
|
||||||
- **VIM-Script**: day 3
|
|
||||||
|
Loading…
Reference in New Issue
Block a user