Re: Constructing a number from digits in an arbitrary base

2020-11-02 Thread Brad Gilbert
I believe this is what you were looking for

sum 46, 20, 26, 87, 11 Z* (1, 101, 101² … *)

sum 1234567890.polymod(101 xx *) Z* (1, 101, 101² … *)

On Mon, Nov 2, 2020 at 2:12 PM Sean McAfee  wrote:

> On Fri, Oct 30, 2020 at 2:19 PM Elizabeth Mattijsen 
> wrote:
>
>> > On 30 Oct 2020, at 22:11, Sean McAfee  wrote:
>> > With polymod, I can get the values of digits even in large bases like
>> 101:
>> >
>> > > 1234567890.polymod(101 xx *)
>> > (46 20 26 87 11)
>> >
>> > Given a list of digit values like that, and the base, I want to
>> reconstruct the original number.
>
>
> So you'd basically need a sub that takes a List, and a base factor, and
>> does the necessary arithmetic for you.  I don't think that's in core.  I'd
>> be glad if someone proved me wrong  :-)
>>
>
> Found it!  The "trick" is to use square braces after the colon and base.
> For example, :101[11,87,26,20,46] evaluates to 1234567890.
>
> The digit values have to be supplied most-significant to
> least-significant, the opposite of the order returned by polymod, and the
> base must be known at compile time, but this is definitely the construction
> I was trying to recall originally.  Even nicer for my golfing purposes, the
> list elements are coerced to numbers automatically, so for example :2[True,
> False, True, False] evaluates to 10.
>
> I can't locate any documentation on this feature, but then I couldn't find
> documentation on the dynamic string-parsing version (eg. :2($str)) when I
> looked either, only the literal form, like :2<10101>.
>
>


Re: Constructing a number from digits in an arbitrary base

2020-11-02 Thread Sean McAfee
On Fri, Oct 30, 2020 at 2:19 PM Elizabeth Mattijsen  wrote:

> > On 30 Oct 2020, at 22:11, Sean McAfee  wrote:
> > With polymod, I can get the values of digits even in large bases like
> 101:
> >
> > > 1234567890.polymod(101 xx *)
> > (46 20 26 87 11)
> >
> > Given a list of digit values like that, and the base, I want to
> reconstruct the original number.


So you'd basically need a sub that takes a List, and a base factor, and
> does the necessary arithmetic for you.  I don't think that's in core.  I'd
> be glad if someone proved me wrong  :-)
>

Found it!  The "trick" is to use square braces after the colon and base.
For example, :101[11,87,26,20,46] evaluates to 1234567890.

The digit values have to be supplied most-significant to least-significant,
the opposite of the order returned by polymod, and the base must be known
at compile time, but this is definitely the construction I was trying to
recall originally.  Even nicer for my golfing purposes, the list elements
are coerced to numbers automatically, so for example :2[True, False, True,
False] evaluates to 10.

I can't locate any documentation on this feature, but then I couldn't find
documentation on the dynamic string-parsing version (eg. :2($str)) when I
looked either, only the literal form, like :2<10101>.


Re: Constructing a number from digits in an arbitrary base

2020-10-30 Thread yary
> So you'd basically need a sub that takes a List, and a base factor, and
does the necessary arithmetic for you.  I don't think that's in core.

If that were to exist, would that be an inverse of "polymod"- maybe
"polymul"? - with this property

@decomposed-num = $some_number.polymod(@a-sequence)
if and only if
$some_number = @decomposed-num.polymul(@a-sequence)

-y

On Fri, Oct 30, 2020 at 2:19 PM Elizabeth Mattijsen  wrote:

> > On 30 Oct 2020, at 22:11, Sean McAfee  wrote:
> >
> > Sorry, it seems I wasn't explicit enough.
> >
> > With polymod, I can get the values of digits even in large bases like
> 101:
> >
> > > 1234567890.polymod(101 xx *)
> > (46 20 26 87 11)
> >
> > Given a list of digit values like that, and the base, I want to
> reconstruct the original number.  One way would be the one I originally
> suggested:
> >
> > > sum <46 20 26 87 11> Z* (1, * * 101 ... *)
> > 123456789
> >
> > ...but I'm hoping there's something more concise, shorter, and/or
> readable.
>
> Ah, so it's not about parsing per se.  Sorry I misunderstood.
>
> So you'd basically need a sub that takes a List, and a base factor, and
> does the necessary arithmetic for you.  I don't think that's in core.  I'd
> be glad if someone proved me wrong  :-)
>
>
>
> Liz


Re: Constructing a number from digits in an arbitrary base

2020-10-30 Thread Sean McAfee
On Fri, Oct 30, 2020 at 2:19 PM Elizabeth Mattijsen  wrote:

> > On 30 Oct 2020, at 22:11, Sean McAfee  wrote:
> > > sum <46 20 26 87 11> Z* (1, * * 101 ... *)
> > 123456789
> >
> > ...but I'm hoping there's something more concise, shorter, and/or
> readable.
>
> Ah, so it's not about parsing per se.  Sorry I misunderstood.
>
> So you'd basically need a sub that takes a List, and a base factor, and
> does the necessary arithmetic for you.  I don't think that's in core.  I'd
> be glad if someone proved me wrong  :-)
>

Well, not necessarily even a sub.  Just an expression.

My specific use case at the moment is a golf challenge where I have a list
of objects, some of which are Nil, and I want to create a number from them
where the Nil values are treated as a binary 0 digit and the non-Nil values
as a binary 1 digit, and I'm currently doing it like this:

:2((+«?«@some-are-Nil).join)

As I mentioned, I feel like I've seen a short way to make a number from its
digits, but now I can't remember it.  I could be wrong.  But if it exists
I'm hoping it would let me shave off a few bytes.


Re: Constructing a number from digits in an arbitrary base

2020-10-30 Thread Bruce Gray



> On Oct 30, 2020, at 3:25 PM, Sean McAfee  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()'
13368

$ raku -e 'say :37()'
Cannot convert string to number: Cannot convert radix of 37 (max 36) in 
':37<⏏ABC>' (indicated by ⏏)
  in block  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 .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)


Re: Constructing a number from digits in an arbitrary base

2020-10-30 Thread Elizabeth Mattijsen
> On 30 Oct 2020, at 22:11, Sean McAfee  wrote:
> 
> Sorry, it seems I wasn't explicit enough.
> 
> With polymod, I can get the values of digits even in large bases like 101:
> 
> > 1234567890.polymod(101 xx *)
> (46 20 26 87 11)
> 
> Given a list of digit values like that, and the base, I want to reconstruct 
> the original number.  One way would be the one I originally suggested:
> 
> > sum <46 20 26 87 11> Z* (1, * * 101 ... *)
> 123456789
> 
> ...but I'm hoping there's something more concise, shorter, and/or readable.

Ah, so it's not about parsing per se.  Sorry I misunderstood.

So you'd basically need a sub that takes a List, and a base factor, and does 
the necessary arithmetic for you.  I don't think that's in core.  I'd be glad 
if someone proved me wrong  :-)



Liz

Re: Constructing a number from digits in an arbitrary base

2020-10-30 Thread Sean McAfee
Sorry, it seems I wasn't explicit enough.

With polymod, I can get the values of digits even in large bases like 101:

> 1234567890.polymod(101 xx *)
(46 20 26 87 11)

Given a list of digit values like that, and the base, I want to reconstruct
the original number.  One way would be the one I originally suggested:

> sum <46 20 26 87 11> Z* (1, * * 101 ... *)
1234567890

...but I'm hoping there's something more concise, shorter, and/or readable.


Re: Constructing a number from digits in an arbitrary base

2020-10-30 Thread Elizabeth Mattijsen
$ raku -e 'dd "g".parse-base(17)'
16

> On 30 Oct 2020, at 21:25, Sean McAfee  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, if the 
> base is fixed at compile time.  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?
>