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:

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.


Note that:

   The example input texts lines may, or may not, have trailing dollar characters.
   All columns should share the same alignment.
   Consecutive space characters produced adjacent to the end of lines are insignificant for the purposes of the task.
   Output text will be viewed in a mono-spaced font on a plain text editor or basic terminal.
   The minimum space between columns should be computed from the text and not hard-coded.
   It is not a requirement to add separating characters between or around columns.



Other tasks related to string operations:

Metrics
 Array length
 String length
 Copy a string
 Empty string  (assignment)
Counting
 Word frequency
 Letter frequency
 Jewels and stones
 I before E except after C
 Bioinformatics/base count
 Count occurrences of a substring
 Count how many vowels and consonants occur in a string
Remove/replace
 XXXX redacted
 Conjugate a Latin verb
 Remove vowels from a string
 String interpolation (included)
 Strip block comments
 Strip comments from a string
 Strip a set of characters from a string
 Strip whitespace from a string -- top and tail
 Strip control codes and extended characters from a string
Anagrams/Derangements/shuffling
 Word wheel
 ABC problem
 Sattolo cycle
 Knuth shuffle
 Ordered words
 Superpermutation minimisation
 Textonyms (using a phone text pad)
 Anagrams
 Anagrams/Deranged anagrams
 Permutations/Derangements
Find/Search/Determine
 ABC words
 Odd words
 Word ladder
 Semordnilap
 Word search
 Wordiff  (game)
 String matching
 Tea cup rim text
 Alternade words
 Changeable words
 State name puzzle
 String comparison
 Unique characters
 Unique characters in each string
 Extract file extension
 Levenshtein distance
 Palindrome detection
 Common list elements
 Longest common suffix
 Longest common prefix
 Compare a list of strings 
 Longest common substring
 Find common directory path
 Words from neighbour ones
 Change e letters to i in words
 Non-continuous subsequences
 Longest common subsequence
 Longest palindromic substrings
 Longest increasing subsequence
 Words containing "the" substring
 Sum of the digits of n is substring of n
 Determine if a string is numeric
 Determine if a string is collapsible
 Determine if a string is squeezable
 Determine if a string has all unique characters
 Determine if a string has all the same characters
 Longest substrings without repeating characters
 Find words which contains all the vowels
 Find words which contains most consonants
 Find words which contains more than 3 vowels
 Find words which first and last three letters are equals
 Find words which odd letters are consonants and even letters are vowels or vice_versa
Formatting
 Substring
 Rep-string
 Word wrap
 String case
 Align columns
 Literals/String
 Repeat a string
 Brace expansion
 Brace expansion using ranges
 Reverse a string
 Phrase reversals
 Comma quibbling
 Special characters
 String concatenation
 Substring/Top and tail
 Commatizing numbers
 Reverse words in a string
 Suffixation of decimal numbers
 Long literals, with continuations 
 Numerical and alphabetical suffixes
 Abbreviations, easy
 Abbreviations, simple
 Abbreviations, automatic
Song lyrics/poems/Mad Libs/phrases
 Mad Libs
 Magic 8-ball
 99 Bottles of Beer
 The Name Game (a song)
 The Old lady swallowed a fly
 The Twelve Days of Christmas
Tokenize
 Text between
 Tokenize a string
 Word break problem
 Tokenize a string with escaping
 Split a character string based on change of character
Sequences
 Show ASCII table
 De Bruijn sequences
 Self-referential sequences
 Generate lower case ASCII alphabet




 
/* ARM assembly AARCH64 Raspberry PI 3B or android 64 bits */
/*  program alignColumn64.s     */
 
/*******************************************/
/* Constantes file                         */
/*******************************************/
/* for this file see task include a file in language AArch64 assembly*/
.include "../includeConstantesARM64.inc"
 
.equ BUFFERSIZE, 16 * 10
 
/*********************************/
/* Initialized data              */
/*********************************/
.data
szMessLeft:        .asciz "LEFT :\n"
szMessRight:       .asciz "\nRIGHT :\n" 
szMessCenter:      .asciz "\nCENTER :\n" 
szCarriageReturn:  .asciz "\n"
 
szLine1:    .asciz "Given$a$text$file$of$many$lines,$where$fields$within$a$line$"
szLine2:    .asciz "are$delineated$by$a$single$'dollar'$character,$write$a$program"
szLine3:    .asciz "that$aligns$each$column$of$fields$by$ensuring$that$words$in$each$"
szLine4:    .asciz "column$are$separated$by$at$least$one$space."
szLine5:    .asciz "Further,$allow$for$each$word$in$a$column$to$be$either$left$"
szLine6:    .asciz "justified,$right$justified,$or$center$justified$within$its$column."
 
.align 8
qtbPtLine:    .quad szLine1,szLine2,szLine3,szLine4,szLine5,szLine6
              .equ NBLINES, (. - qtbPtLine) / 8
 
/*********************************/
/* UnInitialized data            */
/*********************************/
.bss  
/*********************************/
/*  code section                 */
/*********************************/
.text
.global main 
main:                               // entry of program 
    ldr x0,qAdrqtbPtLine
    bl computeMaxiLengthWords
    mov x19,x0                      // column counter
    ldr x0,qAdrszMessLeft
    bl affichageMess
    ldr x0,qAdrqtbPtLine
    mov x1,x19                      // column size
    bl alignLeft
    ldr x0,qAdrszMessRight
    bl affichageMess
    ldr x0,qAdrqtbPtLine
    mov x1,x19                      // column size
    bl alignRight
    ldr x0,qAdrszMessCenter
    bl affichageMess
    ldr x0,qAdrqtbPtLine
    mov x1,x19                      // column size
    bl alignCenter
100:                                // standard end of the program 
    mov x0, #0                      // return code
    mov x8, #EXIT                   // request to exit program
    svc #0                          // perform the system call
qAdrszCarriageReturn:     .quad szCarriageReturn
qAdrszMessLeft:           .quad szMessLeft
qAdrszMessRight:          .quad szMessRight
qAdrszMessCenter:         .quad szMessCenter
qAdrqtbPtLine:            .quad qtbPtLine
/******************************************************************/
/*      compute maxi words                                 */ 
/******************************************************************/
/* x0 contains adresse pointer array */
computeMaxiLengthWords:
    stp fp,lr,[sp,-16]!      // save  registres
    mov x2,#0                // indice pointer array
    mov x3,#0                // maxi length words
1:
    ldr x1,[x0,x2,lsl #3]    // load pointer
    mov x4,#0                // length words counter
    mov x5,#0                // indice line character
2:
    ldrb w6,[x1,x5]          // load a line character
    cmp x6,#0                // line end ?
    beq 4f
    cmp x6,#'$'              // separator ?
    bne 3f
    cmp x4,x3
    csel x3,x4,x3,gt         // if greather replace maxi
    mov x4,#-1               // raz length counter
3:
    add x4,x4,#1
    add x5,x5,#1             // increment character indice
    b 2b                     // and loop
4:                           // end line
    cmp x4,x3                // compare word counter and maxi
    csel x3,x4,x3,gt         // if greather replace maxi
    add x2,x2,#1             // increment indice line pointer
    cmp x2,#NBLINES          // maxi ?
    blt 1b                   // no -> loop
 
    mov x0,x3                // return maxi length counter
100:
    ldp fp,lr,[sp],16        // restaur des  2 registres
    ret
 
/******************************************************************/
/*      align left                                                */ 
/******************************************************************/
/* x0 contains the address of pointer array*/
/* x1 contains column size */
alignLeft:
    stp fp,lr,[sp,-16]!       // save  registres
    sub sp,sp,#BUFFERSIZE    // reserve place for output buffer
    mov fp,sp
    mov x5,x0                // array address
    mov x2,#0                // indice array
1:
    ldr x3,[x5,x2,lsl #3]    // load line pointer
    mov x4,#0                // line character indice
    mov x7,#0                // output buffer character indice
    mov x6,#0                // word lenght 
2:
    ldrb w0,[x3,x4]          // load a character line
    strb w0,[fp,x7]          // store in buffer
    cmp w0,#0                // line end ?
    beq 6f
    cmp w0,#'$'              // separator ?
    bne 5f
    mov x0,#' '
    strb w0,[fp,x7]          // replace $ by space
3:
    cmp x6,x1                // length word >= length column
    bge 4f
    add x7,x7,#1
    mov x0,#' '
    strb w0,[fp,x7]          // add space to buffer
    add x6,x6,#1
    b 3b                     // and loop
4:
    mov x6,#-1               // raz word length
5:
    add x4,x4,#1             // increment line indice
    add x7,x7,#1             // increment buffer indice
    add x6,x6,#1             // increment word length
    b 2b
 
6:
    mov x0,#'\n'
    strb w0,[fp,x7]          // return line
    add x7,x7,#1
    mov x0,#0
    strb w0,[fp,x7]          // final zéro
    mov x0,fp
    bl affichageMess         // display output buffer
    add x2,x2,#1
    cmp x2,#NBLINES
    blt 1b
 
100:
    add sp,sp,#BUFFERSIZE
    ldp fp,lr,[sp],16        // restaur des  2 registres
    ret
/******************************************************************/
/*      align right                                                */ 
/******************************************************************/
/* x0 contains the address of pointer array*/
/* x1 contains column size */
alignRight:
    stp fp,lr,[sp,-16]!       // save  registres
    sub sp,sp,#BUFFERSIZE    // reserve place for output buffer
    mov fp,sp
    mov x5,x0                // array address
    mov x2,#0                // indice array
1:
    ldr x3,[x5,x2,lsl #3]    // load line pointer
    mov x4,#0                // line character indice
    mov x7,#0                // output buffer character indice
    mov x6,#0                // word lenght 
    mov x8,x3                // word begin address
2:                           // compute word length
    ldrb w0,[x3,x4]          // load a character line
    cmp w0,#0                // line end ?
    beq 3f
    cmp w0,#'$'              // separator ?
    beq 3f
    add x4,x4,#1             // increment line indice
    add x6,x6,#1             // increment word length
    b 2b
 
3:
    cmp x6,#0
    beq 4f
    sub x6,x1,x6             // compute left spaces to add
4:                           // loop add spaces to buffer
    cmp x6,#0
    blt 5f
    mov x0,#' '
    strb w0,[fp,x7]          // add space to buffer
    add x7,x7,#1
    sub x6,x6,#1
    b 4b                     // and loop
5:
    mov x9,#0
6:                           // copy loop word to buffer
    ldrb w0,[x8,x9]
    cmp x0,#'$'
    beq 7f
    cmp x0,#0                // line end
    beq 8f
    strb w0,[fp,x7]
    add x7,x7,#1
    add x9,x9,#1
    b 6b
7:
    add x8,x8,x9
    add x8,x8,#1             // new word begin
    mov x6,#0                // raz word length
    add x4,x4,#1             // increment line indice
    b 2b
 
8:
    mov x0,#'\n'
    strb w0,[fp,x7]          // return line
    add x7,x7,#1
    mov x0,#0
    strb w0,[fp,x7]          // final zéro
    mov x0,fp
    bl affichageMess         // display output buffer
    add x2,x2,#1
    cmp x2,#NBLINES
    blt 1b
 
100:
    add sp,sp,#BUFFERSIZE
    ldp fp,lr,[sp],16        // restaur des  2 registres
    ret
/******************************************************************/
/*      align center                                                */ 
/******************************************************************/
/* x0 contains the address of pointer array*/
/* x1 contains column size */
alignCenter:
    stp fp,lr,[sp,-16]!      // save  registres
    sub sp,sp,#BUFFERSIZE    // reserve place for output buffer
    mov fp,sp
    mov x5,x0                // array address
    mov x2,#0                // indice array
1:
    ldr x3,[x5,x2,lsl #3]    // load line pointer
    mov x4,#0                // line character indice
    mov x7,#0                // output buffer character indice
    mov x6,#0                // word length
    mov x8,x3                // word begin address
2:                           // compute word length
    ldrb w0,[x3,x4]          // load a character line
    cmp w0,#0                // line end ?
    beq 3f
    cmp w0,#'$'              // separator ?
    beq 3f
    add x4,x4,#1             // increment line indice
    add x6,x6,#1             // increment word length
    b 2b
3:
    cmp x6,#0
    beq 5f
    sub x6,x1,x6             // total spaces number to add
    mov x12,x6
    lsr x6,x6,#1             // divise by 2 = left spaces number
4:
    cmp x6,#0
    blt 5f
    mov x0,#' '
    strb w0,[fp,x7]          // add space to buffer
    add x7,x7,#1             // increment output indice
    sub x6,x6,#1             // decrement number space
    b 4b                     // and loop
5:
    mov x9,#0
6:                           // copy loop word to buffer
    ldrb w0,[x8,x9]
    cmp x0,#'$'              // séparator ?
    beq 7f
    cmp x0,#0                // line end ?
    beq 10f
    strb w0,[fp,x7]
    add x7,x7,#1
    add x9,x9,#1
    b 6b
7:
    lsr x6,x12,#1            // divise total spaces by 2
    sub x6,x12,x6            // and compute number spaces to right side
8:                           // loop to add right spaces 
    cmp x6,#0
    ble 9f
    mov x0,#' '
    strb w0,[fp,x7]          // add space to buffer
    add x7,x7,#1
    sub x6,x6,#1
    b 8b                     // and loop
 
9:
    add x8,x8,x9
    add x8,x8,#1             // new address word begin
    mov x6,#0                // raz word length
    add x4,x4,#1             // increment line indice
    b 2b                     // and loop new word
 
10:
    mov x0,#'\n'
    strb w0,[fp,x7]          // return line
    add x7,x7,#1
    mov x0,#0
    strb w0,[fp,x7]          // final zéro
    mov x0,fp
    bl affichageMess         // display output buffer
    add x2,x2,#1             // increment line indice
    cmp x2,#NBLINES          // maxi ?
    blt 1b                   // loop
 
100:
    add sp,sp,#BUFFERSIZE
    ldp fp,lr,[sp],16        // restaur des  2 registres
    ret
/********************************************************/
/*        File Include fonctions                        */
/********************************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"
 