How to resolve the algorithm Sort an outline at every level step by step in the Julia programming language
How to resolve the algorithm Sort an outline at every level step by step in the Julia programming language
Table of Contents
Problem Statement
Write and test a function over an indented plain text outline which either:
Your code should detect and warn of at least two types of inconsistent indentation:
Your code should be able to detect and handle both tab-indented, and space-indented (e.g. 4 space, 2 space etc) outlines, without being given any advance warning of the indent characters used, or the size of the indent units. You should also be able to specify different types of sort, for example, as a minimum, both ascending and descending lexical sorts. Your sort should not alter the type or size of the indentation units used in the input outline.
(For an application of Indent Respectful Sort, see the Sublime Text package of that name. The Python source text [1] is available for inspection on Github).
Tests
The output sequence of an ascending lexical sort of each level should be: The output sequence of a descending lexical sort of each level should be:
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Sort an outline at every level step by step in the Julia programming language
The provided Julia code defines a data structure and functions for creating and printing hierarchical outlines from text. Here's a detailed explanation:
-
Outline Entry Structure:
Entry
is an abstract type representing an outline entry.OutlineEntry
is a concrete subtype ofEntry
that represents an outline entry with a level (depth), text, parent entry (optional), and a list of child entries.
-
Outline Structure:
Outline
represents an outline with a root entry, a vector of all entries, and abaseindent
string used for indentation.
-
Helper Functions:
rootentry()
: Creates an empty root outline entry with level 0, empty text, no parent, and no children.indentchar(ch)
: Checks if a character is an indent character (' ' or '\t').firsttext(s)
: Finds the index of the first non-indent character in a string.splitline(s)
: Splits a string into a tuple of the indentation and the text.
-
Custom Print Function for OutlineEntry:
- This function overrides the default
print
behavior forOutlineEntry
objects. - It prints the entry's text, indented by its level.
- It then recursively prints all of its child entries.
- This function overrides the default
-
Custom Print Function for Outline:
- This function overrides the default
print
behavior forOutline
objects. - It pushes the
baseindent
string onto a stack of indents. - It prints the root entry.
- It pops the
baseindent
string from the stack.
- This function overrides the default
-
firstindent(lines)
:- Analyzes the lines of text input to determine the consistent indentation string used in the outline.
- It tries to find the first line that contains non-indent characters and returns the indentation string from that line.
- If no such line is found, it returns a default indentation string.
-
Outline(str)
:- Takes a string representing the outline text.
- Initializes an empty array of
OutlineEntry
objects and an array of lines after filtering out empty lines. - Calculates the
indent
,parentindex
, andlastindents
variables based on the first line's indentation. - Verifies that the indentation is consistent (either all spaces or all tabs).
- Iterates through the lines and creates
OutlineEntry
objects based on the indentation levels. - Sets the parent relationships and adds the entries to the array of entries.
- Returns an
Outline
object with the root entry, array of entries, andbaseindent
string.
-
sorttree!(ent::OutlineEntry)
:- Sorts the children of an
OutlineEntry
object recursively. - Optionally sorts the children of the current entry (if the entry level matches the specified level).
- Sorts the children of an
-
outlinesort!(ol::Outline)
:- Calls
sorttree!
on the root entry of theOutline
object to sort the entire outline.
- Calls
-
Example Usage:
- The code creates two
Outline
objects using sample text. - It demonstrates printing the outlines, sorting them, and sorting them in reverse order.
- It also demonstrates sorting only a specific level of the outline.
- Error Handling:
- The code includes try-catch blocks to handle exceptions that may occur if the input text has invalid indentation or outline structure.
Source code in the julia programming language
import Base.print
abstract type Entry end
mutable struct OutlineEntry <: Entry
level::Int
text::String
parent::Union{Entry, Nothing}
children::Vector{Entry}
end
mutable struct Outline
root::OutlineEntry
entries::Vector{OutlineEntry}
baseindent::String
end
rootentry() = OutlineEntry(0, "", nothing, [])
indentchar(ch) = ch == ' ' || ch == '\t'
firsttext(s) = something(findfirst(!indentchar, s), length(s) + 1)
splitline(s) = begin i = firsttext(s); i == 1 ? ("", s) : (s[1:i-1], s[i:end]) end
const _indents = [" "]
function Base.print(io::IO, oe::OutlineEntry)
println(io, _indents[end]^oe.level, oe.text)
for child in oe.children
print(io, child)
end
end
function Base.print(io::IO, o::Outline)
push!(_indents, o.baseindent)
print(io, o.root)
pop!(_indents)
end
function firstindent(lines, default = " ")
for lin in lines
s1, s2 = splitline(lin)
s1 != "" && return s1
end
return default
end
function Outline(str::String)
arr, lines = OutlineEntry[], filter(x -> x != "", split(str, r"\r\n|\n|\r"))
root, indent, parentindex, lastindents = rootentry(), firstindent(lines), 0, 0
if ' ' in indent && '\t' in indent
throw("Mixed tabs and spaces in indent are not allowed")
end
indentlen, indentregex = length(indent), Regex(indent)
for (i, lin) in enumerate(lines)
header, txt = splitline(lin)
indentcount = length(collect(eachmatch(indentregex, header)))
(indentcount * indentlen < length(header)) &&
throw("Error: bad indent " * string(UInt8.([c for c in header])) *
", expected " * string(UInt8.([c for c in indent])))
if indentcount > lastindents
parentindex = i - 1
elseif indentcount < lastindents
parentindex = something(findlast(x -> x.level == indentcount - 1, arr), 0)
end
lastindents = indentcount
ent = OutlineEntry(indentcount, txt, parentindex == 0 ? root : arr[parentindex], [])
push!(ent.parent.children, ent)
push!(arr, ent)
end
return Outline(root, arr, indent)
end
function sorttree!(ent::OutlineEntry, rev=false, level=0)
for child in ent.children
sorttree!(child, rev)
end
if level == 0 || level == ent.level
sort!(ent.children, lt=(x, y) -> x.text < y.text, rev=rev)
end
return ent
end
outlinesort!(ol::Outline, rev=false, lev=0) = begin sorttree!(ol.root, rev, lev); ol end
const outline4s = Outline("""
zeta
beta
gamma
lambda
kappa
mu
delta
alpha
theta
iota
epsilon""")
const outlinet1 = Outline("""
zeta
gamma
mu
lambda
kappa
delta
beta
alpha
theta
iota
epsilon""")
println("Given the text:\n", outline4s)
println("Sorted outline is:\n", outlinesort!(outline4s))
println("Reverse sorted is:\n", outlinesort!(outline4s, true))
println("Using the text:\n", outlinet1)
println("Sorted outline is:\n", outlinesort!(outlinet1))
println("Reverse sorted is:\n", outlinesort!(outlinet1, true))
println("Sorting only third level:\n", outlinesort!(outlinet1, false, 3))
try
println("Trying to parse a bad outline:")
outlinebad1 = Outline("""
alpha
epsilon
iota
theta
zeta
beta
delta
gamma
kappa
lambda
mu""")
catch y
println(y)
end
try
println("Trying to parse another bad outline:")
outlinebad2 = Outline("""
zeta
beta
gamma
lambda
kappa
mu
delta
alpha
theta
iota
epsilon""")
catch y
println(y)
end
You may also check:How to resolve the algorithm Hello world/Text step by step in the Wisp programming language
You may also check:How to resolve the algorithm FizzBuzz step by step in the GDScript programming language
You may also check:How to resolve the algorithm Send email step by step in the Java programming language
You may also check:How to resolve the algorithm Character codes step by step in the Lasso programming language
You may also check:How to resolve the algorithm Memory allocation step by step in the zkl programming language