sub Combine_Branches { my $tree = $_[0]; my $twig_depth = $_[1]; my $leaf_depth = $_[2]; my @branches = (\$tree); my @twigs = (); my @branch_indeces = (0); my @twig_indeces = (0); my $depth = 0; my $branch = \$tree; # REFERENCE TO THE REFERENCE!!! my $twig = \$tree; my $branch_index = 0; my $twig_index = 1; my $leaf_mode = 0; my $loop_count = 0; my $zero_count = 0; if ($twig_depth >= $leaf_depth) { return }; while (1) { $loop_count++; if ($depth < 0) { last } # END LOOP ########### If less than branching depth, traverse branches if ($depth < $twig_depth) { if (exists $$branch->[$branch_index]) { push @twigs, undef; push @twig_indeces, 0; push @branches, $branch; push @branch_indeces, $branch_index; $depth++; $branch = \$$branch->[$branch_index]; $branch_index = 0; $twig_index = 1; # continue to next branch } elsif ($branch_index < $#$$branch) { $branch_index ++ # drop back a branch } else { $branch = pop @branches; $branch_index = ( pop @branch_indeces ) + 1; $depth -- } } ########## If equal to branching depth, transition to traversing twigs. elsif ($depth == $twig_depth) { if (exists $$branch->[$twig_index]) { push @twigs, $$branch; push @twig_indeces, $twig_index; push @branches, $branch; push @branch_indeces, $branch_index; $twig = $$branch->[$twig_index]; $branch = \$$branch->[0]; $branch_index = 0; $twig_index = 0; $leaf_mode = 1; $depth++; } elsif ($twig_index < $#$$branch) { $twig_index++ } else { $$branch = $$branch->[0]; $branch = pop @branches ; $branch_index = pop @branch_indeces; pop @twigs; pop @twig_indeces; $branch_index++; $depth --; } } ########## If over branching depth and under leaf depth, traverse twigs elsif ($depth > $twig_depth and $depth < $leaf_depth) { if (exists $twig->[$twig_index]) { push @twigs, $twig; push @twig_indeces, $twig_index; push @branches, $branch; push @branch_indeces, $twig_index; $branch = \$$branch->[$twig_index]; $twig = $twig->[$twig_index]; $twig_index = 0; $depth++; } # Next index towards twig elsif ($twig_index < $#$twig) { $twig_index++ } # Past end of subbranch, backtrack. else { $depth--; $branch = pop @branches ; $branch_index = ( pop @branch_indeces ); $twig = pop @twigs; $twig_index = ( pop @twig_indeces ) + 1; } } # If at leaf depth, copy leaves elsif ($depth == $leaf_depth) { if (defined $twig) { if (defined $$branch ) { # TODO: Possibly throw an error if there is overlap. } else { $$branch = $twig; # TODO: Expand the possibility of combining leaves. # Perhaps average, concatenate, overwrite, leave first, etc... } } $branch = pop @branches ; $twig = pop @twigs; $branch_index = pop @branch_indeces; $twig_index = ( pop @twig_indeces ) + 1; $depth--; } # Else something went very wrong. else { die "Inconsistent State, Leaf Mode = $leaf_mode, Depth = $depth, $!" } } return ($tree ? $tree : []); } #################################################################### # PRINT STATE #------------------------------------------------------------------- # This is just a support subroutine for debugging. You call is with # the function call below: # # print_state("This is a useful message", # $depth, $branch_index, $twig_index, $tree, # \@branches, \@branch_indeces, # \@twigs, \@twig_indeces, # $$branch, $twig ); # #################################################################### sub print_state { my ( $message, $depth, $branch_index, $twig_index, $tree, $branches, $branch_indeces, $twigs, $twig_indeces, $branch, $twig ) = @_; print << "___STATE___";
Depth: $depth Branch Index: $branch_index Twig Index: $twig_index
Message: $message
Tree: @$tree
Branch: $branch Index: $branch_index Branches: @$branches Branch Indeces: @$branch_indeces
Twig: $twig Twigs: @$twigs Twig Indeces: @$twig_indeces
___STATE___ print "
Branch:\n" . Dumper($branch) . "
\n" ; print "
Twig:\n" . Dumper($twig) . "
\n" ; }