RosettaCodeData/Task/Tree-datastructures/Perl/tree-datastructures.pl

60 lines
1.5 KiB
Perl

use strict;
use warnings;
use feature 'say';
use JSON;
use Data::Printer;
my $trees = <<~END;
RosettaCode
encourages
code
diversity
comparison
discourages
golfing
trolling
emphasising execution speed
code-golf.io
encourages
golfing
discourages
comparison
END
my $level = ' ';
sub nested_to_indent { shift =~ s#^($level*)# ($1 ? length($1)/length $level : 0) . ' ' #egmr }
sub indent_to_nested { shift =~ s#^(\d+)\s*# $level x $1 #egmr }
say my $indent = nested_to_indent $trees;
my $nest = indent_to_nested $indent;
use Test::More;
is($trees, $nest, 'Round-trip');
done_testing();
# Import outline paragraph into native data structure
sub import {
my($trees) = @_;
my $level = ' ';
my $forest;
my $last = -999;
for my $branch (split /\n/, $trees) {
$branch =~ m/(($level*))*/;
my $this = $1 ? length($1)/length($level) : 0;
$forest .= do {
if ($this gt $last) { '[' . trim_and_quote($branch) }
elsif ($this lt $last) { ']'x($last-$this).',' . trim_and_quote($branch) }
else { trim_and_quote($branch) }
};
$last = $this;
}
sub trim_and_quote { shift =~ s/^\s*(.*\S)\s*$/"$1",/r }
eval $forest . ']' x (1+$last);
}
my $forest = import $trees;
say "Native data structure:\n" . np $forest;
say "\nJSON:\n" . encode_json($forest);