Re: Constructing a number from digits in an arbitrary base
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
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
> 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
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
> 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
> 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
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
$ 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
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?