Welcome to the Monastery PerlMonks

### comment on

 Need Help??

To do well at Perl golf, perhaps the most important thing is to unearth the "fundamental insights" into the problem. Some of the fundamental insights of this golf were:

• Rather than calculating a running total, it's shorter and simpler to convert \$_ in place; for example, transform II plus III into 2 + 3. With that done, simply use eval to compute the total.
• The y/IVXLC/XLCDM/ transliteration is a short and sneaky way to multiply by ten.
• You don't need to write two converters: it is sufficient to write an arabic_to_roman() converter. To convert the other way, simply convert 1..3999 into a table or something and do a lookup. I didn't appreciate this at first and foolishly wrote two converters. When I became aware of my blunderific overlook, my score dropped by 40 strokes.
• The shortest way to lookup the number corresponding to a roman numeral is to create a symbolic reference for each roman numeral whose value is the corresponding arabic number. For more fun, a la ton and others, transform, for example, II plus III into \$II  +\$  III and eval that. This is the insight I missed, only trying a hash and a grep lookup.
• You can further eliminate the array of roman numerals by creating a second set of symbolic references mapping negative numbers to roman numerals. Note that for this to work you must use negative numbers, since positive ones (e.g. \$3) are read-only variables used by perl's regex engine. As you might expect, not many of the contestants hit upon this final insight, only ton, Juho, and jojo managing it.
Notice that none of these insights depends on knowing Ton's magic formula. Golfers like Ton have a knack for finding these insights quickly and easily, while I struggle; once I find them, it is a simple matter of golfing technique to whittle down the solution. For me, the hard part is to find them. Using the above insights, a simple solution like this:
```#!perl -pl
map{\$_.=(!y/IVXLC/XLCDM/,I,II,III,IV,V,VI,VII,VIII,IX)[\$&]while s/\d//
+;\$\$_=\$n++}@R=0..3999;
y/mp/-+/;s/\w+/\${\$&}/g;\$_=\$R[eval]
comes in at around 130. You could get down to around 120, again without knowing Ton's magic formula, by whittling the arabic-to-roman converter:
```#!perl -pl
map{y/IVXLC/XLCDM//s//\$&-9?\$&-4?I x\$&:IV:IX/e&s/I{5}/V/while/\d/;\$\$_=\$
+n++}@R=0..3999;
y/m/-/;s/\w+/+\${\$&}/g;\$_=\$R[eval]
To go lower, you'll need to sneak in y/iul-}/-\$+ / somewhere to transform \$_ directly into symrefs (e.g. \$II  +\$  III) that can be directly eval'ed. Doing that allows you to eliminate the s/\w+/\${\$&}/g above. Still further savings are available by replacing the @R array above with a second set of symbolic references, this time mapping negative numbers back to roman numerals.

While I don't fully understand your shortest 186 solution:

```#!perl -pla
%n=I1V5X10L50C100D500M1000=~/(.)(\d+)/g;sub
d{\$#_-=\$z*2*(@_&&\$z<\$_)-(\$z=\$_)for@n{/./g};@_}\$t+=(\$.=/p/-/n/||\$.)*d
for@F;map{\$s.=\$_ x(\$t/d),\$t%=d}M,CM,D,CD,C,XC,L,XL,X,IX,V,IV,I;\$_=\$s
it seems like sour grapes to claim that:
this contest was effectively written for a few people who were in the know, who had seen your magic algorithm, shutting out the rest of us.
As shown above, without knowing Ton's magic algorithm, you could have easily trimmed 60 strokes off your solution by unearthing the fundamental insights into the problem.

Update: oops, changed 4e3 to 3999 (4e3 fails test case "MD plus I") plus minor code improvements. Added extra symbolic reference insight.

In reply to Re^3: Perl Golf Ethics by eyepopslikeamosquito
in thread Perl Golf Ethics by Anonymous Monk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

• Are you posting in the right place? Check out Where do I post X? to know for sure.
• Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
• Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
• Want more info? How to link or or How to display code and escape characters are good places to start.

Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (7)
As of 2022-08-11 07:28 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?

No recent polls found

Notices?