How to resolve the algorithm Range expansion step by step in the Cowgol programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Range expansion step by step in the Cowgol programming language

Table of Contents

Problem Statement

A format for expressing an ordered list of integers is to use a comma separated list of either Example The list of integers: Is accurately expressed by the range expression: (And vice-versa).

Expand the range description: Note that the second element above, is the range from minus 3 to minus 1.

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Range expansion step by step in the Cowgol programming language

Source code in the cowgol programming language

include "cowgol.coh";

# Callback interface 
interface RangeCb(n: int32);

# This will call `cb' for each number in the range, in ascending order.
# It will return NULL on success, or the location of an error if
# there is one.
sub Expand(ranges: [uint8], cb: RangeCb): (err: [uint8]) is
    err := 0 as [uint8];
    loop
        # Grab first number
        var n1: int32;
        var next: [uint8];
        (n1, next) := AToI(ranges);
        
        if next == ranges then
            # No number here!
            err := ranges; 
            break;
        elseif [next] == ',' or [next] == 0 then
            # Only one number, not a range
            cb(n1);
        elseif [next] != '-' then
            # No dash! 
            err := ranges;
            break;
        else    
            # Grab second number
            ranges := @next next;
            var n2: int32;
            (n2, next) := AToI(ranges);
            if next == ranges or n1 >= n2 then
                # No second number, or first not before second
                err := ranges;
                break;
            end if;
          
            # We need all numbers from n1 to n2 inclusive
            while n1 <= n2 loop
                cb(n1);
                n1 := n1 + 1;
            end loop;
        end if;

        # stop if end reached
        if [next] == 0 then break;
        elseif [next] != ',' then
            err := ranges;
            break;
        end if;
        ranges := @next next;
    end loop;
end sub;

# This function will use `Expand' above to expand a comma-separated
# range list, and reformat it as a comma-separated list of integers.
sub ExpandFmt(ranges: [uint8], buf: [uint8]): (err: [uint8]) is
    # Format and add number to buffer
    sub AddNum implements RangeCb is
        buf := IToA(n, 10, buf);
        [buf] := ',';
        buf := @next buf;
    end sub;
    
    # Expand range, adding numbers to buffer
    err := Expand(ranges, AddNum);
    [@prev buf] := 0;
end sub;

# Expand and print, and/or give error
sub PrintExpansion(ranges: [uint8]) is
    var buf: uint8[256];
    var err := ExpandFmt(ranges, &buf[0]);
    print(ranges);
    print_nl();
    print("  >> ");
    if err == 0 as [uint8] then
        # everything is OK
        print(&buf[0]);
    else
        # error
        print("error at: ");
        print(err);
    end if;
    print_nl();
end sub;

# Try it on the given input
PrintExpansion("-6,-3--1,3-5,7-11,14,15,17-20");

# Try it on a couple of wrong ones
PrintExpansion("-6-3--1,3-5,7-11,14,15,17-20"); # misformatted range
PrintExpansion("-6,-3--1,5-3,7-11,14,15,17-20"); # numbers not in order

  

You may also check:How to resolve the algorithm Averages/Pythagorean means step by step in the zkl programming language
You may also check:How to resolve the algorithm Combinations with repetitions step by step in the Stata programming language
You may also check:How to resolve the algorithm Munching squares step by step in the XPL0 programming language
You may also check:How to resolve the algorithm Wilson primes of order n step by step in the Raku programming language
You may also check:How to resolve the algorithm Hello world/Text step by step in the JSE programming language