The premise
Your job at HappyCartoonFriendFinder.com has taken a turn for the worse. All of the venture capital has dried out, subscriptions are down, and the pop-up ad revenue isn't paying the bills anymore. In order to keep the lights on for one more month, your boss decides to make a testimonial page, where toons can present their happy stories of new-found love, all thanks to HappyCartoonFriendFinder.com.
After querying the database, you find you've got just 5 paying couples who met through HappyCartoonFriendFinder.com, and you've already stored their names in a hash :
%couples = (
Fred=>"Wilma",
Barney=>"Betty",
George=>"Jane",
Homer=>"Marge",
Peter=>"Lois"
);
Unfortunately, your company is so low on funding, that they can't pay for more than 80 characters of coding.
Not only that, somebody's stolen your remaining supply of newlines, slashes, backslashes and semi-colons, and
grabbed all but 2 doublequotes!
Your goal is to produce a small alphabetically listed snippet of text which will be passed onto an p2b end-to-end hyper-business server
for use in a larger HTML file, which should hopefully attract new subscribers.
this file should look like :
Barney is married to Betty
Fred is married to Wilma
George is married to Jane
...
and so on, for each of the couples.
The goal
print out the couple's information as formatted above to STDOUT. Do it in one line of code, using no more than 80
characters. You have only 2 '"' (doublequotes), and you can't use the characters ';', '\' or '/'.
You can assume a shebang line properly formatted for your system,a newline, the %couples hash as specified
above, and one final newline. This means that your solution should be 9 lines long.
Can you save HappyCartoonFriendFinder.com?
This is a relatively easy challenge, suitable for those who are starting to get comfortable with perl. If you say
"that's easy!" or have written one or more books on perl, consider skipping this node :)
The reference answer
#! perl -l
%couples = (
Fred=>"Wilma",
Barney=>"Betty",
George=>"Jane",
Homer=>"Marge",
Peter=>"Lois"
);
print foreach sort map {"$_ is married to $couples{$_}"} keys %couples
|
Update
the 2 entries below are close, but using "\n" disqualifies them. What options in perl could take the place of a newline? (or is this a trick?)
An annoyed saint notes : "in your perl puzzle you should note that people *can* adjust command-line options.. we've been resorting to slurping `cat $0` and doing substitutions to get it to work" and 'maybe say "You can assume a shebang line of your choice, ...'
Re: perl puzzle - cartoon couple registry (beginner, semi-golf)
by BlueBlazerRegular (Friar) on Jun 11, 2002 at 21:08 UTC
|
All right, I'll jump in. I'm not exactly a newbie, but I'm also not an 'expert' (fill in your own opinion on what an 'expert' is).
So without further ado, this is what I ended up with:
#!/usr/bin/perl -w
%couples = (
Fred=>"Wilma",
Barney=>"Betty",
George=>"Jane",
Homer=>"Marge",
Peter=>"Lois"
);
print "$_ is married to $couples{$_}\n" for (sort keys %couples);
Looking at just the important line, I started with:
foreach $key (sort keys %couples) {print "$key is married to $couples{
+$key}\n"};
Hmm, exactly 80 characters. But wait, I can use the default variable ('$_') rather than creating my own, so I'm now down to 71 characters.
foreach (sort keys %couples) {print "$_ is married to $couples{$_}\n"}
+;
Ahh, there's more. 'foreach' can be written as 'for' taking me done to 67 characters:
for (sort keys %couples) {print "$_ is married to $couples{$_}\n"};
Not quite - I can get rid of those pesky brackets by reversing the 'for' and 'print' statements, reducing it down to 65 characters:
print "$_ is married to $couples{$_}\n" for (sort keys %couples);
And that's as far as I've gotten. I've noticed that my solution got more 'perlish' (albeit not much) as I went along, so I was hoping that some of our more experienced monks would contribute as well - and notes as to how you got there are most welcome. Most Perl golf I see is from a realm I'm not familiar with, so a map to that wonderful place would be appreciated greatly.
Pat
P.S. Viewng my post in VIM with syntax checking on leads to some strange colored text...
| [reply] [d/l] [select] |
Re: perl puzzle - cartoon couple registry (beginner, semi-golf)
by mrbbking (Hermit) on Jun 11, 2002 at 23:57 UTC
|
My solution ended up nearly identical to BlueBlazerRegular's, but I dropped a bit of excess punctuation and whitespace, to come in with 21 chars to spare:
# 1 2 3 4 5 6
#23456789012345678901234567890123456789012345678901234567890
print"$_ is married to $couples{$_}\n"for sort keys%couples
Bonus (for me, anyhow): I played with map a bit, and found that it was actually longer that way.
# 1 2 3 4 5 6
#2345678901234567890123456789012345678901234567890123456789012
print map{"$_ is married to $couples{$_}\n"}sort keys%couples
Update: Whoops. I can get away with '\n' since it's not an actual 'newline', but may casual disregard of the "can't use a backslash" rule was just silly. I'm out! | [reply] [d/l] [select] |
|
Building off mrbbking, why don't we try and get rid of \n. After thinking and messing around bit, I ended up using $*: The multiline matching variable. I'd love to know *why* this works, and if it's compatible with *nix, as I used activestate.
Update: Tested on a FreeBSD shell, and it *does* work, as long as we run it with perl -l...
Please don't run this with warnings, as it won't work because $* is a deprecated special variable.
Here Goes:
Still 59 Letters
#! perl -l
%couples = (
Fred=>"Wilma",
Barney=>"Betty",
George=>"Jane",
Homer=>"Marge",
Peter=>"Lois"
);
print"$_ is married to $couples{$_}$*"for sort keys%couples
Another idea that may or may not have merit is to set %couples to a shorter word, and call that in the print. Something that would (logically) be *like*
print"$_ is married to $c{$_}$*"for sort keys(%c=%couples)
That code doesn't work, though, and would save you just one character.
Update 2: I found it strange that I was getting newlines, instead of 0 or 1 from $*, so I investigated. From perldoc perlrun: -l enables automatic line-ending processing. If octnum is omitted, sets $\ to the current value of $/. That means that there's no reason to use $*, as -l will give us $/, anyways.
You will then realize that the previous answers would be correct, if we got rid of \n, or in my case $* (-l chops the last letter off in addition, which meant that my $* which should have been evaluated as 0 or 1, was being chopped off and replaced by a newline ($/). Strage, but we don't even need to print newlines, with perl -l :)
That means: print"$_ is married to $couples{$_}"for sort keys%couples can replace the respective line in the previous solution(s)
Gyan Kapur
gyan.kapur@rhhllp.com | [reply] [d/l] [select] |
|
print"$_ is married to $a{$_}$*"for sort keys%{*a=*couples}
is the same whereas
print"$_ is married to $a{$_}$*"for sort keys*a=*couples
is no go and
print"$_ is married to $a{$_}$*"for sort keys%a=%couples
is just not right...
--
perl -pew "s/\b;([mnst])/'$1/g"
| [reply] [d/l] [select] |
Re: perl puzzle - cartoon couple registry (beginner, semi-golf)
by perigeeV (Hermit) on Jun 12, 2002 at 10:55 UTC
|
the 2 entries below are close, but using "\n" disqualifies them. What options in perl could take the place of a newline? (or is this a trick?)
print "$_ is married to $couples{$_}<br>" for(sort keys %couples)
You don't need a newline. You need a <br> tag. The output is going to an HTML file.
| [reply] [d/l] [select] |
|
| [reply] |
Re: perl puzzle - cartoon couple registry (beginner, semi-golf)
by Cybercosis (Monk) on Jun 12, 2002 at 08:05 UTC
|
well, here's something that qualifies (it's only a slight improvement over previous answers for better rules-conformity.
weighing in at 67 chars:
print"$_ is married to $couples{$_}",chr 0x0a for sort keys%couples
just tr/0x0a/0x0d/ if your system uses that for newline. and, at 76 chars (ever so short of the limit...), the same code with microsoft newline:
print"$_ is married to $couples{$_}",chr 0x0d, chr 0x0a for sort keys%couples
~Cybercosis | [reply] [d/l] [select] |
|
Unless you have done binmode STDOUT, you can print "\n" and it will print the appropriate newline for your system, including those with a two character newline (CP/M and DOS use "\x0D\x0A").
Also, why use chr 0x0a instead of the shorter chr 10?
| [reply] [d/l] [select] |
Re: perl puzzle - cartoon couple registry (beginner, semi-golf)
by mothra (Hermit) on Jun 12, 2002 at 14:08 UTC
|
Either:
map{print"$_ is married to $couples{$_}".chr 10}sort keys%couples}
or:
map{print"$_ is married to $couples{$_}<br>"}sort keys%couples}
The latter, of course, only newlines in HTML.
Update: print"$_ is married to $couples{$_}<br>"for sort keys%couples :) | [reply] [d/l] [select] |
Re: perl puzzle - cartoon couple registry (beginner, semi-golf)
by Abigail-II (Bishop) on Jun 12, 2002 at 14:40 UTC
|
Without using any slashes, backslashes, semi-colons, double
quotes, command line options, and using 72 characters:
map{print qq{$_ is married to $couples{$_}@{[chr 10]}}}sort keys%coupl
+es
Abigail | [reply] [d/l] |
|
My approch was similar.
Without using any slashes, backslashes, semi-colons, command line options, only two double quotes, and using 64 characters:
printf"$_ is married to $couples{$_}%c",10 for sort keys%couples
Changing the double-quotes into qq{} makes it 67 characters.
Of course, mine fails if anyone has a % in their name. In real Golf, it is the sort of thing they would update the test script to catch.
The most evil newline variant I considered was:
$:=~m{.(.)}s and print "something$1"
| [reply] [d/l] [select] |
Re: perl puzzle - cartoon couple registry (beginner, semi-golf)
by danger (Priest) on Jun 13, 2002 at 04:19 UTC
|
#!/usr/bin/perl
%couples = (
Fred=>"Wilma",
Barney=>"Betty",
George=>"Jane",
Homer=>"Marge",
Peter=>"Lois"
);
print`perl -lne'tr! ",!!d and s!=>(?=[A-Z])! is married to ! and print
+' $0|sort`
I mean, if we don't use our budget of 80 characters this time around,
they'll just budget 70 characters for us next time! (and I'm hiding
my spare double quote for an emergency, so don't ask me if you used
up both of yours).
| [reply] [d/l] |
Re: perl puzzle - cartoon couple registry (beginner, semi-golf)
by Aristotle (Chancellor) on Jun 13, 2002 at 02:46 UTC
|
And now, for something entirely different.
# 1 2 3 4 5 6
#234567890123456789012345678901234567890123456789012345678901234
{(@c=each%couples)&&printf("%s is married to %s%c",@c,10)&&redo}
Pity I've been beaten. :-)
# Update: trickier, same char. count
{(@c=each%couples)?printf("%s is married to %s%c",@c,10)&redo:1}
____________ Makeshifts last the longest. | [reply] [d/l] [select] |
Re: perl puzzle - cartoon couple registry (beginner, semi-golf)
by gumby (Scribe) on Jun 12, 2002 at 19:44 UTC
|
$c=[{Fred=>1,
Barney=>2,
George=>3,
Homer=>4,
Peter=>5}
"Wilma",
"Betty",
"Jane",
"Marge",
"Lois"
];
while(my($h,$w)=each %$c){print"$h is married to $w\n";}
I have noticed that this is an extremely braindead post. D'oh! | [reply] [d/l] |
|
#!/usr/bin/perl -w -l
%couples = (
Fred=>"Wilma",
Barney=>"Betty",
George=>"Jane",
Homer=>"Marge",
Peter=>"Lois"
);
print"$h is married to $w"while(($h,$w)=each%couples)
| [reply] [d/l] |
Re: perl puzzle - cartoon couple registry (beginner, semi-golf)
by Pug (Monk) on Jun 12, 2002 at 23:45 UTC
|
I have been on a map kick recently so...
using 2 " and no ; / \ or enter keys
#!/usr/bin/perl -l
%couples = (
Fred=>"Wilma",
Barney=>"Betty",
George=>"Jane",
Homer=>"Marge",
Pter=>"Lous"
);
map print, map "$_ is married to $couples{$_}",sort keys%couples
It weights in at 63 characters.
I was reading the above posts and I was able to get this
%c=%couples,map print,map "$_ is married to $c{$_}",sort keys%c
Which is 62 characters.
Update.
Thanks for the getting rid of the extra map belg4mit.
I don't know what I was thinking *grin*
In a semi related note I used this when someone wanted to
a print out of the @INC.
--
Mortic | [reply] [d/l] [select] |
|
map print("$_ is married to $couples{$_}"),sort keys%couples
60 char, who needs a semi-colon? map map is inefficient and
in this case wasteful.
--
perl -pew "s/\b;([mnst])/'$1/g"
| [reply] [d/l] |
Re: perl puzzle - cartoon couple registry (TMTOWTDI)
by jynx (Priest) on Jun 13, 2002 at 01:32 UTC
|
Since i can't think of a good way to golf this well, i'll bend the rules slightly. Here's a solution that you place before the couples declaration. It uses command line options, two quotes, and weighs in at 58 chars. Slightly amusing...
#!/usr/bin/perl -l
#23456789_123456789_123456789_123456789_123456789_123456789_
sub _{print shift()." is married to ".shift while@_}_ sort
%couples = (
Fred=>"Wilma",
Barney=>"Betty",
George=>"Jane",
Homer=>"Marge",
Peter=>"Lois"
);
jynx
Update: Ah, err, uh, whoops... LOL! This is a non-working solution. It's really amusing who's married to whom in it though! Sorry about that, apparently my eyesight is going (i thought it looked fine until i retested a couple minutes ago) -- it must be time to go home... | [reply] [d/l] |
|
|