Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

Re: Rosetta PGA-TRAM

by moritz (Cardinal)
on Jun 13, 2009 at 12:31 UTC ( #771227=note: print w/replies, xml ) Need Help??

in reply to Rosetta PGA-TRAM

I wrote a Perl 6 version (transcoded from the Perl 5 version), which uses the following improvements:
  • Instead of another scope for %rtoa, I used a state variable (also available in perl-5.10)
  • I wrote the "pipeline" as a set of method calls, which means they are read in the order that they are executed
  • Use of a formal parameter
  • say instead of print (also available in 5.10)
  • (Updated) use hyphens instead of underscores as word separator in the sub name. It's a matter of taste, but I like it better that way.

Here's the code, which works with today's Rakudo:

sub roman-to-dec($x) { state %rtoa = M=>1000, D=>500, C=>100, L=>50, X=>10, V=>5, I=>1; $x.uc.split('').map({ %rtoa{$_} }).reduce: { $^a+$^b-$a%$b*2 } } my @testdata = <XLII LXIX mi>; for @testdata -> $r { say "$r: ", roman-to-dec($r); }

Replies are listed 'Best First'.
Re^2: Rosetta PGA-TRAM
by John M. Dlugosz (Monsignor) on Jun 17, 2009 at 22:33 UTC
    Why does the block use $^a in one place (the automatic parameter) and $a in another place? Shouldn't that be a different (undeclared) variable? (Likewise for b).

    If you move the uc you can avoid copying the whole string. Not much savings for a small string I suppose, but you break the clean pipeline nature by copying the input first, rather than doing nothing more than passing each character through the pipeline.

    $x.split('').map({ %rtoa{$_.uc} }).reduce: { $^a+$^b-$a%$b*2 }
    Here's a shaken-up version, starting with noticing how the list return of a for loop is similar to the map function:
       sub infix:<ↀ> ($a,$b) { $a+$b-$a%$b*2 }
       [ↀ] do for $x.split('') { %rtoa{$_.uc} }
    and an excuse to show off the cool form of the reduction metaoperator.

    P.S.: used pre instead of code because Perl Monks still doesn't like Unicode. code escapes out the entities, and the form isn't submitted in UTF-8 so various things are automatically encoded. Nasty.

      Why does the block use $^a in one place (the automatic parameter) and $a in another place? Shouldn't that be a different (undeclared) variable? (Likewise for b).

      No, the ^ twigil is only necessary in the first occurrence. That was introduced because things like this:

      my $block = { my $v = %hash{$^key}; say "The lookup {%hash{$^key}} yields $v"; };

      Would complain about the closure inside the string getting no argument, because $^key was interpreted as a formal parameter to the inner-most closure, which in this case was the one inside the string.

      Or more general, you couldn't refer to outer lexicals that happened to be self-declaring formal parameters.

      So it was decided that after $^foo occurred once, you could refer to it as $foo to, disambiguating it in inner blocks.

        I see. I must have overlooked that when I read through the diffs with the last version I studied carefully. It's so easy to overlook changed or especially removed things!
Re^2: Rosetta PGA-TRAM
by John M. Dlugosz (Monsignor) on Jun 17, 2009 at 22:53 UTC
    I notice your use of the indirect object form at the very end to avoid parens around (just) brackets. But didn't do so in the other place, because it's not at the end. Moving one paren doesn't make it much better. But you could use feed notation and lose the parens in both places:
    $result= ( $x.split('') ==> map { %rtoa{$_.uc} } ==> reduce { $^a+$^b +-$a%$b*2 } );
    but you still wind up with one paren after a brace. Or if you reversed the written order, so "everything to the right" is indeed the argument to the listop, I think this works:
    reduce {$^a+$^b-$a%$b*2 } map { %rtoa{$_.uc} } $x.split('');
    which makes me think that there is merit in doing it that way as originally presented. listops are naturally written with the processing sequence in the opposite order. Fighting it means adding parens, no matter how you try.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://771227]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (3)
As of 2017-09-20 06:31 GMT
Find Nodes?
    Voting Booth?
    During the recent solar eclipse, I:

    Results (233 votes). Check out past polls.