#!/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