Sort an outline at every level: Difference between revisions

Content added Content deleted
m (→‎{{header|Wren}}: Minor tidy)
(New post.)
Line 916: Line 916:
epsilon
epsilon
}}</syntaxhighlight>
}}</syntaxhighlight>

=={{header|Java}}==
<syntaxhighlight lang="java">
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public final class SortAnOutlineAtEveryLevel {

public static void main(String[] args) {
Outline outline_4spaces = initialiseOutline("""
zeta
beta
gamma
lambda
kappa
mu
delta
alpha
theta
iota
epsilon""");
Outline outline_1tab = initialiseOutline("""
zeta
gamma
mu
lambda
kappa
delta
beta
alpha
theta
iota
epsilon""");
System.out.println("Given the text containing spaces: " + outline_4spaces);
System.out.println("The ascending sorted text is: " + outline_4spaces.sort(Sort.ASCENDING));
System.out.println("The descending sorted text is: " + outline_4spaces.sort(Sort.DESCENDING));
System.out.println("Given the text containing tabs: " + outline_1tab);
System.out.println("The ascending sorted text is: " + outline_1tab.sort(Sort.ASCENDING));
System.out.println("The descending sorted text is: " + outline_1tab.sort(Sort.DESCENDING));
try {
System.out.println("Trying to parse the first bad outline:");
@SuppressWarnings("unused")
var outline_bad1 = initialiseOutline("""
alpha
epsilon
iota
theta
zeta
beta
delta
gamma
kappa
lambda
mu""");
} catch (AssertionError error) {
System.err.println(error.getMessage());
}
try {
System.out.println("Trying to parse the second bad outline:");
@SuppressWarnings("unused")
var outlinebad2 = initialiseOutline("""
zeta
beta
gamma
lambda
kappa
mu
delta
alpha
theta
iota
epsilon""");
} catch (AssertionError error) {
System.err.println(error.getMessage());
}
}
private static Outline initialiseOutline(String text) {
OutlineEntry root = new OutlineEntry("", 0, null);
List<OutlineEntry> children = new ArrayList<OutlineEntry>();
children.addLast(root);
String[] lines = text.split("\n");
String firstIndent = firstIndent(lines);
int parentIndex = 0;
int previousIndent = 0;
if ( firstIndent.contains(" ") && firstIndent.contains("\t") ) {
throw new AssertionError("Mixed tabs and spaces are not allowed");
}
for ( int i = 0; i < lines.length; i++ ) {
List<String> splits = splitLine(lines[i]);
String blank = splits.get(0);
String content = splits.get(1);
final int currentIndent = blank.length() / firstIndent.length();
if ( currentIndent * firstIndent.length() != blank.length() ) {
throw new AssertionError("Invalid indentation on line " + i);
}
if ( currentIndent > previousIndent ) {
parentIndex = i;
} else if ( currentIndent < previousIndent ) {
parentIndex = parentIndex(children, currentIndent);
}
previousIndent = currentIndent;
OutlineEntry entry = new OutlineEntry(content, currentIndent + 1, children.get(parentIndex));
entry.parent.children.addLast(entry);
children.add(entry);
}
return new Outline(root, firstIndent);
}
private static int parentIndex(List<OutlineEntry> children, int parentLevel) {
for ( int i = children.size() - 1; i >= 0; i-- ) {
if ( children.get(i).level == parentLevel ) {
return i;
}
}
return -1;
}
private static String firstIndent(String[] lines) {
for ( String line : lines ) {
String indent = splitLine(line).getFirst();
if ( ! indent.isEmpty() ) {
return indent;
}
}
return " ";
}
private static List<String> splitLine(String line) {
for ( int i = 0; i < line.length(); i++ ) {
final char ch = line.charAt(i);
if ( ch != ' ' && ch != '\t' ) {
return List.of( line.substring(0, i), line.substring(i) );
}
}
return List.of( line, " " );
}
private enum Sort { ASCENDING, DESCENDING }
private static record Outline(OutlineEntry root, String baseIndent) {
public Outline sort(Sort aSort) {
root.sort(aSort, 0);
return this;
}
public String toString() {
return root.toString(baseIndent);
}
}
private static class OutlineEntry implements Comparable<OutlineEntry> {
public OutlineEntry(String aText, int aLevel, OutlineEntry aParent) {
text = aText;
level = aLevel;
parent = aParent;
}
@Override
public int compareTo(OutlineEntry other) {
return text.compareTo(other.text);
}
public OutlineEntry sort(Sort aSort, int aLevel) {
for ( OutlineEntry child : children ) {
child.sort(aSort, aLevel);
}
if ( aLevel == 0 || aLevel == level ) {
switch ( aSort ) {
case ASCENDING -> Collections.sort(children, Comparator.naturalOrder());
case DESCENDING -> Collections.sort(children, Comparator.reverseOrder());
}
}
return this;
}
public String toString(String aBaseIndent) {
String result = aBaseIndent.repeat(level) + text + "\n";
for ( OutlineEntry child : children ) {
result += child.toString(aBaseIndent);
}
return result;
}
private String text;
private int level;
OutlineEntry parent;
List<OutlineEntry> children = new ArrayList<OutlineEntry>();
}

}
</syntaxhighlight>
{{ out }}
<pre>
Given the text containing spaces:
zeta
beta
gamma
lambda
kappa
mu
delta
alpha
theta
iota
epsilon

The ascending sorted text is:
alpha
epsilon
iota
theta
zeta
beta
delta
gamma
kappa
lambda
mu

The descending sorted text is:
zeta
gamma
mu
lambda
kappa
delta
beta
alpha
theta
iota
epsilon

Given the text containing tabs:
zeta
gamma
mu
lambda
kappa
delta
beta
alpha
theta
iota
epsilon

The ascending sorted text is:
alpha
epsilon
iota
theta
zeta
beta
delta
gamma
kappa
lambda
mu

The descending sorted text is:
zeta
gamma
mu
lambda
kappa
delta
beta
alpha
theta
iota
epsilon

Trying to parse the first bad outline:
Invalid indentation on line 2
Trying to parse the second bad outline:
Invalid indentation on line 2
</pre>


=={{header|Julia}}==
=={{header|Julia}}==