#! perl -slw use strict; use List::Util qw[ max ]; our $N; use enum qw[ LEFT RIGHT ]; sub _traverse { my( $code, $tree, $d, $w ) = @_; ref $tree->[LEFT] and $w = _traverse( $code, $tree->[LEFT], $d+1, $w ) or $code->( ++$w, $d, $tree->[LEFT] ); $code->( ++$w, $d,'^' ); ref $tree->[RIGHT] and $w = _traverse( $code, $tree->[RIGHT], $d+1, $w ) or $code->( ++$w, $d, $tree->[RIGHT] ); return $w; } sub traverse(&$) { _traverse( @_, 0, 0 ); } use enum qw[ WIDTH DEPTH NAME ]; sub dumpTree { my $tree = shift; my @g; traverse{ push @g, [ @_ ]; } $tree; my $width = max( map $_->[WIDTH], @g ); my $depth = max( map $_->[DEPTH], @g ); my @graph = map ' ' x $width, 0 .. $depth; substr $graph[ $_->[DEPTH] ], $_->[WIDTH], 1, substr($_->[NAME],0,1) for @g; unshift @graph, (' ' x $width) x 2; for my $i ( reverse 0 .. $#graph ) { substr( $graph[$i-1], $-[1], $+[1]-$-[1], '/' . ' ' x (length($1)-2) . '\\' ), substr( $graph[ $i ], $-[2], 1, ' ' ) while $graph[ $i ] =~ m[(\S\s*(\^)\s*\S)]g; } my $n; for my $i ( reverse 0 .. $#graph ) { $n = $+[1]-$-[1], substr( $graph[ $i-1 ], $-[1]+1, $n-2, '_' x ($n-2)) while $graph[ $i ] =~ m[(/\s+\\)]g; } print for @graph, ''; return unless $N; my @names = map[ split '', reverse ], grep !/\^/, map $_->[NAME], @g; print for map{ join( ' ', '', map pop @$_//' ', @names ) } 0 .. max( map scalar @$_, @names ); } my @a = qw[ alpha bravo charlie delta echo foxtrot golf hotel indigo juliet kilo mike november oscar papa quebec romeo sierra tango uniform victor whiskey xray yankee zulu ]; our $S //= 0; srand $S if $S; my $r; $r = int( rand $#a ), splice @a, $r, 2, [ @a[ $r, $r+1 ]] while @a > 1; @a = @{ $a[0] }; dumpTree( \@a );