How to resolve the algorithm Align columns step by step in the Kotlin programming language

Published on 22 June 2024 08:30 PM

How to resolve the algorithm Align columns step by step in the Kotlin programming language

Table of Contents

Problem Statement

Given a text file of many lines, where fields within a line are delineated by a single 'dollar' character, write a program that aligns each column of fields by ensuring that words in each column are separated by at least one space. Further, allow for each word in a column to be either left justified, right justified, or center justified within its column. Use the following text to test your programs:

Note that:

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Align columns step by step in the Kotlin programming language

Objective: The code reads data from a file and aligns its contents into columns separated by pipes ("|"). The columns can be aligned left, right, or centered.

Implementation Details:

Enum Class AlignFunction:

  • An enum class defining three alignment functions: LEFT, RIGHT, and CENTER.
  • Each function takes a string and a length as input and formats the string according to the specified alignment.

Class ColumnAligner:

  • Constructor: Takes a list of strings and initializes the column aligner.

  • Operator Kotlin extension function invoke(a: AlignFunction): String:

    • The main function that aligns the data into columns.
    • Iterates over the "words" (tokenized strings) in each line and aligns them using the provided alignment function a.
    • Joins the aligned words with pipes and newlines to form the final aligned output.

Internal Implementation of ColumnAligner:

  • words: A 2D array of strings representing the tokenized words from each line.
  • column_widths: An array of integers representing the maximum width of each column.

Parsing the Input Data:

  • The lines from the file are read into a list.
  • Each line is split into "words" using a custom separator "$".
  • The words and column widths are updated for each line.

Main Function:

  • Reads the file name and alignment option (if any) from command line arguments.
  • If no alignment is specified, the default is "L" (left).
  • Creates a ColumnAligner object and prints the aligned data based on the specified alignment.

Example Usage: To align the contents of a file called "data.txt" left-aligned, run the program as follows:

ColumnAligner data.txt L

Output:

The output will be printed to the console, with the data in the file aligned into columns separated by pipes. The alignment will depend on the specified option ("L", "R", or "C").

Source code in the kotlin programming language

import java.nio.charset.StandardCharsets
import java.nio.file.Files
import java.nio.file.Paths

enum class AlignFunction {
    LEFT { override fun invoke(s: String, l: Int) = ("%-" + l + 's').format(("%" + s.length + 's').format(s)) },
    RIGHT { override fun invoke(s: String, l: Int) = ("%-" + l + 's').format(("%" + l + 's').format(s)) },
    CENTER { override fun invoke(s: String, l: Int) = ("%-" + l + 's').format(("%" + ((l + s.length) / 2) + 's').format(s)) };

    abstract operator fun invoke(s: String, l: Int): String
}

/** Aligns fields into columns, separated by "|".
 * @constructor Initializes columns aligner from lines in a list of strings.
 * @property lines Lines in a single string. Empty string does form a column.
 */
class ColumnAligner(val lines: List<String>) {
     operator fun invoke(a: AlignFunction) : String {
        var result = ""
        for (lineWords in words) {
            for (i in lineWords.indices) {
                if (i == 0)
                    result += '|'
                result += a(lineWords[i], column_widths[i])
                result += '|'
            }
            result += '\n'
        }
        return result
    }

    private val words = arrayListOf<Array<String>>()
    private val column_widths = arrayListOf<Int>()

    init {
        lines.forEach  {
            val lineWords = java.lang.String(it).split("\\$")
            words += lineWords
            for (i in lineWords.indices) {
                if (i >= column_widths.size) {
                    column_widths += lineWords[i].length
                } else {
                    column_widths[i] = Math.max(column_widths[i], lineWords[i].length)
                }
            }
        }
    }
}

fun main(args: Array<String>) {
    if (args.isEmpty()) {
        println("Usage: ColumnAligner file [L|R|C]")
        return
    }
    val ca = ColumnAligner(Files.readAllLines(Paths.get(args[0]), StandardCharsets.UTF_8))
    val alignment = if (args.size >= 2) args[1] else "L"
    when (alignment) {
        "L" -> print(ca(AlignFunction.LEFT))
        "R" -> print(ca(AlignFunction.RIGHT))
        "C" -> print(ca(AlignFunction.CENTER))
        else -> System.err.println("Error! Unknown alignment: " + alignment)
    }
}


  

You may also check:How to resolve the algorithm Munchausen numbers step by step in the Ada programming language
You may also check:How to resolve the algorithm Jewels and stones step by step in the Ring programming language
You may also check:How to resolve the algorithm Averages/Mode step by step in the Sidef programming language
You may also check:How to resolve the algorithm Determine sentence type step by step in the Ring programming language
You may also check:How to resolve the algorithm Align columns step by step in the OCaml programming language