From 8fea880ef9fc5b8c58c96ca0286905b198c482eb Mon Sep 17 00:00:00 2001 From: Patrick Michl Date: Sun, 1 Dec 2024 14:17:35 +0100 Subject: [PATCH] initial --- .gitignore | 2 + day01.sh | 49 ++++++++++++++++++ utils/array.sh | 138 +++++++++++++++++++++++++++++++++++++++++++++++++ utils/main.sh | 14 +++++ 4 files changed, 203 insertions(+) create mode 100644 .gitignore create mode 100755 day01.sh create mode 100644 utils/array.sh create mode 100644 utils/main.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8d05bfc --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +input.txt + diff --git a/day01.sh b/day01.sh new file mode 100755 index 0000000..6062516 --- /dev/null +++ b/day01.sh @@ -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 "$@" diff --git a/utils/array.sh b/utils/array.sh new file mode 100644 index 0000000..8d12acb --- /dev/null +++ b/utils/array.sh @@ -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[@]}" +} diff --git a/utils/main.sh b/utils/main.sh new file mode 100644 index 0000000..2be2fbd --- /dev/null +++ b/utils/main.sh @@ -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" +}