#!/bin/bash

# format: [name]&[rle]
# listed in order of https://conwaylife.com/wiki/List_of_common_evolutionary_sequences
# to try to catch as many thing as possible with fitlers, some of these are descendants
# uses forms recommended by HotDogPi [thanks hdp!]
HF=$"Honeyfarm&2b3o\$bo3bo\$o5bo\$o5bo\$o5bo\$bo3bo\$2b3o!"
R=$"R&b2o\$bobo\$o2bo\$b2o\$bo!"
TL=$"TrafficLight&3o\$obo\$3o!"
# PP=$"Prepuslar&3o3b3o\$obo3bobo\$3o3b3o!"
Pi=$"Pi&b3o\$o3bo\$2ob2o!"
S=$"Stairstep&3o\$o2b2o\$2o2bo\$2b3o!"
Century=$"Century&b3o\$3bo\$ob2o\$2o!"
B=$"B&2bo\$b3o\$2o2bo\$2b3o!"
W=$"Wing&b2o\$o2bo\$bobo\$2b2o!"
TD=$"Teardrop&b3o\$o2bo\$o2bo\$b2o!"
I=$"I&3b2o\$bo2bo\$o3bo\$bobo\$2bo!"
O=$"Octomino&b3o\$o\$obo\$3o!"
J33=$"Jason33&2bo\$2obo\$o3bo\$b3o!"
Pro=$"Procrastinator&o\$3o\$3bo\$b3o!"
BT=$"BlonkTie&bobo\$o3bo\$o4bo\$bo3bo\$2b3o!"
IW=$"Iowona&2b2o\$o3bo\$o2bo\$b2o!"
U=$"UTurner&2bo\$bobo\$o\$o2bo\$2o!"
HDesc=$"HDescendant&2o\$o2b2o\$bo2bo\$b3o!"
RT=$"RTurner&2b2o\$4bo\$o2bo\$3o!"

# E=$"E&3o\$2b2o\$b2o!"
# H=$"Herschel&o\$obo\$3o\$2bo!"
read -r -d '' topTwo << "EOM"
cat 2o$2o 10 -1 -1 / forbidden obo$b2o$bo2$2o$2o! 0 -4 forbidden 2o3bo$2ob2o$4b2o! 0 0 forbidden b2o$b2o2$bo$2o$obo! -1 0 forbidden 2o$b2ob2o$o3b2o! -4 -1 forbidden o3b2o$b2ob2o$2o! -4 0 forbidden obo$2o$bo2$b2o$b2o! -1 -4 forbidden 4b2o$2ob2o$2o3bo! 0 -1 forbidden 2o$2o2$bo$b2o$obo! 0 0 required o! -1 -1
cat 2o$o$b3o$3bo! 10 -2 -2 * forbidden 2o$o$b3ob2o$3bobobo$6bo! -2 -2 forbidden bo$obo$2o2$2o$o$b3o$3bo! -2 -6 forbidden bo$2bo$3o2$3b2o$3bo$4b3o$6bo! -5 -6 forbidden 2bo$obo$b2o2$3b2o$3bo$4b3o$6bo! -5 -6 required bo$o$b3o$3bo! -2 -2 locus 2o$o! -2 -2
EOM
topTwo+="\n"
# blinker, TL, and traffic stop (considered transparent due to it's super long reset time)
read -r -d '' periodTwoTransparent << "EOM"
cat 3o! 30 -1 0 . period 2 transparent
cat 2b3o2$o5bo$o5bo$o5bo2$2b3o! 30 -4 -4 . period 2 transparent
cat 2b3o2$o$o$o$8b2o$2b3o3bobo$10bo$10b2o! 40 -6 -5 * period 2 transparent required 9b2o$o5bo2b3o$bo3b2obob2o$10b2o$10b2o! -6 -1 forbidden 2b3o2$o$o$o$8b2o$2b3o3bobo$10bo$10b2o2$10b2o$10bobo$11bo! -6 -5
EOM
periodTwoTransparent+='\n'

# clock and killer toads
read -r -d '' periodTwoNonTransparent << "EOM"
cat bo$2b2o$2o$2bo! 10 -2 -2 | period 2 required b2o$4o$4o$b2o! -2 -2
cat 2bo$o2bo$o2bo$bo2$bo$o2bo$o2bo$2bo! 10 -2 -5 + required 2bo$4o$4o$bo2$bo$4o$4o$2bo! -2 -5
EOM
periodTwoNonTransparent+='\n'

read -r -d '' mold << "EOM"
cat 2o$3o$2obo$2bobo$bo2bo$2b2o! 10 -3 -3 + period 4 required b2o$4o$3obo$bobobo$2bo2bo$3b2o! -4 -3
EOM
mold+='\n'

# figure eight, blocker, kok's galazy
read -r -d '' periodEight << "EOM"
cat 2b2o2$o3bo$o4bo$2bobobo$3bobobo$4bo4bo$5bo3bo2$6b2o! 10 -5 -5 | period 8 required 2bo$b3o$5o$b5o$2b5o$3b5o$4b3o$5bo! -4 -4
cat 4b2o$2obo2bob2o$o4bo2b2o$4bo$bobo! 10 -5 -3 x period 8 required 8o$8o$8o$8o! -4 -3
cat 3bo2bo$7bo$8b2o$2bob2o6bo$2bo2bo3bo$bo3bob3o$o11bo$3b3obo3bo$3bo3bo2bo$o6b2obo$3b2o$5bo$6bo2bo! 10 -7 -7 / period 8 required 3b5o$2b7o$b9o$11o$11o$11o$11o$11o$b9o$2b7o$3b5o! -6 -6
EOM
periodEight+="\n"

read -r -d '' periodSeven << "EOM"
cat 8bo$3b2o4b2o$b3ob2o2b2o$o8bo$bob2o$bobo3bobo$6b2obo$bo8bo$2o2b2ob3o$2o4b2o$2bo! 10 -6 -6 x required 3b8o$b10o$10o$b9o$b9o$b9o$b10o$10o$8o! -6 -5 period 7 mustinclude
cat bo2bo$5bo$o5bo$2o4bo$5bo$4bo$3b4obo$3bo3bo$bo3bo$ob4o$4bo$3bo$2bo4b2o$2bo5bo$3bo$4bo2bo! 10 -5 -8 x required 3b3o$b6o$b6o$b5o$b4o$b6obo$b7o$b7o$ob6o$4b4o$3b5o$2b6o$2b6o$3b3o! -5 -7 period 7 mustinclude
cat 5bo$5bo2$3bo3bo$b3obob3o$o4bo4bo$b4obobobo$4bobo4b2o$b2obo2bob2o2bo$b2obo3bobob2o$5bo4bobo$10bo2bo$6bo4b3o$7b4o$11bo$3b2obobob2o$3bob2ob2o$7bo3b3o$7bob2o2bo$8bobo! 10 -7 -10 + required 4b3o$3b5o$b9o$11o$b10o$b12o$3b11o$3b11o$4b9o$4b10o$4b10o$4b9o$4b9o$3b10o$3bob8o$7b7o$7b4o2bo$8bobo! -7 -8 forbidden 5bo$5bo2$3bo3bo$b3obob3o$o4bo4bo$b4obobobo$4bobo4b2o$b2obo2bob2o2bo$b2obo3bobob2o$5bo4bobo$10bo2bo$6bo4b3o$7b4o$11bo$3b2obobob2o$3bob2ob2o$7bo3b3ob2o$7bob2o2bobobo$8bobo5bo! -7 -10 forbidden 6bo$6bo2$4bo3bo$2b3obob3o$bo4bo4bo$2b4obobobo$5bobo4b2o$2b2obo2bob2o2bo$2b2obo3bobob2o$6bo4bobo$11bo2bo$7bo4b3o$8b4o$12bo$b2ob2obobob2o$obobob2ob2o$bo6bo3b3o$8bob2o2bo$9bobo! -8 -10 period 7 mustinclude
EOM
periodSeven+="\n"

read -r -d '' Kazyan << "EOM"
cat 2o$2o 10 -1 -1 / forbidden obo$b2o$bo2$2o$2o! 0 -4 forbidden 2o3bo$2ob2o$4b2o! 0 0 forbidden b2o$b2o2$bo$2o$obo! -1 0 forbidden 2o$b2ob2o$o3b2o! -4 -1 forbidden o3b2o$b2ob2o$2o! -4 0 forbidden obo$2o$bo2$b2o$b2o! -1 -4 forbidden 4b2o$2ob2o$2o3bo! 0 -1 forbidden 2o$2o2$bo$b2o$obo! 0 0 required o! -1 -1
cat 2o$o$b3o$3bo! 10 -2 -2 * forbidden 2o$o$b3ob2o$3bobobo$6bo! -2 -2 forbidden bo$obo$2o2$2o$o$b3o$3bo! -2 -6 forbidden bo$2bo$3o2$3b2o$3bo$4b3o$6bo! -5 -6 forbidden 2bo$obo$b2o2$3b2o$3bo$4b3o$6bo! -5 -6 required bo$o$b3o$3bo! -2 -2 locus 2o$o! -2 -2
cat bo$obo$bobo$2bo! 6 -1 -1 | required bo$o 0 0
cat bo$obo$bo! 10 -1 -1 | required o! -1 0
cat 2obo$2ob3o$6bo$2ob2obo$bob2ob2o$bo$2b3ob2o$4bob2o! 10 -3 -3 | forbidden 2bo$obo$b2o2$3b2obo$3b2ob3o$9bo$3b2ob2obo$4bob2ob2o$4bo$5b3ob2o$7bob2o! -6 -7 forbidden bo$2bo$3o2$3b2obo$3b2ob3o$9bo$3b2ob2obo$4bob2ob2o$4bo$5b3ob2o$7bob2o! -6 -7 forbidden 2bo$obo$b2o$4b2obo$4b2ob3o$10bo$4b2ob2obo$5bob2ob2o$5bo$6b3ob2o$8bob2o! -7 -6 forbidden bo$2bo$3o$4b2obo$4b2ob3o$10bo$4b2ob2obo$5bob2ob2o$5bo$6b3ob2o$8bob2o! -7 -6 forbidden 2obo$2ob3o$6bo$2ob2obo$bob2ob2o$bo$2b3ob2o$4bob2o$9b3o$9bo$10bo! -3 -3 forbidden 2obo$2ob3o$6bo$2ob2obo$bob2ob2o$bo$2b3ob2o$4bob2o$9b2o$9bobo$9bo! -3 -3 forbidden 2obo$2ob3o$6bo$2ob2obo$bob2ob2o$bo$2b3ob2o$4bob2o2$8b3o$8bo$9bo! -3 -3 forbidden 2obo$2ob3o$6bo$2ob2obo$bob2ob2o$bo$2b3ob2o$4bob2o2$8b2o$8bobo$8bo! -3 -3 required 3bo$3b3o$6bo$2ob2obo$bob2ob2o$bo$2b3o$4bo! -3 -3 locus 2o$2o5$6b2o$6b2o! -3 -3
EOM
Kazyan+="\n"

TNosedP4='cat 8bo$8bo$7b3o2$2b2o9b2o$2bo11bo$3b11o$3o2b7o2b3o$o2bo2bo3bo2bo2bo$b2o4b3o4b2o$7b3o$8bo! 10 -8 -7 / period 4 required 2b2o9b2o$2bo11bo$3bo9bo$3o11b3o$o2bo9bo2bo$b2o11b2o! -8 -3'
TNosedP4+="\n"
fountain='cat 9bo2$3b2obo5bob2o$3bo5bo5bo$4b2ob2ob2ob2o2$6b2o3b2o$2o15b2o$o2bo3bobobo3bo2bo$b3ob9ob3o$4bo4bo4bo$3b2o9b2o$3bo11bo$5bo7bo$4b2o7b2o! 10 -10 -4 @ period 4 required 3b13o$3b13o$3b13o$3b13o$3b13o$19o$8ob10o$b17o$4b11o$3b13o$3b13o$4b2o7b2o$4b2o7b2o! -10 -2 forbidden 9bo2$3b2obo5bob2o$3bo5bo5bo$4b2ob2ob2ob2o2$6b2o3b2o$2o15b2o$o2bo3bobobo3bo2bo$b3ob9ob3o$4bo4bo4bo$3b2o9b2o$3bo11bo$5bo7bo$4b2o7b2o2$4b2o$3bobo$4bo! -10 -4 forbidden 9bo2$3b2obo5bob2o$3bo5bo5bo$4b2ob2ob2ob2o2$6b2o3b2o$2o15b2o$o2bo3bobobo3bo2bo$b3ob9ob3o$4bo4bo4bo$3b2o9b2o$3bo11bo$5bo7bo$4b2o7b2o2$13b2o$13bobo$14bo! -10 -8'
foutain+="\n"
p4Domino='cat 7b2o2$6bo$5bob3o$3b3o4bo$2bo3bo5bo$2b5o5bo$5bo2bobobo$4obo4bo$o2b2o! 10 -7 -3 @ period 4 required 6b3o$5b5o$3b8o$2b11o$2b11o$5b8o$4ob7o$o2b2o! -7 -1 forbidden 11b2o2$10bo$9bob3o$7b3o4bo$6bo3bo5bo$6b5o5bo$9bo2bobobo$b2ob4obo4bo$obobo2b2o$bo! -11 -3'
p4Domino+="\n"
# main parameters to edit


blinker='cat 3o! 30 -1 0 . period 2 transparent mustinclude'
blinker+="\n"
halfTL='cat 3o2$4bo$4bo$4bo! 20 -2 -2 | period 2 transparent mustinclude'
halfTL+="\n"

searchName="2cat_p7" # file naming purposes

whichCatalysts="${periodSeven}${Kazyan}"

activeRegions=( "$R" "$Pi" "$S" "$Century" "$B" "$W" "$TD" "$I" "$O" "$J33" "$Pro" "$BT" "$IW" "$U" "$HDesc" "$RT" ) #  
symOptions='C2-even C2 C2|even C2even D2| D2|even C4 C4even' # D2/ C4 C4even D4+ D4+|even D4+-even D4+even D4x D4xeven' # D8 D8even'
# C2 variants seem to be the most productive, but stuff has been found in D4+, C4, and D2 too.

maxGen=200
lastGen=50
numCats=2

apgmeraDirectory="$HOME/Documents/apgmera"
golchemyDirectory="$HOME/Documents/golchemy/experiments"
CatForceDirectory="$HOME/Documents/CatForce-periodic"

# try to catch flippers. does not take into account whether flipped catalyst placements are viable
# so 95%+ of the flipper partials are uncompletable in my experience.
flippers="false"

stopAt=10 # search covers: active region has center 0 <= x <= stopAt, 0<= y <= stopAt

earlyParams="start-gen 1\nmax-gen $maxGen\nlast-gen $lastGen\nstable-interval 18\nnum-catalyst $numCats\nnum-transparent 1\n"
oscParams=$'stop-after-cats-destroyed 15\n'

debug="false" # print CatForce progress messages and save full-report files. deletes them if they're empty, though.

# end main parameters to edit

# notes/clarifications:

# (1) like LLS, | represents vertical reflection line, - horizontal. even says reflect across x= -0.5 or y = -0.5, line between two cells,
# lack of even says x=0 or y=0. Alternative for |even is horizontaleven, -even is verticaleven, where vertical/horizontal refer to bounding
# box dims. Following this pattern, C2|even denotes rotation about (-0.5,0), even though there's no reflection involved.

# (2) if we have C2 symmetry, say, I assume that all catalysts are placed on the right half; if C4 or D4+, then 1st quadrant; etc.
# worth noting because these could backfire if you use fit-in-width-height. [This could be fixed]

# (3) stable interval 18 might be a bit high for low-period stuff. Similarly could relax stop-after-cats-destroyed.

# (4) if symmetry isn't a D2 variant, via composing with reflections across the axes, we can assume the center of the active region is below and
# to the right of the center of symmetry. Via further composing with a reflection across y=x, we can assume x >= y.
# however, that last part swaps | with -. so if you include D4+|even, for example, you should probably also include D4+-even.
# for D2, it suffices to have D2- and D2/.

if ! [[ -f 'active_region_occurs' ]] || ! [[ -f 'CatForce' ]]
then
    echo "executables not found...trying running make"
    if ! make
    then
        echo "make did not run successfully. exiting script"
        exit 0;
    fi
fi

for obj in "${activeRegions[@]}"
do
    rle="${obj#*&}" # regex for drop everything before the first &
    name="${obj%&*}" # regex for drop everything after the last &

    echo "Starting active object ${name}"

    if [ ! -d "$name" ]
    then
        mkdir "$name"
    fi

    rotatedObj=$( python3 generateOrientedRLEs.py "$rle" )
    
    IFS=$'\n' read -d '' -ra rotatedRLEs < <(printf '%s\0' "$rotatedObj") # found via stack overflow, split up by \n.
    # rotatedRLEs = all orientations of the object [as a set: ie it detects redundancy, only 1 for honeyfarm, 4 for pi, etc]

    for sym in $symOptions
    do
        if [ $sym = 'D2backslash' ]
        then
            echo 'WARNING: D2\ no longer supported. It causes placement headaches, due to wanting to put active region in 2nd quadrant not 1st.'
            echo '         Searching D2/ intead.'
            sym="D2/"
        fi

        echo "    Starting symmetry ${sym}"
        soFar=0

        symParams="symmetry ${sym}\n"
        
        # checking filter for D8 vs C1 is very little time difference, so not a big deal
        # to include extra symmetries when that simplifies code structure here.
        # [filterGroup only gets used if flippers is set to "true"]
        if  [ "${sym:2:4}" = "even" ] || [ $sym = 'D4+even' ] || [ $sym = 'D4xeven' ]
        then
            centerOfSymX="-0.5"
            centerOfSymY="-0.5"
            filterGroup="D8even"
        elif [ $sym = 'C2|even' ] || [ $sym = 'D4+|even' ]
        then
            centerOfSymX="-0.5"
            centerOfSymY="0"
            filterGroup="D4+|even"
        elif [ $sym = 'C2-even' ] || [ $sym = 'D4+-even' ]
        then
            centerOfSymX="0"
            centerOfSymY="-0.5"
            filterGroup="D4+-even"
        else
            centerOfSymX="0"
            centerOfSymY="0"
            filterGroup="D8"
        fi


        startTimeForSymAndObj=$SECONDS

        for orientNum in ${!rotatedRLEs[@]}
        do
            orientedRLE="${rotatedRLEs[$orientNum]}"

            dims=$( python3 getWidthHeight.py $rle )

            height=${dims#*,}
            width=${dims%,*}

            
            if [ "${sym:0:2}" != "D2" ]
            then
                # naive total,  (area of 0 <= y <= x <= stopAt) * (num orientations)
                approxTotal=$(( ($stopAt+1) * ($stopAt+1) * ${#rotatedRLEs[@]} / 2 ))
                # rough correction for overlap
                if [[ "${sym:0:1}" == "C" ]]
                then
                    approxTotal=$(($approxTotal - $width / 2 * ($height / 2) ))
                elif [ "${sym:0:3}" == "D4+" ] ||  [ "${sym:0:2}" == "D8" ]
                then
                    approxTotal=$(($approxTotal - $height / 2 * $stopAt))
                fi
                if [ "${sym:0:3}" == "D4x" ] || [ "${sym:0:2}" == "D8" ]
                then
                    greaterDim=$( [[ $width > $height ]] && echo $width || echo $height)
                    approxTotal=$(($approxTotal - $greaterDim / 2 * $stopAt))
                fi
            else
                approxTotal=$(( ($stopAt+1) * ${#rotatedRLEs[@]} ))
            fi

            # because we count points not edges, something with width 2, height 3, corner (0,0)
            # has center (0.5, 1), not (1, 1.5). I want x0 + width/2 to be the center.
            # So I'll be non-standard and count edges, not points.
            height=$(( $height - 1 ))
            width=$(( $width - 1 ))

            # due to the above, odd width things have center at half-integer.
            if [ $(( $width % 2 )) == "1" ]
            then
                startCenterX="-0.5"
            else
                startCenterX="0"
            fi

            if [ $(( $height % 2 )) == "1" ]
            then
                startCenterY="-0.5"
            else
                startCenterY="0"
            fi


            for centerX in $(seq $startCenterX 1 $stopAt)
            do
                for centerY in $(seq $startCenterY 1 $stopAt)
                do
                    # upper left corner.
                    x0=$( echo "$centerX - $width / 2" | bc -l )
                    y0=$( echo "$centerY - $height / 2" | bc -l )
                    x0=$( printf "%.0f" $x0 )
                    y0=$( printf "%.0f" $y0 )

                    activeRegionOccurs=$(./active_region_occurs ${orientedRLE} $x0 $y0 $sym)

                    # if the symmetry isn't D2, then we can assume the center of the object is below and to the right of the center of symmetry
                    # moreover, if we search both variants, horizontal even and vertical even, we can assume x coord of center >= y coord of center via composing
                    # with a diagonal reflection.

                    if [[ "${sym:0:2}" != "D2" &&  $(echo "$centerX >= $centerOfSymX" |bc -l) = "1" && \
                            $(echo "$centerY >= $centerOfSymY" |bc -l) = "1" && $(echo "$centerX >= $centerY" |bc -l) = "1" ]]
                    then
                        inCorrectRegion="true"
                    elif [[ $sym = "D2|" || $sym = "D2|even" ]]  && [[ $(echo "$centerY == $startCenterY" |bc -l) = "1" ]]
                    then
                        inCorrectRegion="true"
                    elif [[ $sym = "D2-" || $sym = "D2-even" ]] && [[ $(echo "$centerX == $startCenterX" |bc -l) = "1"  ]]
                    then
                        inCorrectRegion="true"
                    elif [[ $sym = 'D2/' ]] && [[ $(echo "$centerY == $centerX" |bc -l) = "1" || $(echo "$centerX - $centerY == 0.5" |bc -l) = "1"  ]]
                    then
                        inCorrectRegion="true"
                    else   
                        inCorrectRegion="false"
                    fi

                    if [[ "$inCorrectRegion" == "true" && "$activeRegionOccurs" == "true" ]]
                    then

                        searchArea="search-area -30 -30 60 60\n"

                        #pattern
                        patParams="pat ${orientedRLE} $x0 ${y0}\n"

                        # filters
                        if [ "$flippers" = "true" ]
                        then
                            reoccurFilter="filter 1-$maxGen $orientedRLE $x0 $y0 ${filterGroup}\n"
                        else
                            reoccurFilter="filter 1-$maxGen $orientedRLE $x0 ${y0}\n"
                        fi

                        # output file naming (avoid |, / in file names)
                        symLen=${#sym}
                        if [[ $sym = 'D2|' || $sym = 'D2|even' ]]
                        then
                            symAsString="${sym/\|/ReflectAcrossYAxis}"
                        elif [[ symLen -ge 5  && "${sym:symLen-5:5}" = '|even' ]] 
                        then
                            symAsString="${sym/\|/horizontal}"
                        elif [[ $sym = 'D2/' ]]
                        then
                            symAsString='D2slash'
                        else
                            symAsString="$sym"
                        fi
                    
                        outfileName="${name}_${symAsString}_orient${orientNum}_${centerX/./,}_${centerY/./,}_${searchName}.rle"
                        outfileFullName="${name}_${symAsString}_orient${orientNum}_${centerX/./,}_${centerY/./,}_${searchName}_full.rle"

                        if [ "$debug" == "true" ]
                        then
                            #outfileParams="output ${outfileName}\nfull-report ${outfileFullName}\n" # debugging purposes, save full report
                            #reportMatches=$'report-matches true\n'
                            outfileParams="output ${outfileName}\n"
                        else
                            outfileParams="output ${outfileName}\n"
                            #reportMatches=$'report-matches true\nquiet-mode true\n'
                        fi

                        # create search file.

                        
                        echo -e "${earlyParams}${symParams}${searchArea}${whichCatalysts}${patParams}${reoccurFilter}${outfileParams}${reportMatches}${oscParams}" > temp_p7.txt

                        # run search file.
                        if [ "$debug" == "false" ]
                        then
                            ./CatForce temp_p7.txt > /dev/null
                        else
                            ./CatForce temp_p7.txt
                        fi

                        # delete RLEs with no results
                        if [ "$(wc -c ${outfileName} | awk '{print $1}')" = "28" ]
                        then
                            rm $outfileName
                        else
                            # cd $golchemyDirectory
                            # python3 catpipe.py $CatForceDirectory/$outfileName | ${apgmeraDirectory}/apgluxe
                            # cd $CatForceDirectory
                            mv $outfileName $name/$outfileName
                        	echo -e "\n        Possible results: see ${outfileName}\n"
						fi

                        # debug mode and no full results => delete full results.
                        if [ -f $outfileFullName ] && [ "$(wc -c ${outfileFullName} | awk '{print $1}')" = "28" ]
                        then
                            rm $outfileFullName
                        elif [ -f $outfileFullName ]
                        then
                            mv $outfileFullName $name/$outfileFullName
                        fi

                        # update count.
                        soFar=$(($soFar + 1))
                        timeForSymAndObj=$(echo "$SECONDS - $startTimeForSymAndObj" |bc -l)

                        # display progress message.
                        toPrint="\r        ${soFar} done of roughly $approxTotal for $name with symmetry $sym. "
                        if [[ $(echo "$timeForSymAndObj > 3600 * $soFar" |bc -l) = "1" ]]
                        then
                            toPrint+="Average $(($timeForSymAndObj  / ($soFar * 3600) )) h $((($timeForSymAndObj / (60 * $soFar) ) % 60)) min $(( ($timeForSymAndObj / $soFar ) % 60)) sec per search"
                        elif [[ $(echo "$timeForSymAndObj > 60 * $soFar" |bc -l) = "1" ]]
                        then
                            toPrint+="Average $((($timeForSymAndObj / (60 * $soFar) ) % 60)) min $(( ($timeForSymAndObj / $soFar ) % 60)) sec per search"
                        else
                            toPrint+="Average $(( ($timeForSymAndObj / $soFar ) % 60)) sec per search"
                        fi
                        printf "$toPrint"
                    
                    fi
                done
            done # locations
        done # orientations
        printf " DONE, after $(($timeForSymAndObj  /  3600)) h $((($timeForSymAndObj / 60 ) % 60)) min $(($timeForSymAndObj % 60)) sec.\n"
    done # symmetries
done # objects

