> On Oct 30, 2020, at 3:25 PM, Sean McAfee <eef...@gmail.com> wrote:
> 
> I want to construct a number from its digits in some arbitrary base.  That 
> is, to essentially do the inverse of this kind of polymod call:
> 
>     my @digits = $number.polymod($base xx *);
> 
> I have a nagging feeling that I've seen a very concise way to do this in Raku 
> before, but now it escapes me, and all my searching has found only pages 
> describing basic, ordinary base conversion.
> 
> Obviously for bases from 2-10 one can just concatenate the digits and pass 
> them to a conversion construct like :2(...) or :5(...) or whatever,

That works up to base 36 !

$ raku -e 'say :36(<ABC>)'
13368

$ raku -e 'say :37(<ABC>)'
Cannot convert string to number: Cannot convert radix of 37 (max 36) in 
':37<⏏ABC>' (indicated by ⏏)
  in block <unit> at -e line 1


> if the base is fixed at compile time.

.parse-base allows for runtime definition of the base (without needing EVAL)
$ raku -e 'say <ABC>.parse-base(36)'
13368

> For the more general case the best I can come up with is
> 
>     my $number = sum @digits Z* (1, * * $base ... *);
> 
> Is there a shorter and/or better way?
> 

For base 36 and below, if you are using non-standard symbols as digits (e.g. 
0123456789ᘔƐ like the song “Little Twelve Toes”), I would .trans() into the 
standard symbols, and then .parse-base() .

Above base 36, your solution looks good to me.
Off the top of my head, the only improvements I see are to .reverse (to allow a 
more natural storage of the digits), and to isolate the infinite sequence:
        # Code is not tested
        constant @position_values = 1, * * 62 … *;
        my $number = sum @digits.reverse Z* @position_values;

Oh, and to use the single character Unicode Horizontal Ellipsis, of course. :^)

I should point out that above base 36, you also need selection of symbols, and 
their ordering, to translate the symbols-as-digits into a list of positional 
values.
That is why 36 is the built-in limit, because the choice of symbols and order 
is only obvious (to we hexidecimal-trained humans) up to (Arabic numbers + 
English Alphabet).

-- 
Hope this helps,
Bruce Gray (Util of PerlMonks)

Reply via email to