How to resolve the algorithm Run-length encoding step by step in the AppleScript programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Run-length encoding step by step in the AppleScript programming language

Table of Contents

Problem Statement

Given a string containing uppercase characters (A-Z), compress repeated 'runs' of the same character by storing the length of that run, and provide a function to reverse the compression. The output can be anything, as long as you can recreate the input with it.

Note: the encoding step in the above example is the same as a step of the Look-and-say sequence.

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Run-length encoding step by step in the AppleScript programming language

Source code in the applescript programming language

------------------ RUN-LENGTH ENCODING‎‎ -----------------

-- encode :: String -> String
on encode(s)
    script go
        on |λ|(cs)
            if {}  cs then
                set c to text 1 of cs
                set {chunk, residue} to span(eq(c), rest of cs)
                (c & (1 + (length of chunk)) as string) & |λ|(residue)
            else
                ""
            end if
        end |λ|
    end script
    |λ|(characters of s) of go
end encode


-- decode :: String -> String
on decode(s)
    script go
        on |λ|(cs)
            if {}  cs then
                set {ds, residue} to span(my isDigit, rest of cs)
                set n to (ds as string) as integer
                replicate(n, item 1 of cs) & |λ|(residue)
            else
                ""
            end if
        end |λ|
    end script
    |λ|(characters of s) of go
end decode


--------------------------- TEST -------------------------
on run
    set src to ¬
        "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW"
    set encoded to encode(src)
    set decoded to decode(encoded)
    
    unlines({encoded, decoded, src = decoded})
end run


-------------------- GENERIC FUNCTIONS -------------------

-- eq :: a -> a -> Bool
on eq(a)
    -- True if a and b are equivalent in terms
    -- of the AppleScript (=) operator.
    script go
        on |λ|(b)
            a = b
        end |λ|
    end script
end eq


-- isDigit :: Char -> Bool
on isDigit(c)
    set n to (id of c)
    48  n and 57  n
end isDigit


-- mReturn :: First-class m => (a -> b) -> m (a -> b)
on mReturn(f)
    -- 2nd class handler function lifted into 1st class script wrapper. 
    if script is class of f then
        f
    else
        script
            property |λ| : f
        end script
    end if
end mReturn


-- Egyptian multiplication - progressively doubling a list, appending
-- stages of doubling to an accumulator where needed for binary 
-- assembly of a target length
-- replicate :: Int -> String -> String
on replicate(n, s)
    -- Egyptian multiplication - progressively doubling a list, 
    -- appending stages of doubling to an accumulator where needed 
    -- for binary assembly of a target length
    script p
        on |λ|({n})
            n  1
        end |λ|
    end script
    
    script f
        on |λ|({n, dbl, out})
            if (n mod 2) > 0 then
                set d to out & dbl
            else
                set d to out
            end if
            {n div 2, dbl & dbl, d}
        end |λ|
    end script
    
    set xs to |until|(p, f, {n, s, ""})
    item 2 of xs & item 3 of xs
end replicate


-- span :: (a -> Bool) -> [a] -> ([a], [a])
on span(p, xs)
    -- The longest (possibly empty) prefix of xs
    -- that contains only elements satisfying p,
    -- tupled with the remainder of xs.
    -- span(p, xs) eq (takeWhile(p, xs), dropWhile(p, xs)) 
    script go
        property mp : mReturn(p)
        on |λ|(vs)
            if {}  vs then
                set x to item 1 of vs
                if |λ|(x) of mp then
                    set {ys, zs} to |λ|(rest of vs)
                    {{x} & ys, zs}
                else
                    {{}, vs}
                end if
            else
                {{}, {}}
            end if
        end |λ|
    end script
    |λ|(xs) of go
end span


-- unlines :: [String] -> String
on unlines(xs)
    -- A single string formed by the intercalation
    -- of a list of strings with the newline character.
    set {dlm, my text item delimiters} to ¬
        {my text item delimiters, linefeed}
    set s to xs as text
    set my text item delimiters to dlm
    s
end unlines


-- until :: (a -> Bool) -> (a -> a) -> a -> a
on |until|(p, f, x)
    set v to x
    set mp to mReturn(p)
    set mf to mReturn(f)
    repeat until mp's |λ|(v)
        set v to mf's |λ|(v)
    end repeat
    v
end |until|


  

You may also check:How to resolve the algorithm Magnanimous numbers step by step in the Factor programming language
You may also check:How to resolve the algorithm Formal power series step by step in the D programming language
You may also check:How to resolve the algorithm Proper divisors step by step in the VBA programming language
You may also check:How to resolve the algorithm Execute a Markov algorithm step by step in the Java programming language
You may also check:How to resolve the algorithm Jacobi symbol step by step in the AutoHotkey programming language