Table of Contents

About

ARexx does not exactly have a built-in datatype for arrays except from stems which are difficult to declare and address. On the other hand ARexx has a family of functions that concerns words in strings - a word is a sequence of characters delimited by space. The problem is that the space character is not always feasible given a set of inputs that contain words that may have a space character. In consequence, we present a family of Wizardry and Steamworks designed functions that is able to process words delimited by any user-supplied character.

Quicksort

The wasStringQuicksort function sorts a token-delimited sequence of words. For example, given a call:

String = 'Good day!'
Say wasStringQuicksort(String, ' ')

will output: day! Good

/*************************************************************************/
/*    Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3    */
/*************************************************************************/
wasStringQuicksort: procedure /* Sorts strings separated by token.       */
    Parse ARG String,Token,Lambda
 
    Count = wasWords(String, Token)
 
    If Count <= 1 Then Return String
 
    Middle = Trunc(Count/2)
 
    Pivot = wasSubWord(String,Middle,Token)
 
    String = wasDelWord(String,Middle,Token)
    Count = Count - 1
 
    Less = ''
    More = ''
    Do i = 1 To Count
        Word = wasSubWord(String, i, Token)
        Compare = wasStringCompare(Word, Pivot)
        Select
            When Compare = 1 Then
                Select
                    When Less ~= '' Then 
                        Less = Less || Token || Word
                    Otherwise Less = Word
                End
            Otherwise
                Select
                    When More ~= '' Then 
                        More = More || Token || Word
                    Otherwise More = Word
                End
        End
 
    End
 
    Interpret Lambda
 
    Less = wasStringQuicksort(Less,Token,Lambda)
    More = wasStringQuicksort(More,Token,Lambda)
 
    If Less = '' & More ~= '' Then Return Pivot || Token || More
    If Less ~= '' & More = '' Then Return Less || Token || Pivot
 
Return Less || Token || Pivot || Token || More

One extra addition is the Lambda parameter which can be itself a function. The Lambda function is evaluated at run-time within the quick-sort algorithm on every iteration right before the recursive calls. As a consequence, you can do the following:

func = 'Say "Please wait, sorting pivot: "Pivot'
Search = wasStringQuicksort(Search, '/', func)

where

Note that func inherits all the variables within wasStringQuicksort when it is interpreted and thus we are able to extract the current pivot.

Binary Search

wasBinarySearch searches a token-delimited string for a word and returns it when found or the empty string otherwise.

For example, given a call:

String = 'Good day!'
Say wasBinarySearch(String, 'Good', ' ')

will output: Good

/*************************************************************************/
/*    Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3    */
/*************************************************************************/
wasBinarySearch: procedure /* Finds a string within a string by token.   */
    Parse ARG String,Search,Token,Lambda
 
    Count = wasWords(String, Token)
 
    If Count <= 1 Then Return String
 
    Pivot = wasSubWord(String,Trunc(Count/2),Token)
    Index = wasFindWord(String,Pivot,Token)
 
    Compare = wasStringCompare(Pivot, Search)
    Select
        When Compare < 0 Then
            Do
                Less = ''
                Do i = 1 To Index - 1
                    Word = wasSubWord(String,i,Token)
                    Select
                        When Less ~= '' Then Less = Less || Token || Word
                        Otherwise Less = Word
                    End
                End
                String = Less
            End
        When Compare > 0 Then
            Do
                More = ''
                Do i = Index + 1 To Count
                    Word = wasSubWord(String,i,Token)
                    Select
                        When More ~= '' Then More = More || Token || Word
                        Otherwise More = Word
                    End
                End
                String = More
            End
        Otherwise Return Pivot
    End
 
    Interpret Lambda
 
Return wasBinarySearch(String,Search,Token)

A function may be supplied as an additional parameter which will be interpreted before each recursive call.

Insertion Sort

The wasStringInsertSort sorts a token-delimited string of words and returns the result.

For example, given a call:

String = 'Good day!'
Say wasStringInsertSort(String, 'Good', ' ')

will output: Good

/*************************************************************************/
/*    Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3    */
/*************************************************************************/
wasStringInsertSort: procedure /* Sorts strings separated by token.      */
    Parse ARG String,Token
    Count = wasWords(String, Token)
    Do i = 2 To Count
        x = wasSubWord(String, i, Token)
        j = i
        Do While j > 1
            k = wasSubWord(String, j - 1, Token)
            If wasStringCompare(k, x) > -1 Then Leave
            String = wasChgWord(String, j, k, Token)
            j = j - 1
        End
        String = wasChgWord(String, j, x, Token)
    End
Return String

Intersect Two Sets of Token-Delimited Strings

wasSortedSetsIntersect will return the intersection of two token-delimited strings that have been previously sorted. For example, a call such as:

Say wasSortedSetsIntersect('Day/Good/Sir/!', 'Good/!', '/')

will output: Good/!

/*************************************************************************/
/*    Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3    */
/*************************************************************************/
wasSortedSetsIntersect: procedure /* Intersects two sorted sets.         */
    Parse ARG A,B,Token,Lambda
 
    If A = '' | B = '' Then Return ''
 
    Parse VAR A AHead Interpret(Token) ATail
    Parse VAR B BHead Interpret(Token) BTail
 
    Interpret Lambda
 
    If AHead ~= BHead Then
        Do
            Compare = wasStringCompare(AHead, BHead)
            If Compare < 0 Then
                Return wasSortedSetsIntersect(A, BTail, Token)
            If Compare > 0 Then
                Return wasSortedSetsIntersect(ATail, B, Token)
        End
 
    Look = wasSortedSetsIntersect(ATail, BTail, Token)
    If Look ~= '' Then Return AHead || Token || Look
Return AHead

Additionally, the function takes an extra optional parameter that can be a function which will be interpreted before all recursive calls.

Index