#!/bin/bash # # ex1.bash: Advent2020 game, day 20/game 2. CMD=${0##*/} set -o noglob shopt -s extglob source tile.bash #declare -A strings declare -a strings T R B L RT RR RB RL nums declare -a final declare -A FINAL declare -a CORNER EDGE CENTRAL declare -i count=-1 res=1 SQUARE while read -r line; do case ${line:0:1} in T*) ((count++)) num=${line##* } num=${num%%:} nums+=("$num") ;; \#|.) strings[$count]="${strings[$count]} $line" ;; esac done ((count++)) case "$count" in 9) SQUARE=3 ;; 144) SQUARE=12 ;; *) printf "Fatal: unknown square size." exit 0 ;; esac printf "size=%d\n" "$SQUARE" declare top bottom left right declare fliptop flipbottom flipleft flipright for key in "${!nums[@]}"; do # shellcheck disable=SC2206 str=(${strings[$key]}) top top "${str[@]}" right right "${str[@]}" bottom bottom "${str[@]}" left left "${str[@]}" flip fliptop "$top" flip flipright "$right" flip flipbottom "$bottom" flip flipleft "$left" T+=("$top") B+=("$bottom") R+=("$right") L+=("$left") RT+=("$fliptop") RR+=("$flipright") RB+=("$flipbottom") RL+=("$flipleft") done #echo BORDERS: #print_all_borders #exit 0 ALL="${T[*]} ${R[*]} ${B[*]} ${L[*]} ${RT[*]} ${RR[*]} ${RB[*]} ${RL[*]} " ALLSIZE=${#ALL} for ((i=0; i<${#nums[@]}; ++i)); do c=0 for t in ${T[$i]} ${R[$i]} ${B[$i]} ${L[$i]}; do S=${ALL//$t} # 10 is line size ((c += (ALLSIZE-${#S})/10)) done # 6 is 4 for itself, + 2 for other matching #printf "%s: %d\n" "${nums[$i]}" "$c" case "$c" in 6) CORNER+=("$i") ;; 7) EDGE+=("$i") ;; 8) CENTRAL+=("$i") ;; esac done printf "CENTRAL[%d]=%s\n" "${#CENTRAL[@]}" "${CENTRAL[*]}" printf "EDGE[%d]=%s\n" "${#EDGE[@]}" "${EDGE[*]}" printf "CORNER[%d]=%s\n" "${#CORNER[@]}" "${CORNER[*]}" for ((i=0; i<${#CORNER[@]}; ++i)); do printf "corner[%d]=%d\n" "$i" "${nums[$i]}" done #printf "ALL=%s\n" "$ALL" printf "ALLSIZE=%d\n" "$ALLSIZE" printf "%s : count=%d\n" "$CMD" "$count" for ((row=0; row 0)); then echo "border tile match: idx=$index $j [${nums[$j]}]" print_tile "$j" FINAL[$row,$col]="$j" final+=("${nums[$j]}") echo "c=$c" attach_left "$right" "$j" if ((col < SQUARE-1)); then unset "EDGE[$index]" EDGE=("${EDGE[@]}") printf "after removing EDGE $j\n" printf "EDGE[%d]=%s\n" "${#EDGE[@]}" "${EDGE[*]}" else unset "CORNER[$index]" CORNER=("${CORNER[@]}") printf "after removing CORNER $j\n" printf "CORNER[%d]=%s\n" "${#CORNER[@]}" "${CORNER[*]}" fi found=1 break fi ((index++)) done if ((found==0)); then printf "NOT FOUND\n" exit 0 fi continue fi ################################## 1st and last col if ((col==0 || col==SQUARE-1)); then if ((row > 0 && row < SQUARE-1)); then list=("${EDGE[@]}") else list=("${CORNER[@]}") fi l=${FINAL[$((row-1)),$col]} printf "FINAL[%d,%d]=%d\n" "$((row-1))" "$col" "$l" printf "UPPER TILE" print_tile "$j" bottom bottom "${strings[$l]}" printf "UPPER bottom line: %s\n" "$bottom" index=0 for j in "${list[@]}"; do printf "looking for tile %d [%d]\n" "$j" "${nums[$j]}" SIDES="${T[$j]} ${R[$j]} ${B[$j]} ${L[$j]} ${RT[$j]} ${RR[$j]} ${RB[$j]} ${RL[$j]}" LENGTH=${#SIDES} S=${SIDES//$bottom} # 10 is line size ((c = (LENGTH-${#S})/10)) if ((c > 0)); then echo "border tile match: ${nums[$j]}" print_tile "$j" FINAL[$row,$col]="$j" final+=("${nums[$j]}") echo "c=$c" attach_top "$bottom" "$j" if ((row < SQUARE-1)); then unset "EDGE[$index]" EDGE=("${EDGE[@]}") else unset "CORNER[$index]" CORNER=("${CORNER[@]}") fi found=1 break fi ((index++)) done if ((found==0)); then printf "NOT FOUND\n" exit 0 fi continue fi ################################## rest of last row if ((row == SQUARE-1)); then l=${FINAL[$((row-1)),$col]} printf "FINAL[%d,%d]=%d\n" "$((row-1))" "$col" "${FINAL[$((row-1)),$col]}" bottom bottom "${strings[$l]}" index=0 for j in "${EDGE[@]}"; do SIDES="${T[$j]} ${R[$j]} ${B[$j]} ${L[$j]} ${RT[$j]} ${RR[$j]} ${RB[$j]} ${RL[$j]}" LENGTH=${#SIDES} S=${SIDES//$bottom} # 10 is line size ((c = (LENGTH-${#S})/10)) if ((c > 0)); then echo "border tile match: ${nums[$j]}" print_tile "$j" FINAL[$row,$col]="$j" final+=("${nums[$j]}") echo "c=$c" attach_top "$bottom" "$j" unset "EDGE[$index]" EDGE=("${EDGE[@]}") found=1 break fi ((index++)) done if ((found==0)); then printf "NOT FOUND\n" exit 0 fi continue fi ################################## central tiles l=${FINAL[$((row-1)),$col]} printf "FINAL[%d,%d]=%d\n" "$((col-1))" "${FINAL[$,$((col-1))]}" bottom bottom "${strings[$l]}" index=0 for j in "${CENTRAL[@]}"; do SIDES="${T[$j]} ${R[$j]} ${B[$j]} ${L[$j]} ${RT[$j]} ${RR[$j]} ${RB[$j]} ${RL[$j]}" LENGTH=${#SIDES} S=${SIDES//$bottom} # 10 is line size ((c = (LENGTH-${#S})/10)) if ((c > 0)); then echo "border tile match: ${nums[$j]}" print_tile "$j" FINAL[$row,$col]="$j" final+=("${nums[$j]}") echo "c=$c" attach_top "$bottom" "$j" unset "CENTRAL[$index]" CENTRAL=("${CENTRAL[@]}") found=1 break fi ((index++)) done if ((found==0)); then printf "NOT FOUND\n" exit 0 fi continue done done for ((r=0; r=0; --i)); do # fliptop1+=${top:$i:1} # flipbottom1+=${bottom:$i:1} # done # flip fliptop $top # flip flibottom $bottom # printf "T=%s\n" "$fliptop1" # printf "T=%s\n" "$fliptop" # echo # exit 0 #test end # printf "RIGHT=%s\n" "$right" # # find next tile # for j in "${EDGE[@]}"; do # SIDES="${T[$j]} ${R[$j]} ${B[$j]} ${L[$j]} ${RT[$j]} ${RR[$j]} ${RB[$j]} ${RL[$j]}" # LENGTH=${#SIDES} # S=${SIDES//$right} # # 10 is line size # ((c = (LENGTH-${#S})/10)) # if ((c > 0)); then # echo "border tile match: ${nums[$j]}" # print_tile "$j" # final+=("${nums[$j]}") # echo "c=$c" # attach_left "$right" "$j" # unset "EDGE[$j]" # EDGE=("${EDGE[@]}") # break # fi # done # echo after done # print_tile "$j" # right right "${strings[$j]}" # printf "RIGHT=%s\n" "$right" # # find next tile # for j in "${CORNER[@]}"; do # SIDES="${T[$j]} ${R[$j]} ${B[$j]} ${L[$j]} ${RT[$j]} ${RR[$j]} ${RB[$j]} ${RL[$j]}" # LENGTH=${#SIDES} # S=${SIDES//$right} # # 10 is line size # ((c = (LENGTH-${#S})/10)) # if ((c > 0)); then # echo "corner tile match: ${nums[$j]}" # final+=("${nums[$j]}") # print_tile "$j" # echo "c=$c" # attach_left "$right" "$j" # unset "CORNER[$j]" # CORNER=("${CORNER[@]}") # break # fi # done # exit 0 i=${CORNER[0]} printf "corner=%d=%d\n" "$i" "${nums[$i]}" printf "origin:\n" print_tile "$i" flip_h "$i" printf "horizontal flip:\n" print_tile "$i" flip_h "$i" flip_v "$i" printf "vertical flip:\n" print_tile "$i" flip_v "$i" printf "origin:\n" print_tile "$i" declare l="" r="" right r "${strings[$i]}" printf "right=%s\n" "$r" printf "origin:\n" print_tile "$i" r=""; l="" left l "${strings[$i]}" printf "left =%s\n" "$l" printf "origin:\n" print_tile "$i" echo ZOBI