83 lines
2.0 KiB
Bash
83 lines
2.0 KiB
Bash
|
#!/usr/bin/env bash
|
||
|
|
||
|
set -o errexit
|
||
|
set -o nounset
|
||
|
set -o pipefail
|
||
|
if [[ "${TRACE-0}" == "1" ]]; then
|
||
|
set -o xtrace
|
||
|
fi
|
||
|
|
||
|
cd "$(dirname "$0")"
|
||
|
|
||
|
INPUT_FILE="$1"
|
||
|
|
||
|
get_seeds ()
|
||
|
{
|
||
|
echo -n "$(grep seeds "${INPUT_FILE}" | cut -d ' ' -f 2-)"
|
||
|
}
|
||
|
|
||
|
gen_map ()
|
||
|
{
|
||
|
# Generates files for given index of map in input file.
|
||
|
local paragraph map_name map_content
|
||
|
paragraph=$(($1+1)) # number of paragraph in input file
|
||
|
map_name=$(awk -v RS= "{if(NR == ${paragraph}) print}" "${INPUT_FILE}" | head -n 1 | cut -d ' ' -f 1)
|
||
|
map_content=$(awk -v RS= "{if(NR == ${paragraph}) print}" "${INPUT_FILE}"| tail -n +2)
|
||
|
echo "${map_content}" > "${map_name}.map"
|
||
|
maps+=("${map_name}.map")
|
||
|
}
|
||
|
|
||
|
map_seed ()
|
||
|
{
|
||
|
# Usage: map_seed MAP_FILE SEED_NUMBER
|
||
|
# Prints the mapping of the seed number in the give map.
|
||
|
local map seed dest_start source_start length diff
|
||
|
map="$1"
|
||
|
seed="$2"
|
||
|
while read -r line; do
|
||
|
dest_start=$(cut -d ' ' -f 1 <<< "${line}")
|
||
|
source_start=$(cut -d ' ' -f 2 <<< "${line}")
|
||
|
length=$(cut -d ' ' -f 3 <<< "${line}")
|
||
|
if [[ ${seed} -ge ${source_start} && ${seed} -le $((source_start+length-1)) ]]; then
|
||
|
diff=$((seed-source_start))
|
||
|
echo -n $((dest_start+diff))
|
||
|
return
|
||
|
fi
|
||
|
done < "${map}"
|
||
|
echo -n "${seed}" # no mapping
|
||
|
}
|
||
|
|
||
|
main ()
|
||
|
{
|
||
|
IFS=" " read -r -a seeds <<< "$(get_seeds)"
|
||
|
declare -a maps=()
|
||
|
declare -a destinations=()
|
||
|
local map_count destination lowest
|
||
|
map_count=$(awk -v RS= 'END {print NR}' "${INPUT_FILE}")
|
||
|
map_count=$((map_count-1)) # one of the paragraphs in the file is seeds
|
||
|
for ((i=1; i<=map_count; i++)); do
|
||
|
gen_map "${i}"
|
||
|
done
|
||
|
for seed in "${seeds[@]}"; do
|
||
|
destination=''
|
||
|
for map in "${maps[@]}"; do
|
||
|
if [[ -z ${destination} ]]; then
|
||
|
destination=$(map_seed "${map}" "${seed}")
|
||
|
else
|
||
|
destination=$(map_seed "${map}" "${destination}")
|
||
|
fi
|
||
|
done
|
||
|
destinations+=("${destination}")
|
||
|
done
|
||
|
lowest="${destinations[0]}"
|
||
|
for dest in "${destinations[@]}"; do
|
||
|
if [[ ${dest} -lt ${lowest} ]]; then
|
||
|
lowest="${dest}"
|
||
|
fi
|
||
|
done
|
||
|
echo "${lowest}"
|
||
|
rm -f ./*.map
|
||
|
}
|
||
|
|
||
|
main
|