This commit is contained in:
Patrick Michl 2024-12-01 14:17:35 +01:00
commit 8fea880ef9
No known key found for this signature in database
GPG Key ID: BFE0ACEE21CD5EB0
4 changed files with 203 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
input.txt

49
day01.sh Executable file
View File

@ -0,0 +1,49 @@
#!/usr/bin/env bash
unset PATH; readonly PATH
source ./utils/main.sh
source ./utils/array.sh
p1() {
local input="$1" a b tmp i
local left=() right=() res=()
while read -r a b; do
left+=("$a")
right+=("$b")
done <<< "$input"
array.timsort left
array.timsort right
for ((i=0; i < ${#left[@]}; i++)); do
tmp="$((left[i] - right[i]))"
echo "${left[$i]} - ${right[$i]} = ${tmp#-}"
res+=("${tmp#-}")
done > log
array.sum res
}
p2() {
local input="$1" a b i j
local left=() right=() res=()
while read -r a b; do
left+=("$a")
right+=("$b")
done <<< "$input"
for i in "${left[@]}"; do
local tmp=0
for j in "${right[@]}"; do
(( i == j )) && ((tmp++))
done
res+=("$((i*tmp))")
done
array.sum res
}
main "$@"

138
utils/array.sh Normal file
View File

@ -0,0 +1,138 @@
#!/usr/bin/env bash
array.min2() {
(( $1 < $2 )) && echo "$1" && return
echo "$2"
}
_int.insertion_sort() {
local -n _int_isort_arr="$1"
local _int_isort_left="$2" _int_isort_right="$3"
local i=0 j=0
for (( i=_int_isort_left+1; i<=_int_isort_right; i+=1 )) do
local value="${_int_isort_arr["$i"]}" j=$((i-1))
while (( j>=_int_isort_left && _int_isort_arr[j] > value )); do
_int_isort_arr[j+1]="${_int_isort_arr["$j"]}"
((j-=1))
done
_int_isort_arr[j+1]="$value"
done
}
_int.merge() {
local -n _int_merge_arr="$1"
local l="$2" m="$3" r="$4" _int_merge_left=() _int_merge_right=()
local _int_merge_left_len=$((m-l+1)) _int_merge_right_len=$((r-m))
for (( i=0; i < _int_merge_left_len; i+=1 )); do
_int_merge_left[i]="${_int_merge_arr[$((l+i))]}"
done
for (( i=0; i < _int_merge_right_len; i+=1 )); do
_int_merge_right[i]="${_int_merge_arr[$((m+1+i))]}"
done
local i=0 j=0 k="$l"
while (( i < _int_merge_left_len && j < _int_merge_right_len )); do
if (( _int_merge_left[i] <= _int_merge_right[j] )); then
_int_merge_arr[k]="${_int_merge_left[$i]}"
((i+=1))
else
_int_merge_arr[k]="${_int_merge_right[$j]}"
((j+=1))
fi
((k+=1))
done
while (( i < _int_merge_left_len )); do
_int_merge_arr[k]="${_int_merge_left[$i]}"
((k+=1))
((i+=1))
done
while (( j < _int_merge_right_len )); do
_int_merge_arr[k]="${_int_merge_right[$j]}"
((k+=1))
((j+=1))
done
}
_int.min_run() {
local len="$1" r=0
while (( len >= 32 )); do
r=$((r | (len & 1)))
len=$((len >> 1))
done
echo $((len + r))
}
array.timsort() {
local -n _array_timsort_arr="$1"
local len="${#_array_timsort_arr[@]}"
local min_run; min_run="$(_int.min_run "$len")"
local i=0 j=0 size=0 _array_timsort_left=0 _int_timsort_mid=0 _array_timsort_right=0
for (( i=0; i < len; i+=min_run )); do
_int.insertion_sort _array_timsort_arr "$i" "$(array.min2 "$((i+min_run-1))" "$((len-1))")"
done
for (( size=min_run; size < len; size*=2 )); do
for (( _array_timsort_left=0; _array_timsort_left < len; _array_timsort_left+=2*size )); do
_int_timsort_mid=$((_array_timsort_left+size-1))
_array_timsort_right=$(array.min2 "$((_array_timsort_left+2*size-1))" "$((len-1))")
if (( _int_timsort_mid < _array_timsort_right )); then
_int.merge _array_timsort_arr "$_array_timsort_left" "$_int_timsort_mid" "$_array_timsort_right"
fi
done
done
}
array.insertion_sort() {
local -n _array_isort_arr="$1"
_int.insertion_sort _array_isort_arr 0 "$((${#_array_isort_arr[@]}-1))"
}
array.qsort() {
read -ra arr <<< "$@"
((${#arr[@]} == 0)) && echo && return
local smaller=() bigger=() pivot="${arr[0]}" res=()
for i in "${arr[@]}"; do
if ((i < pivot)); then
smaller+=("$i")
elif ((i > pivot)); then
bigger+=("$i")
fi
done
read -ra smaller_sorted <<< "$(array.qsort "${smaller[@]}")"
read -ra bigger_sorted <<< "$(array.qsort "${bigger[@]}")"
res=("${smaller_sorted[@]}" "$pivot" "${bigger_sorted[@]}")
echo "${res[@]}"
}
array.sum() {
local -n _array_sum_input="$1"
local result=0
for i in "${_array_sum_input[@]}"; do
((result+=i))
done
echo "$result"
}
array.from_bytes() {
local input="$1" output=()
while IFS= read -rd '' -n1 byte; do
output+=("$byte")
done <<< "$input"
echo "${output[@]}"
}

14
utils/main.sh Normal file
View File

@ -0,0 +1,14 @@
#!/usr/bin/env bash
set -u
p1() { echo 'Not yet implemented'; }
p2() { echo 'Not yet implemented'; }
main() {
local -r input="$(<"${1:-/dev/stdin}")"
time p1 "$input"
echo
time p2 "$input"
}