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