> 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)