Sort an outline at every level: Difference between revisions

→‎{{header|Raku}}: Add a Raku example
m (→‎{{header|Phix}}: added syntax colouring the hard way)
(→‎{{header|Raku}}: Add a Raku example)
Line 2,120:
Unknown 2 (Z -> A):
Inconsistent indentation width at line 3</pre>
 
=={{header|Raku}}==
Rather than a monolithic verify-and-sort-and-print routine, implement as a series of routines that can be chained together or used separately as desired.
 
* Routine to check indent characters and return the indent white-space if it is consistent.
 
* Routine to import a text "outline" into a native data structure
 
* Routine(s) to output the data structure in the desire sort order.
 
<lang perl6>my @tests = q:to/END/.split( /\n\n+/ )».trim;
zeta
beta
gamma
lambda
kappa
mu
delta
alpha
theta
iota
epsilon
 
zeta
gamma
mu
lambda
kappa
delta
beta
alpha
theta
iota
epsilon
 
alpha
epsilon
iota
theta
zeta
beta
delta
gamma
kappa
lambda
mu
 
zeta
beta
gamma
lambda
kappa
mu
delta
alpha
theta
iota
epsilon
END
 
for @tests -> $t {
say "{'=' x 55}\nUnsorted:\n$t";
my $indent = try detect-indent $t;
next unless $indent;
say "\nSorted ascending:";
pretty-print import($t, :level($indent) ).List, :ws($indent);
say "\nSorted descending:";
pretty-print import($t, :level($indent) ).List, :ws($indent), :desc;
}
 
sub detect-indent ($text) {
my $consistent = $text.lines.map(* ~~ / ^ (\h*) /).join.comb.Set;
note "\nUnwilling to continue; Inconsistent indent characters." and return '' if +$consistent > 1;
my @ws = $text.lines.map: (* ~~ / ^ (\h*) /)».Str;
my $indent = @ws.grep( *.chars > 0 ).min.first;
note "\nUnwilling to continue; Inconsistent indentation." and return '' unless all
@ws.map: { next unless .[0]; (.[0].chars %% $indent.chars) }
$indent
}
 
sub import (Str $trees, :$level) {
my $forest = '[';
my $last = -Inf;
for $trees.lines -> $branch {
$branch ~~ / ($($level))* /;
my $this = +$0;
$forest ~= do {
given $this cmp $last {
when More { (?$this ?? q[ => \[ ] !! "" )~ "'{$branch.trim}'" }
when Same { ", '{$branch.trim}'" }
when Less { "{']' x $last - $this}, '{$branch.trim}' " }
}
}
$last = $this;
}
$forest ~= ']' x 1 + $last;
use MONKEY-SEE-NO-EVAL;
$forest.EVAL;
}
 
multi pretty-print (List $struct, :$level = 0, :$ws = ' ', :$desc = False) {
if $desc {
pretty-print($_, :level($level), :$ws, :$desc ) for $struct.flat.sort.reverse.List
} else {
pretty-print($_, :level($level), :$ws, :$desc ) for $struct.flat.sort.List
}
}
 
multi pretty-print (Pair $struct, :$level = 0, :$ws = ' ', :$desc = False) {
say $ws x $level, $struct.key;
pretty-print( $struct.value.sort( ).List, :level($level + 1), :$ws, :$desc )
}
 
multi pretty-print (Str $struct, :$level = 0, :$ws = ' ', :$desc = False) {
say $ws x $level , $struct;
}</lang>
{{out}}
<pre>=======================================================
Unsorted:
zeta
beta
gamma
lambda
kappa
mu
delta
alpha
theta
iota
epsilon
 
Sorted ascending:
alpha
epsilon
iota
theta
zeta
beta
delta
gamma
kappa
lambda
mu
 
Sorted descending:
zeta
gamma
mu
lambda
kappa
delta
beta
alpha
theta
iota
epsilon
=======================================================
Unsorted:
zeta
gamma
mu
lambda
kappa
delta
beta
alpha
theta
iota
epsilon
 
Sorted ascending:
alpha
epsilon
iota
theta
zeta
beta
delta
gamma
kappa
lambda
mu
 
Sorted descending:
zeta
gamma
mu
lambda
kappa
delta
beta
alpha
theta
iota
epsilon
=======================================================
Unsorted:
alpha
epsilon
iota
theta
zeta
beta
delta
gamma
kappa
lambda
mu
 
Unwilling to continue; Inconsistent indent characters.
=======================================================
Unsorted:
zeta
beta
gamma
lambda
kappa
mu
delta
alpha
theta
iota
epsilon
 
Unwilling to continue; Inconsistent indentation.</pre>
 
=={{header|Wren}}==
10,327

edits