calculating a sequence that alternates between summation and subtraction

Viewed 45

I'm trying to create a fractal tree in bash, provided that the user enters N where N is the number of branches.

I need to write the following sequence that gets N as an input:

N = 1; sequence = 50
N = 2; sequence = (50-16),(50+16)
N = 3; sequence = (50-16-8),(50-16+8),(50+16-8),(50+16+8)
N = 4; sequence = (50-16-8-4),(50-16-8+4),(50-16+8-4),(50-16+8+4),(50+16-8-4),(50+16-8+4),(50+16+8-4),(50+16+8+4)
N = 5; sequence = (50-16-8-4-2),(50-16-8-4+2),(50-16-8+4-2),(50-16-8+4+2),(50-16-8+4-2),(50-16-8+4+2),(50-16+8-4-2),(50-16+8-4+2),(50-16+8+4-2),(50-16+8+4+2),(50+16-8-4-2),(50+16-8-4+2),(50+16-8+4-2),(50+16-8+4+2),(50+16+8-4-2),(50+16+8-4+2),(50+16+8+4-2),(50+16+8+4+2)

I'm trying to use for loops and basic mathematics to get this sequence as an array but I'm still failing to get the accurate output, here is my code so far:

#!/bin/bash

N=$1
declare -a sequence=()

temp1=50
temp2=50
for i in $(eval echo "{1..$N}");do
        for j in $(eval echo "{1..$N}");do
                temp1=$((temp1+2**(5-j)))
                temp2=$((temp2-2**(5-j)))
        done
                sequence+=($temp1)
                sequence+=($temp2)
                temp1=50
                temp2=50
done

echo ${sequence[@]}

I don't know how to alternate between summation and subtraction, how can I approach this?

1 Answers

Ok so I am not really sure what it is that you are doing haha, but I wrote a script that generates the output you described..

N=${1}

sequence=()
math_sequence=()

if [ $N -eq 1 ]
then
    math_sequence+=(50)
    sequence+=(50)
else
    for i in `seq 0 $(bc <<< "(2^(${N}-1)) - 1")`
    do
        X=50
        Y=32
        SIGNS=$(echo "obase=2;${i}" | bc | xargs printf "%0$((${N}-1))d\n" | sed 's/0/-/g; s/1/+/g')
        MATH="$X"
        VAL=$Y
        for (( i=0; i<${#SIGNS}; i++ )); do
            MATH+="${SIGNS:$i:1}"
            VAL=$(bc <<< "$VAL / 2")
            MATH+="${VAL}"
        done
        math_sequence+=( "(${MATH}), " )
        sequence+=( $(bc <<< "${MATH}") )
    done
fi
echo ${math_sequence[@]}
echo "----------------"
echo ${sequence[@]}

Some tricks I used here..

  1. I saw that the +/- pattern kinda looked like binary counting: ----,---+,--+-,--++...+++-,++++ So I just made a binary counter and used the 0's and 1's as - and +.
  2. bc <<< "${EQUATION}" is much more reliable than $(( ${EQUATION} )). At least I like it better. Works for larger numbers, uses ^ instead of ** for exponents. My fav
  3. I generate two arrays for ya... math_sequence which contains the list of equations, and sequence which contains the actual values. I was not sure which one you actually wanted so I gave you both.
  4. The script is pretty configurable. Just change X and Y in the for loop and you can tweak this thing to make all sorts of numbers.

bash thisScript.sh <N> Will generate the output you described:

N = 1; sequence = 50
N = 2; sequence = (50-16),(50+16)
N = 3; sequence = (50-16-8),(50-16+8),(50+16-8),(50+16+8)
N = 4; sequence = (50-16-8-4),(50-16-8+4),(50-16+8-4),(50-16+8+4),(50+16-8-4),(50+16-8+4),(50+16+8-4),(50+16+8+4)
N = 5; sequence = (50-16-8-4-2),(50-16-8-4+2),(50-16-8+4-2),(50-16-8+4+2),(50-16-8+4-2),(50-16-8+4+2),(50-16+8-4-2),(50-16+8-4+2),(50-16+8+4-2),(50-16+8+4+2),(50+16-8-4-2),(50+16-8-4+2),(50+16-8+4-2),(50+16-8+4+2),(50+16+8-4-2),(50+16+8-4+2),(50+16+8+4-2),(50+16+8+4+2)

Related