вычисление последовательности, которая чередуется между суммированием и вычитанием - PullRequest
2 голосов
/ 31 марта 2020

Я пытаюсь создать фрактальное дерево в bash, при условии, что пользователь вводит N, где N - число ветвей.

Мне нужно написать следующую последовательность, которая получает N в качестве ввода :

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)

Я пытаюсь использовать циклы и базовую c математику, чтобы получить эту последовательность в виде массива, но мне все еще не удается получить точный вывод, вот мой код:

#!/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[@]}

Я не знаю, как чередовать суммирование и вычитание, как я могу подойти к этому?

1 Ответ

1 голос
/ 31 марта 2020

Хорошо, поэтому я не совсем уверен, что вы делаете, ха-ха, но я написал скрипт, который генерирует результат, который вы описали ..

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[@]}

Некоторые приемы, которые я использовал здесь ..

  1. Я увидел, что шаблон +/- выглядит как двоичный счет: ----,---+,--+-,--++...+++-,++++ Так что я просто создал двоичный счетчик и использовал 0's и 1's как - и +.
  2. bc <<< "${EQUATION}" гораздо надежнее, чем $(( ${EQUATION} )). По крайней мере, мне это нравится больше. Работает для больших чисел, использует ^ вместо ** для показателей. Мой любимый
  3. Я генерирую два массива для ya ... math_sequence, который содержит список уравнений, и sequence, который содержит фактические значения. Я не был уверен, какой из них вы на самом деле хотели, поэтому дал вам оба.
  4. Сценарий довольно настраиваемый. Просто измените X и Y в for loop, и вы можете настроить эту вещь для создания всевозможных чисел.

bash thisScript.sh <N> Сгенерирует результат, который вы описали:

N = 1; последовательность = 50
N = 2; последовательность = (50-16), (50 + 16)
N = 3; последовательность = (50-16-8), (50-16 + 8), (50 + 16-8), (50 + 16 + 8)
N = 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), (50 + 16 + 8 + 4)
N = 5; последовательность = (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)

...