函数和分形 - 递归树 - Bash!逻辑问题

时间:2016-05-22 17:18:40

标签: linux bash fractals

我正在尝试根据构建它的要求构建分形树。 出了点问题。请协助。我正在尝试根据请求的级别构建分形树。这里的关卡被跳过了。需要了解如何解决问题。

    #!/bin/bash
declare -A matrix
for ((i=1;i<=63;i++)) do
    for ((j=1;j<=100;j++)) do
        matrix[$i,$j]='_'
    done
done
function update_matrix {
p1=$1
p2=$(echo $2-1|bc)
p1=$(echo $p1-1|bc)
p3=$(echo 2^$p2|bc)
p4=$(echo 2*$p3|bc)
p5=$(echo $p3/2|bc)
p6=$3
for ((q1=$p3;q1<$p4;q1++)) do
        if [ "$(echo $q1-$p3|bc)" -lt "$p5" ]
            then
            q2=$(echo $p6-$(echo $p5-$(echo $q1-$p3|bc)|bc)|bc)
            q3=$(echo $p6+$(echo $p5-$(echo $q1-$p3|bc)|bc)|bc)
            matrix[$q1,$q2]=1
            matrix[$q1,$q3]=1
            #printf '%s' "$q1 $q2 -- $q1 $q3"
            #echo ""
            else
            matrix[$q1,$p6]=1
            #echo $q1 $p6
        fi
done

if [ $p1 -ge 1 ]
then
update_matrix $p1 $p2 $(echo $p6+$p5|bc)
update_matrix $p1 $p2 $(echo $p6-$p5|bc)
else
return
fi
}
read iteration
if [ $iteration -ge 1 ]
then
    update_matrix $iteration 6 32
fi
for ((i=1;i<=63;i++)) do
    for ((j=1;j<=100;j++)) do
        printf '%s' "${matrix[$i,$j]}"
    done
    echo ""
done

输出是:

____________________________________________________________________________________________________
________________________________________________1_1_________________________________________________
_________________________________________________1__________________________________________________
_________________________________________________1___1______________________________________________
__________________________________________________1_1_______________________________________________
___________________________________________________1________________________________________________
___________________________________________________1________________________________________________
___________________________________________________1_______1________________________________________
____________________________________________________1_____1_________________________________________
_____________________________________________________1___1__________________________________________
______________________________________________________1_1___________________________________________
_______________________________________________________1____________________________________________
_______________________________________________________1____________________________________________
_______________________________________________________1____________________________________________
_______________________________________________________1____________________________________________
_______________________________________1_______________1____________________________________________
________________________________________1_____________1_____________________________________________
_________________________________________1___________1______________________________________________
__________________________________________1_________1_______________________________________________
___________________________________________1_______1________________________________________________
____________________________________________1_____1_________________________________________________
_____________________________________________1___1__________________________________________________
______________________________________________1_1___________________________________________________
_______________________________________________1____________________________________________________
_______________________________________________1____________________________________________________
_______________________________________________1____________________________________________________
_______________________________________________1____________________________________________________
_______________________________________________1____________________________________________________
_______________________________________________1____________________________________________________
_______________________________________________1____________________________________________________
_______________________________________________1____________________________________________________
_______________1_______________________________1____________________________________________________
________________1_____________________________1_____________________________________________________
_________________1___________________________1______________________________________________________
__________________1_________________________1_______________________________________________________
___________________1_______________________1________________________________________________________
____________________1_____________________1_________________________________________________________
_____________________1___________________1__________________________________________________________
______________________1_________________1___________________________________________________________
_______________________1_______________1____________________________________________________________
________________________1_____________1_____________________________________________________________
_________________________1___________1______________________________________________________________
__________________________1_________1_______________________________________________________________
___________________________1_______1________________________________________________________________
____________________________1_____1_________________________________________________________________
_____________________________1___1__________________________________________________________________
______________________________1_1___________________________________________________________________
_______________________________1____________________________________________________________________
_______________________________1____________________________________________________________________
_______________________________1____________________________________________________________________
_______________________________1____________________________________________________________________
_______________________________1____________________________________________________________________
_______________________________1____________________________________________________________________
_______________________________1____________________________________________________________________
_______________________________1____________________________________________________________________
_______________________________1____________________________________________________________________
_______________________________1____________________________________________________________________
_______________________________1____________________________________________________________________
_______________________________1____________________________________________________________________
_______________________________1____________________________________________________________________
_______________________________1____________________________________________________________________
_______________________________1____________________________________________________________________
_______________________________1____________________________________________________________________

需要了解为什么没有创建左侧节点的权利。

3 个答案:

答案 0 :(得分:3)

我缺少的是将变量声明为本地变量。由于哪些全局变量正在更新,因此我的程序无法正常工作。

我修复了问题并使用了局部变量,它就像一个魅力。

解决方案的代码是 它用于Hackerrank函数和分形 - 递归树 - Bash!程序。 花了3个小时把它钉了下来。真的很新鲜,最后解决它。

    #!/bin/bash
declare -A matrix
for ((i=1;i<=63;i++)) do
    for ((j=1;j<=100;j++)) do
        matrix[$i,$j]='_'
    done
done
i=0
declare -A arr
function update_matrix {
local p1 p2 p3 p4 p5 p6 q1 q2 q3 p11 p12 p13 p14 p15 p16
p1=$1
p2=$(echo $2-1|bc)
p1=$(echo $p1-1|bc)
p3=$(echo 2^$p2|bc)
p4=$(echo 2*$p3|bc)
p5=$(echo $p3/2|bc)
p6=$3
for ((q1=$p3;q1<$p4;q1++)) do
        if [ "$(echo $q1-$p3|bc)" -lt "$p5" ]
            then
            q2=$(echo 18+$p6-$(echo $p5-$(echo $q1-$p3|bc)|bc)|bc)
            q3=$(echo 18+$p6+$(echo $p5-$(echo $q1-$p3|bc)|bc)|bc)
            matrix[$q1,$q2]=1
            matrix[$q1,$q3]=1
            #printf '%s' "$q1 $q2 -- $q1 $q3"
            #echo ""
            else
            matrix[$q1,$(echo 18+$p6|bc)]=1
            #echo $q1 $p6
        fi
done

if [ $p1 -ge 1 ]
then
p11=$p1
p12=$p2
p13=$(echo $p6-$p5|bc)
p14=$(echo $p6+$p5|bc)
p15=$p1
p16=$p2

#echo $p11 $p12 $p6 $p5 $p13
update_matrix $p11 $p12 $p13
#echo $p15 $p16 $p6 $p5 $p14

update_matrix $p15 $p16 $p14
t=4
else
s=2
fi
}
read iteration
if [ $iteration -ge 1 ]
then
    #echo $iteration 6 32
    update_matrix $iteration 6 32
fi
for ((i=1;i<=63;i++)) do
    for ((j=1;j<=100;j++)) do
        printf '%s' "${matrix[$i,$j]}"
    done
    echo ""
done

答案 1 :(得分:1)

HackerRank提出的问题要求您使代码递归。为了递归,代码必须在某个时候调用自身。下面,我做了一个递归的create_y函数。该函数将不断调用自身,直到满足停止条件为止。停止条件是if语句,用于检查迭代变量是否大于0。

该函数本身自然希望构建一个Y,并在Y分支的末尾生成新Y,其大小是原始Y的一半。完成后,将按照标准输出。

#!/bin/bash
declare -A SCREEN
SCREENR=63
SCREENW=100
DEPTH=0
MAX=16

function create_y {
    local originR=$1
    local originC=$2
    local iteration=$3
    local size=$4
    local originVR=0
    local originVC=0
    local originNYLR=0
    local originNYLC=0
    local originNYRR=0
    local originNYRC=0

    if [[ iteration -gt 0 ]]; then
        for ((i=0;i<$size;i++))
        do
            SCREEN[$(($originR-$i)),$originC]=1
            let originVR="$(($originR-$i))"
        done

        for ((i=1;i<=$size;i++))
        do
             SCREEN[$(($originVR-$i)),$(($originC - $i))]=1
             let originNYLR="$(($originVR-$i))"
             let originNYLC="$(($originC - $i))"
             SCREEN[$(($originVR-$i)),$(($originC + $i))]=1
             let originNYRR="$(($originVR-$i))"
             let originNYRC="$(($originC + $i))"
        done

        create_y $(($originNYLR-1)) $originNYLC $(($iteration-1)) $(echo "$size/2" | bc)
        create_y $(($originNYRR-1)) $originNYRC $(($iteration-1)) $(echo "$size/2" | bc)
    fi  
}

for ((i=1;i<=$SCREENR;i++)) 
do
    for ((j=1;j<=$SCREENW;j++)) 
    do
        SCREEN[$i,$j]='_'
    done
done

read DEPTH

create_y $SCREENR $(echo "$SCREENW/2" | bc) $DEPTH $MAX

for ((i=1;i<=$SCREENR;i++)) do
    for ((j=1;j<=$SCREENW;j++)) do
         printf '%s' "${SCREEN[$i,$j]}"
    done
    echo ""
done

exit 0

答案 2 :(得分:1)

试图在下面解释为什么这是最佳的。创建网格和解决问题的想法在逻辑上非常简单。

算法:

  • 创建网格。
  • 创建求解函数。
  • 创建一个由 1 组成的列(垂直线),从中间开始,长度为 l(间隔,最初为 16)。
  • 用 1 标记从行尾开始的左右对角线。
  • 你现在有一个 Y!
  • 从 Y 的顶角向左和向右递归,以创建“子 Y”。
  • 递归时请确保您的数据正确(间隔应除以 2 等)。

PS:女士们,先生们,在分享代码时,请在评论时适当尝试,即使是最小的片段。它会改变你的生活!

 #!/bin/bash

 declare -A grid

 #Solves the fractal problem.
 #Variables:
 #  d: depth of recursion.
 #  l: length of gaps/interval.
 #  r: row
 #  c: column.
 solve(){
  local d=$1
  local l=$2
  local r=$3
  local c=$4

  #base case, return.
  if [ $d -eq 0 ]; then
      return
  fi

# iterate backwards.
# create a column/vertical. line of 1's.
# sizeof(line) = l (length of interval) [initially 16].
# See graph below:
: '
        -------------------------------------------------1--------------------------------------------------
        -------------------------------------------------1--------------------------------------------------
        -------------------------------------------------1--------------------------------------------------
        -------------------------------------------------1--------------------------------------------------
        -------------------------------------------------1--------------------------------------------------
        -------------------------------------------------1--------------------------------------------------
        -------------------------------------------------1--------------------------------------------------
        -------------------------------------------------1--------------------------------------------------
        -------------------------------------------------1--------------------------------------------------
        -------------------------------------------------1--------------------------------------------------
        -------------------------------------------------1--------------------------------------------------
        -------------------------------------------------1--------------------------------------------------
        -------------------------------------------------1--------------------------------------------------
        -------------------------------------------------1--------------------------------------------------
        -------------------------------------------------1--------------------------------------------------
        -------------------------------------------------1--------------------------------------------------
'
for (( i = l; i > 0; i-- )); do
    grid[$((r-i)).$c]=1
done

((r -= l))

# iterate backwards.
# create the V-shaped tree/fractal.
# sizeof(tree) = l (length of interval) [initially 16].
# should fill all diagonal cells with 1's .
#       {[r-1, c-1] (left), [r-1, c+1] (right)} --> 1st.
#       {[r-2, c-2] (left), [r-2, c+2] (right)} --> 2nd.                                        for(i in [1,l]) {                       //remember l is dynamic. (16, 8, 4, 2, 1, ..)
#           ...                                                                         ---->       {[r-i, c-l] (left), [r-i, c+l] (right)} = 1 
#           ...                                                                                 }
#       {[r-l, c-l] (left), [r-l, c+l] (right)} --> 16th (or l-th).


for (( i = l; i > 0; i--)); do
    grid[$((r-i)).$((c-i))]=1
    grid[$((r-i)).$((c+i))]=1
done

: '
    This for n = 1 creates the following pattern:

    ----------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------
    ---------------------------------1-------------------------------1----------------------------------
    ----------------------------------1-----------------------------1-----------------------------------
    -----------------------------------1---------------------------1------------------------------------
    ------------------------------------1-------------------------1-------------------------------------
    -------------------------------------1-----------------------1--------------------------------------
    --------------------------------------1---------------------1---------------------------------------
    ---------------------------------------1-------------------1----------------------------------------
    ----------------------------------------1-----------------1-----------------------------------------
    -----------------------------------------1---------------1------------------------------------------
    ------------------------------------------1-------------1-------------------------------------------
    -------------------------------------------1-----------1--------------------------------------------
    --------------------------------------------1---------1---------------------------------------------
    ---------------------------------------------1-------1----------------------------------------------
    ----------------------------------------------1-----1-----------------------------------------------
    -----------------------------------------------1---1------------------------------------------------
    ------------------------------------------------1-1-------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------




'

#   Now comes the fun part, we should recurse.
#   For a complete analysis about why recursion is optimal u could read CLRS
#   or any other Algorithms book of ur choice (be extra carefull on big-O notation, Master Theorem and recursion trees).

# Idea:
#   - We will subrtact 1 from the depth for each complete fractal we create, so we will eventually terminate.
#   - Interval gets reduced by half for any fractal, thus l' = l/2.
#   - r-l: Executed 2 times (see line 48) will bring us to the left/right topmost part of the newly created Y (left/right corner), on the proper row [---------].
#   - c-l/c+l: Will result us beeing on either left or right corner of the Y [See below figure for more].

: '
    
    ----------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------
    ---------------------------------O-------------------------------O----------------------------------        After performing 2 recursive calls (left/right), the execution on the new copy
    ----------------------------------1-----------------------------1-----------------------------------        will start from points marked with "O".
    -----------------------------------1---------------------------1------------------------------------        
    ------------------------------------1-------------------------1-------------------------------------
    -------------------------------------1-----------------------1--------------------------------------
    --------------------------------------1---------------------1---------------------------------------
    ---------------------------------------1-------------------1----------------------------------------
    ----------------------------------------1-----------------1-----------------------------------------
    -----------------------------------------1---------------1------------------------------------------
    ------------------------------------------1-------------1-------------------------------------------
    -------------------------------------------1-----------1--------------------------------------------
    --------------------------------------------1---------1---------------------------------------------
    ---------------------------------------------1-------1----------------------------------------------
    ----------------------------------------------1-----1-----------------------------------------------
    -----------------------------------------------1---1------------------------------------------------
    ------------------------------------------------1-1-------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------
    -------------------------------------------------1--------------------------------------------------




'

# This will work recursivelly so only thing we need to do, is wait and pray that our exit case will work.   
# This can also be seen as "Divide and Conquer" algorithm.

solve $((d-1)) $((l/2)) $((r-l)) $((c-l))
solve $((d-1)) $((l/2)) $((r-l)) $((c+l))

}

 # Just visualize the grid under given assumptions
 print_grid(){
    for ((i=0; i<63; i++)); do
        for ((j=0; j<100; j++)); do
              if [[ ${grid[$i.$j]} ]]; then
              printf 1
              else
                printf -
              fi
        done
        echo
    done
 }

 read n
 solve $n 16 63 49
 print_grid