Question: How to efficiently generate the "look-and-say sequence"?

The so-called look-and-say sequence is something like:

# Starting digit: 0 
0→one 0→
10→one 1, then one 0→
1110→three 1's, then one 0→
3110→one 3, two 1's, then one 0→
132110→… 

Rosetta Code gives an example of how to generate such sequences in Maple; however, the code in that example is lengthy. More to the point, compared to the subsequent Mathematica analogue, it is rather inefficient (though more readable, but that's not the point). 
I slightly modify the original code, and now the modified version is significantly faster than the original one: 
 

restart;

interface(version)NULL

`Standard Worksheet Interface, Maple 2023.1, Windows 10, July 7 2023 Build ID 1723669`

(1)
LookAndSay := proc(m::posint, n::nonnegint := 1, ` $`)::'Vector'(nonnegint);

LookAndSay(5, 0)NULL

Vector[column](%id = 36893490791509382076)

(2)

CodeTools['Usage'](LookAndSay(50), iterations = 4)

memory used=3.99GiB, alloc change=1.92MiB, cpu time=48.73s, real time=25.03s, gc time=39.05s

 

gc()time[real](LookAndSay(50))NULL

25.030

(3)


 

Download LookAndSay.mw

For the sake of convenience, I paste the original Maple code from the page above into here:

generate_seq := proc(s)
	local times, output, i;
	times := 1;
	output := "";
	for i from 2 to StringTools:-Length(s) do
		if (s[i] <> s[i-1]) then
			output := cat(output, times, s[i-1]);
			times := 1; # re-assign
		else 
			times ++;
		end if;
	end do;
	cat(output, times, s[i - 1]);
end proc:

Look_and_Say :=proc(n)
	local value, i;
	value := "1";
	print(value);
	for i from 2 to n do
		value := generate_seq(value);
		print(value);
	end do;
end proc:

#Test:
Look_and_Say(10);

Below is a modified version by me: 

LookAndSay := proc(m::posint, n::nonnegint := 1, $)::'Vector'(nonnegint);
    uses StringTools;
    local delete::'equationlist' := Repeat~(Explode(ExpandCharacterClass(":digit:")), 2), aux::procedure[nonnegint](posint) := proc(_::posint)::nonnegint;
        options cache;
        description "https://rosettacode.org/wiki/Look-and-say_sequence#Maple";
        if _ = 1 then
            n
        else
            local char::'nonemptystring' := String(thisproc(_ - 1)), temp::list(string)(*, str*);
            try
                temp := RegSplit(sprintf("(?=[%s])(?<=(?!%s)[%s])", Unique(char), Join(select[2](foldr, eval(apply), delete, rcurry(OrMap, Unique(char)), curry(curry, Has)), "|"), Unique(char)), char)
            catch "cannot compile regular expression: repetition-operator operand invalid":
                local rule::'equationlist' := (str -> str = Insert(str, 1, " "))~(subs(delete =~ NULL, Generate(2, Support(char))));
                temp := StringSplit(Subs(rule, char), " ") # to be replaced
            end;
            parse(String(seq('length(str), str[1]', str in temp)))
        fi;
    end;
    forget(aux);
    Vector[column](m, aux, datatype = nonnegint)
end:

The form LookAndSay(m, n); produces the first m terms in a "look-and-say" sequence starting with n (which is by default 1). Unfortunately, even if "the modified version is significantly faster than the original one", it is still much slower (25s versus 2.5s) than the uncompiled Mathematica implementation (on the same modern computer):

So, is there a workaround to evaluate LookAndSay(50, 1): in about three seconds (instead of half a minute) in the first call (without looking up a pre-calculated table) (on the same computer) as well? 

Please Wait...