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


Constructing a number from digits in an arbitrary base

2020-10-30 Thread Sean McAfee
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?