Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

12 days of Perl?

by johnaj (Sexton)
on Apr 30, 2021 at 02:03 UTC ( [id://11131906]=poem: print w/replies, xml ) Need Help??

I've been working on an exercise to generate the English "Twelve days of Christmas song". So far, I've come up with the following:

for(<DATA>){s/%/ing/;$_=($i++?$i-1+print" ":a)." $_";print"On the $i",(st,nd,rd)[$i-1]||th," day of Christmas, my true love gave to me: ",$t=$_.$t}__DATA__ partridge in a pear tree. turtle doves and French hens, call% birds, golden rings, geese a-lay%, swans a-swimm%, maids a-milk%, ladies danc%, lords a-leap%, pipers pip%, drummers drumm%,

That generates the following text:

On the 1st day of Christmas, my true love gave to me: a partridge in a pear tree. On the 2nd day of Christmas, my true love gave to me: 2 turtle doves and a partridge in a pear tree. On the 3rd day of Christmas, my true love gave to me: 3 French hens, 2 turtle doves and a partridge in a pear tree. On the 4th day of Christmas, my true love gave to me: 4 calling birds, 3 French hens, 2 turtle doves and a partridge in a pear tree. On the 5th day of Christmas, my true love gave to me: 5 golden rings, 4 calling birds, 3 French hens, 2 turtle doves and a partridge in a pear tree. On the 6th day of Christmas, my true love gave to me: 6 geese a-laying, 5 golden rings, 4 calling birds, 3 French hens, 2 turtle doves and a partridge in a pear tree. On the 7th day of Christmas, my true love gave to me: 7 swans a-swimming, 6 geese a-laying, 5 golden rings, 4 calling birds, 3 French hens, 2 turtle doves and a partridge in a pear tree. On the 8th day of Christmas, my true love gave to me: 8 maids a-milking, 7 swans a-swimming, 6 geese a-laying, 5 golden rings, 4 calling birds, 3 French hens, 2 turtle doves and a partridge in a pear tree. On the 9th day of Christmas, my true love gave to me: 9 ladies dancing, 8 maids a-milking, 7 swans a-swimming, 6 geese a-laying, 5 golden rings, 4 calling birds, 3 French hens, 2 turtle doves and a partridge in a pear tree. On the 10th day of Christmas, my true love gave to me: 10 lords a-leaping, 9 ladies dancing, 8 maids a-milking, 7 swans a-swimming, 6 geese a-laying, 5 golden rings, 4 calling birds, 3 French hens, 2 turtle doves and a partridge in a pear tree. On the 11th day of Christmas, my true love gave to me: 11 pipers piping, 10 lords a-leaping, 9 ladies dancing, 8 maids a-milking, 7 swans a-swimming, 6 geese a-laying, 5 golden rings, 4 calling birds, 3 French hens, 2 turtle doves and a partridge in a pear tree. On the 12th day of Christmas, my true love gave to me: 12 drummers drumming, 11 pipers piping, 10 lords a-leaping, 9 ladies dancing, 8 maids a-milking, 7 swans a-swimming, 6 geese a-laying, 5 golden rings, 4 calling birds, 3 French hens, 2 turtle doves and a partridge in a pear tree.

My script is 343 bytes, which is better than zip and tar+gzip but worse than gzip:

-rw-r--r-- 1 john john 294 May 1 13:29 12days.gz -rw-r--r-- 1 john john 343 Apr 30 04:00 12days.pl -rw-r--r-- 1 john john 370 May 1 13:30 12days.tar.gz -rw-r--r-- 1 john john 2169 May 1 13:29 12days.txt -rw-r--r-- 1 john john 439 May 1 13:30 12days.zip

Does anybody have a shorter solution? For simplicity's sake, I've limited the challenge to digits rather than written numbers.

Replies are listed 'Best First'.
Re: 12 days of Perl?
by choroba (Cardinal) on Apr 30, 2021 at 18:31 UTC
    s/%/ing,/
    gives 339.

    Update 335:

    s/%/ing,/,$_=($i++?$i-1+print" ":a)." $_",print"On the $i",(st,nd,rd)[$i-1]||th," day of Christmas, my true love gave to me: ",$@=$_.$@for split/^/,<<'' partridge in a pear tree. turtle doves and French hens, calling birds, golden rings, geese a-lay% swans a-swimm% maids a-milk% ladies danc% lords a-leap% pipers pip% drummers drumm%
    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]

      Wow, that's a clever usage of $@!

      why the heredoc, is there an older version of perl that must be supported where simple strings could not be multiline?

      this is 333, works on 5.32 atleast:

Re: 12 days of Perl?
by choroba (Cardinal) on Apr 30, 2021 at 09:16 UTC
    If you are also interested in canonical and idiomatic solutions (that probably won't be shorter but might give you some ideas how to approach the problem differently), check Exercism.io.

    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
Re: 12 days of Perl?
by eyepopslikeamosquito (Archbishop) on May 01, 2021 at 10:36 UTC

      Neat, thanks for the links. I made a Google search before posting and found only the first Perl Monks node. I was also surprised this challenge wasn't more popular. I was actually inspired by a post on the /r/prolog subreddit, where such challenges are regularly posted.

      P.S. That code.golf page sure is hard to navigate – can you actually see people's solutions on there?

        That code.golf page sure is hard to navigate – can you actually see people's solutions on there?
        No! If you could, there would be no competition. :) Unfortunately, the original code golf competition web site in Perl, Python, Ruby and PHP is now gone from the web forever and they never published any solutions ... though you can see some of them in my PM code golf nodes (especially the six part series "The golf course looks great ...").

        You can see the (handful) of published solutions for the 12 days of christmas game at the shinh golf link ... no surprise to see the leading one there starting with:

        use Compress::Zlib;print uncompress 'x\xda\xe5 ...
        Note that this solution would not have been accepted at the original code golf competition web site because modules were not allowed in those competitions - though you could use compression via the pack function as described in excruciating detail at Compression in Golf: Part I.

        The tricky problem of how long to keep the competitor's solutions a secret is touched upon in The golf course looks great, my swing feels good, I like my chances (Part IV) in the "No Time Limit" and "Golfer Burn Out" sections ... and also (update) in Re^2: The golf course looks great, my swing feels good, I like my chances (Part I).

        In our early golf games, run on the fwp and golf perl mailing lists, the solutions were kept secret for one week - see Dueling Flamingos: The Story of the Fonality Christmas Golf Challenge for an example of a classic one week Perl code golf competition (with cash prizes!) from the good old days.

Re: 12 days of Perl?
by jdporter (Paladin) on Apr 30, 2021 at 15:49 UTC

      Oh, yes, you're right! That saves another two characters.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: poem [id://11131906]
Approved by kcott
Front-paged by Discipulus
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (5)
As of 2024-04-19 15:26 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found