There Was an Old Lady

23

3

Your goal is to write a program that prints the following poem exactly as it appears here:

There was an old lady who swallowed a fly.
I don't know why she swallowed that fly,
Perhaps she'll die.

There was an old lady who swallowed a spider,
That wriggled and iggled and jiggled inside her.
She swallowed the spider to catch the fly,
I don't know why she swallowed that fly,
Perhaps she'll die.

There was an old lady who swallowed a bird,
How absurd to swallow a bird.
She swallowed the bird to catch the spider,
She swallowed the spider to catch the fly,
I don't know why she swallowed that fly,
Perhaps she'll die.

There was an old lady who swallowed a cat,
Imagine that to swallow a cat.
She swallowed the cat to catch the bird,
She swallowed the bird to catch the spider,
She swallowed the spider to catch the fly,
I don't know why she swallowed that fly,
Perhaps she'll die.

There was an old lady who swallowed a dog,
What a hog to swallow a dog.
She swallowed the dog to catch the cat,
She swallowed the cat to catch the bird,
She swallowed the bird to catch the spider,
She swallowed the spider to catch the fly,
I don't know why she swallowed that fly,
Perhaps she'll die.

There was an old lady who swallowed a horse,
She died of course.

The text must appear exactly as it does here, and fewest characters wins.

Edit: Your program may not access the internet.

Ethan Roseman

Posted 2011-09-18T18:25:54.403

Reputation: 347

2Counted in UTF-8 encoded bytes? – J B – 2011-09-18T18:39:53.927

The golf clearly says "fewest characters", not bytes. Encode it how you want as long as it is still a valid program. – Thomas Eding – 2011-09-19T20:07:57.753

1For reference, the poem is 1208 characters long. – J B – 2011-09-21T08:50:44.740

Answers

16

Perl 5.10, 392 384 372 235 369 (ASCII) / 234 (Unicode)

The shortest ASCII version of this is 369 characters long:

@_=(fly,spider,bird,cat,dog);$_="There was an old lady who!ed a";for$P("",",
That wrJand Jand jJinside her",",
How absurd&",",
Imagine that&",",
What a hog&"){$p=$c;$c=$".shift@_;$t=$p?"She!ed the$c to catch the$p,
$t":"I don't know why she!ed that$c,
Perhaps she'll die.

$_";$_.="$c$P.
$t";s/&/ to! a$c/}s/!/ swallow/g;s/J/iggled /g;say"$_ horse,
She died of course."

It started from this base program:

my @animals = qw(fly spider bird cat dog);
my $buf = "There was an old lady who swallowed a ";
for my $phrase ( "",
                 ",\nThat wriggled and iggled and jiggled inside her",
                 ",\nHow absurd&",
                 ",\nImagine that&",
                 ",\nWhat a hog&" ) { 
  $previous = $current;
  $current = shift @animals;
  $trail = $previous ? "She swallowed the $current to catch the $previous,\n$trail"
                     : "I don't know why she swallowed that $current,\n"
                       . "Perhaps she'll die.\n\n$buf";
  $buf .= "$current$phrase.\n$trail";
  $buf =~ s/&/ to swallow a $current/;
}
say "$buf horse,\nShe died of course.";

The core idea is to keep the end of the rhyme and the beginning of the next one in $trail, augmenting it as we go along. It's made non-trivial by the need of a special case for the first use, and the attempt to re-use the animal name variable even in the animal-specific phrase. Further optimizations include:

  • one-character identifiers for everything
  • using barewords instead of quoted strings for the animal list
  • use of the accumulator $_ for $buf to shorten most substitution operations even more (use of @_ is by force of habit and doesn't win anything more than any other character)
  • including the preceding space directly inside the animal name variable (the space character taken from the $" variable)
  • regexp substitution to shorten the most common phrases: ' swallow' and 'iggled '
  • no code spacing whatsoever and all \n in string literals replaced with actual newlines

All but the last optimization yield this:

@_ = (fly, spider, bird, cat, dog);
$_ = "There was an old lady who!ed a";
for $P ( "",
         ",\nThat wrJand Jand jJinside her",
         ",\nHow absurd&",
         ",\nImagine that&",
         ",\nWhat a hog&" ) { 
  $p = $c;
  $c = $" . shift @_;
  $t = $p ? "She!ed the$c to catch the$p,\n$t"
          : "I don't know why she!ed that$c,\nPerhaps she'll die.\n\n$_";
  $_ .= "$c$P.\n$t";
  s/&/ to! a$c/;
}
s/!/ swallow/g;
s/J/iggled /g;
say "$_ horse,\nShe died of course.";

Additionally, this golf is a victim of the underspecified encoding problem. As it—as of now—counts individual characters instead of bytes in a specified encoding, there's a big gain to be achieved by decoding the program source from UCS2 before starting. The final result isn't very readable anymore, but it's short all right. (234 characters, counted as a difference from perl -E'' as usual) (I had to include the trailing newline back to make it valid UCS2)

$ perl -MEncode=from_to -e'$_="䁟㴨晬礬獰楤敲Ɫ楲搬捡琬摯朩㬤弽≔桥牥⁷慳⁡渠潬搠污摹⁷桯Ⅵ搠愢㭦潲⑐⠢∬∬੔桡琠睲䩡湤⁊慮搠橊楮獩摥⁨敲∬∬ੈ潷⁡扳畲搦∬∬੉浡杩湥⁴桡琦∬∬੗桡琠愠桯朦∩笤瀽④㬤挽␢⹳桩晴䁟㬤琽⑰㼢卨攡敤⁴桥④⁴漠捡瑣栠瑨攤瀬ਤ琢㨢䤠摯渧琠歮潷⁷桹⁳桥Ⅵ搠瑨慴④Ⰺ健牨慰猠獨攧汬⁤楥⸊ਤ弢㬤弮㴢④⑐⸊⑴∻猯☯⁴漡⁡④⽽猯ℯ⁳睡汬潷⽧㭳⽊⽩杧汥搠⽧㭳慹∤张桯牳攬੓桥⁤楥搠潦⁣潵牳攮∊";from_to($_,utf8,ucs2);eval'

A good thing there was a lot to golf from before resorting to Unicode, or it wouldn't be much fun.

Edit: can't find a way to copy/paste the 234-character version to this browser, so I'm leaving the 235-character one. Will fix this evening, when I get my hands on a real UTF8-aware clipboard. found a way. Quasi-proof on ideone.

J B

Posted 2011-09-18T18:25:54.403

Reputation: 9 638

5@JoeyAdams really? I didn't even notice the packed version until I read your comment – Cyoce – 2017-01-06T21:55:13.180

2I revoked my upvote. The unicode packing trick is getting old. – Joey Adams – 2011-09-20T15:17:30.567

2The non-packed version is still in, you know ;p – J B – 2011-09-20T16:27:14.213

8

Perl, 120 94 chars

Count includes call to the interpreter.

You did say to reproduce it exactly as it does here ;)

perl -MLWP::Simple -E'($p=get("http://goo.gl/kg17j"))=~s#^.+?pr.*?de>|</co.*?re>.+$##sg;say$p'

N.B.

This solution is what prompted the 'no-Internet' restriction. Let it be a lesson for future code-golf question specifications :)

Zaid

Posted 2011-09-18T18:25:54.403

Reputation: 1 015

The hilarious thing about this post is that it reads the required output text from this page. I changed my downvote to an upvote. – Joey Adams – 2017-01-22T17:10:13.730

3This entry turned into a quine the moment I posted it! A little regex manipulation restored service back to normal... – Zaid – 2011-09-18T20:05:40.183

Clever, but a little too easy... :P I should have clarified on my rules. – Ethan Roseman – 2011-09-18T20:25:29.920

Quotation marks around address should be double. Very good way to solve it :-) – Ante – 2011-09-18T21:57:47.330

2Rotten way to solve it, because it relies on the existence of an outside resource. I'd count the length of the question against it same as I would a program that read the poem from a file. – dmckee --- ex-moderator kitten – 2011-09-19T00:32:14.920

2Outside resources are not problem, since it is quite questionable what is resource and what is environment at all. I like exploit of gap in not strictly defined initial question. This is not a solution, but good example to take a care asking questions :-) – Ante – 2011-09-19T09:14:06.417

3It may be a rotten way to solve it, but it relies on an outside resource that's exactly as liable to exist as the question it answers. Which makes it perfectly acceptable as an answer to said question, IMO. – J B – 2011-09-19T13:09:57.747

2@trinithis : The 'no-Internet' restriction was imposed after my post. Admittedly, this is not a serious attempt at coding a solution, but it met the specifications at the time of posting it. Oh, and LWP::Simple is part of the Perl core, at least on v5.12.3. – Zaid – 2011-09-20T03:17:17.377

I didnt intend to imply it wasn't. I was just continuing my rant about crap like it in code golf in general. – Thomas Eding – 2011-09-20T07:08:45.457

I'd need to amend my comment to say that the answer only stays valid as long as it remains on the first page of answers. It's still the case for the time being, but who knows... – J B – 2011-09-22T09:30:08.407

Use a URL Shortener. – st0le – 2011-09-22T09:42:40.437

@st0le : Implemented your good suggestion. – Zaid – 2011-09-22T17:08:33.753

3

Vim, 373 keystrokes

iThere was an old lady who swallowed a fly.
I don't know why she s<C-n> that f<C-n>,
Perhaps she'll die.

T<C-x><C-l><Left><C-w>spider<Esc>oThat wriggled <Esc>6hiand <Esc>3hy$u$ppbij<End>inside her.
She s<C-n> the sp<C-n> to catch the f<C-n>,
I<C-x><C-l><C-x><C-l><Esc>qqyapGp3jYPkk$Bqcwbird<Esc>+CHow absurd to sw<C-n><Backspace><Backspace> a b<C-n>.<Esc>qwyb5wvep$Bvepq@qcwcat<Esc>+CImagine that to sw<C-p> a cat.<Esc>@w@qcwdog<Esc>+CWhat a hog to sw<C-p> a dog.<Esc>@w@qcwhorse<Esc>+cGShe d<C-p>d of course.

Funny how exponential that scrambling is.

BlackCap

Posted 2011-09-18T18:25:54.403

Reputation: 3 576

3

C (gcc), 429 424 bytes

-5 bytes thanks to ceilingcat

*w[]={"384fly<1","I don't know why she5ed that fly<Perhaps she'll die.772","There was an old lady who5ed a ","She5ed the "," to catch the "," swallow"," to5 a ","\n","spider","bird","cat","iggled ",",7","3948<0"};U(char*s){for(;*s;s++)*s>47&*s<65?U(w[*s-48]):putchar(*s);}f(){U("2fly.718<That wr;and ;and j;inside her.709<How absurd69.7=:<Imagine that6:.73:49<=dog<What a hog6dog.73dog4:<3:49<=horse<She died of course.7");}

Try it online!

gastropner

Posted 2011-09-18T18:25:54.403

Reputation: 3 264

3

Python 3.x: 407 chars

import base64,zlib;print(zlib.decompress(base64.b64decode(b'eNrlkLFOxDAQRPt8xXTXoHwHdEhEot7L+myD8Z7snKz8Pd6LT7mgFFQIRGftPs/OzOBMMiiUQRESGIF4RnGCXCgEKYZBOIW5B7onsMTDhPcopTIzsjN33ORoUvShos8mOTpnJQ4hgL3pu2741rF89mySigwqWJK3NugmMu6eb+3tY648qrRafPniyDQ5TIKRptFdZ83kz+Q5+sQq8ViP0DFfEquZRrT9vnXdbI2v3fzCoPXs9dgHWR/NorpJWoH9oONCrr5vnf35TlisKryqGsGJ3TZS1/uN8EKurlu5/6k7Jymbm7f6kSEnjHKp0/4TSSOZgA==')).decode('utf8'))

dan04

Posted 2011-09-18T18:25:54.403

Reputation: 6 319

Creative way to compress this. – juniorRubyist – 2017-06-25T23:31:46.123

3You can get it down to 391 chars by doing something like:

import zlib;print zlib.decompress("""eJzlkLFOxDAQRPt8xXTXoHwHdEhEot7L+myD8Z7snKz8Pd6LT7mgFFQIRGftPs/OzOBMMiiUQRES GIF4RnGCXCgEKYZBOIW5B7onsMTDhPcopTIzsjN33ORoUvShos8mOTpnJQ4hgL3pu2741rF89myS igwqWJK3NugmMu6eb+3tY648qrRafPniyDQ5TIKRptFdZ83kz+Q5+sQq8ViP0DFfEquZRrT9vnXd bI2v3fzCoPXs9dgHWR/NorpJWoH9oONCrr5vnf35TlisKryqGsGJ3TZS1/uN8EKurlu5/6k7Jymb m7f6kSEnjHKp0/4TSSOZgA==""".decode('base64')) – ESultanik – 2011-09-21T15:40:06.407

3

JavaScript (422)

Works in the SpiderMonkey interpreter versions used by both anarchy golf and ideone.

for(a="fly0spider0bird0cat0dog0horse0How absurd0Imagine that0What a hog".split(i=0);p=print;p("I don't know why she swallowed that fly,\nPerhaps she'll die.\n")){p("There was an old lady who swallowed a",a[i]+(i?",":"."));i>4&&quit(p("She died of course."));i&&p(i>1?a[4+i]+" to swallow a "+a[i]+".":"That wriggled and iggled and jiggled inside her.");for(j=i++;j;)p("She swallowed the "+a[j]+" to catch the "+a[--j]+",")}

A bit more nicely formatted:

for (a = "fly0spider0bird0cat0dog0horse0How absurd0Imagine that0What a hog".split(i = 0);
p = print; p("I don't know why she swallowed that fly,\nPerhaps she'll die.\n")) {
    p("There was an old lady who swallowed a", a[i] + (i ? "," : "."));
    i > 4 && quit(p("She died of course."));
    i && p(i > 1
        ? a[4 + i] + " to swallow a " + a[i] + "."
        : "That wriggled and iggled and jiggled inside her."
    );
    for (j = i++; j;) p("She swallowed the " + a[j] + " to catch the " + a[--j] + ",");
}

PleaseStand

Posted 2011-09-18T18:25:54.403

Reputation: 5 369

Clever use of the splitting by 0 trick to initialize i to 0 in only 2 bytes. Have a +1 – Cyoce – 2017-01-06T23:32:53.750

2

ink, 370 369 354 bytes

LIST B=fly,spider,bird,cat,dog,horse
VAR s=" swallow"
-(i)~B=B(i)
There was an old lady who{s}ed a {B}{.|,}
{|That wriggled and iggled and jiggled inside her|How absurd|Imagine that|What a hog|She died of course.->END}{|.| to{s} a {B}.}
-(k)~B--
{B:
She{s}ed the {B+1} to catch the {B},
->k
}I don't know why she{s}ed that fly,
Perhaps she'll die.
\ 
->i

Try it online!

Explanation

LIST B=fly,spider,bird,cat,dog,horse           // Ink's "LIST"s aren't much like lists - they're more like enums. Here we create a list type stating what animals exist, and make a set containing none of them.
VAR s=" swallow "                              // Pretty self-explanatory
-(i)~B=B(i)                                    // The i label keeps track of how many times we've visited it. We set B (the set) to be equal to the i-th item in B (the list type).
There was an old lady who{s}ed a {B}{.|,}      // Print the first line. {.|,} is a sequence - it's a period the first time it's encountered, and a comma every subsequent time.
                                               // Sequences can have more than one item in them, which is how we print the second line. When we get to the horse one, we terminate the program right away.
{|That wriggled and iggled and jiggled inside her|How absurd|Imagine that|What a hog|She died of course.->END}{|.|to{s} a {B}}.}
-(k)~B--                                       // Step back through the list type.
{B:                                            // A conditional - we execure the next two lines if B is non-empty.
She{s}ed the {B+1} to catch the {B},           // Print the "she swallowed the..." line
->k                                            // And repeat
}I don't know why she{s}ed that fly,           // Only reached when the conditional fails.
Perhaps she'll die.
\                                              // A backslash and a space to force an empty line.
->i                                            // Back to the top

Sara J

Posted 2011-09-18T18:25:54.403

Reputation: 2 576

2

Ruby, 436 characters

w=" swallowed "
f="There was an old lady who#{w}a "
c=" to swallow a %s"
b="dog","cat","bird","spider","fly"
s=nil,"That wriggled and iggled and jiggled inside her","How absurd"+c,"Imagine that"+c,"What a hog"+c
a=[]
5.times{k=g=b.pop;t,*s=s
puts f+k+(t ??,:?.),t&&[t%k+?.,a.map{|x|y,k=k,x;"She#{w}the #{y} to catch the #{k},"}],"I don't know why she#{w}that fly,","Perhaps she'll die.",""
a=[g]+a}
puts f+"horse,","She died of course."

Howard

Posted 2011-09-18T18:25:54.403

Reputation: 23 109

2

Scala (706 619 599 550 chars)

val L=Seq("fly","spider","bird","cat","dog")
val M="\nThere was an old lady who %sed a %s,"
type S=String
def s(l:S,a:S="",b:S="")=l.format("swallow",a,b)
def p(l:S,a:S=""){println(s(l,a))}
var i=0
var r=List[S]()
L.map{a=>{p(M,a)
if(i>0){p(Seq("","That wriggled and iggled and jiggled inside her.","How absurd","Imagine that","What a hog")(i)+(if(i>1)" to %s a %s."else""),a)
r::=s("She %sed the %s to catch the %s,",L(i),L(i-1))
r.map(p(_))}
p("I don't know why she %sed that fly,\nPerhaps she'll die.")
i+=1}}
p(M,"horse")
p("She died of course.")

Using map instead of foreach allows to squeeze more chars... In codegolf, we don't care about performance, elegance (non-mutability) or logic...

PhiLho

Posted 2011-09-18T18:25:54.403

Reputation: 653

1

tcl, 451 bytes

lassign {\ swallowed fly, spider " to catch the " bird cat iggled " to swallow a"} W f s c b a i w
puts "[set t "There was an old lady who$W a "]fly.
[set I "I don't know why she$W that $f
Perhaps she'll die.

"]$t$s,
That wr$i and $i and j$i inside her.
[set S "She$W the "]$s$c$f
$I$t$b,
How absurd$w $b.[set v \n$S$b$c$s,\n$S$s$c$f\n$I]$t$a,
Imagine that$w $a.
[set X $S$a$c$b,$v$t]dog,
What a hog$w dog.
${S}dog$c$a,
$X\horse,
She died of course."

Available to run on: http://rextester.com/live/GXF89639 (10th attempt)

sergiol

Posted 2011-09-18T18:25:54.403

Reputation: 3 055

1

PHP, 344 bytes

<?=gzinflate(base64_decode("5VAxTsQwEOz9iu2uifIO6JA4iXovu2cbjPdk+2Tl96zjoLugFFQIRGfNjGdn5ug4MVTMgBEkEASkGaoTyBVDkMoECOcwj+YRSOKhwFuUqooZsuM7VXFYmnAwT5wcXnLjDyEAeR6NOX7rUL544jSoWs1q8taGhkeCu+fr+vYxqxrUeDTPX7LwagVFYMIyuQVb4v1Ej5NPNJgHPYCnfE3UYqz8yu5Fbvg28Ocev6yentRD72h95O646af0Xr2p6255+0p/eAcSO5iX5oTgxG5XUHJvBeq6W9plzP+wlpOUuafSbwRyhkmuio0f"));

Try it online!

PHP, 405 bytes

<?=strtr("0fly.
106That wr8and 8and j8inside her.
23107,
How absurd57.
274623109,
Imagine that59.
2947,
27462310dog,
What a hog5dog.
2dog49,
2947,
27462310horse,
She died of course.",["There was an old lady who swallowed a ","I don't know why she swallowed that fly,
Perhaps she'll die.

","She swallowed the ","spider to catch the fly,
"," to catch the "," to swallow a ","spider,
",bird,"iggled ",cat]);

Try it online!

Jörg Hülsermann

Posted 2011-09-18T18:25:54.403

Reputation: 13 026

1

Bubblegum, 255 bytes

0000000: e0 04 85 00   f7 5d 00 2a   1a 08 a7 55   8e 22 31 d2 │ à...÷].*..§U."1Ò
0000010: cb f7 30 fa   52 4d 88 81   61 e4 be 9d   c2 f0 0e f8 │ Ë÷0úRM..aä¾.Âð.ø
0000020: dc c9 de 24   63 c9 1f c7   f7 71 e4 ed   40 68 0e d2 │ ÜÉÞ$cÉ.Ç÷qäí@h.Ò
0000030: cd 76 d8 d9   0d 61 78 f7   40 cf 23 95   48 e9 be 27 │ ÍvØÙ.ax÷@Ï#.Hé¾'
0000040: aa 75 57 ff   51 9e 1f 1f   25 d8 93 4d   18 69 c9 01 │ ªuWÿQ...%Ø.M.iÉ.
0000050: 12 16 ec c1   ff e0 01 7e   fa ea 1e cc   84 d7 58 b8 │ ..ìÁÿà.~úê.Ì.×X¸
0000060: 47 d4 40 b4   ff c7 64 a9   2f 07 bf 7b   f4 25 74 94 │ GÔ@´ÿÇd©/.¿{ô%t.
0000070: af da 8a fc   0c 18 81 58   b8 3c 2e 97   c0 9d e8 27 │ ¯Ú.ü...X¸<..À.è'
0000080: 3e 02 8a d2   1b 7c 94 cc   cb f4 05 7c   c7 77 f3 75 │ >..Ò.|.ÌËô.|Çwóu
0000090: ea 7e 02 d6   3a 84 5c 4e   1f 88 e7 03   9a 1d 3f 13 │ ê~.Ö:.\N..ç...?.
00000a0: a6 9f 2e cf   be 77 16 be   f1 5f 01 52   cf 13 89 b3 │ ¦..Ͼw.¾ñ_.RÏ..³
00000b0: f3 8a f7 90   18 08 50 99   27 f7 83 d2   a4 32 08 76 │ ó.÷...P.'÷.Ò¤2.v
00000c0: ef b4 99 6c   80 dd 1a 47   04 26 fe b1   02 b3 d4 e7 │ ï´.l.Ý.G.&þ±.³Ôç
00000d0: 3d 44 3a 64   64 46 39 77   35 61 6b 6c   7b 68 34 db │ =D:ddF9w5akl{h4Û
00000e0: 51 75 39 2e   bc 46 8e 96   d1 8a 4c 79   f4 7a 7b e0 │ Qu9.¼F..Ñ.Lyôz{à
00000f0: f5 44 85 eb   ef 68 d5 22   26 4a 2a ef   fc 60 00    │ õD.ëïhÕ"&J*ïü`.

Uriel

Posted 2011-09-18T18:25:54.403

Reputation: 11 708

1

Python 2, 453 442 427 387 bytes

  • @nore saved 11 bytes: Thanks a ton!!: pointed £ used before was a double byte char!!
  • saved 15 bytes: swallow shorthand
  • @nore saved 40 bytes!!!!! THANKS A LOT!!!
  • @Zachary T saved 1 byte: space between in and "..." removed
  • Thanks to notepad++'s find and replace tool. ;)
r="%2(:0)That wr66j5 inside her(_1)How absurd+1({3)Imagine that+3(}4)What a hog+4(~4*3)}horse)She died of course."
for i in"}~3*1){!{~1*0)_!_~0*2):!:^2)$%!~She7ed the !%There was an old lady who7ed a !$Perhaps she'll die(\n!* to 3ch the !^I don't know why she7ed that !+ to7 a !(.\n!),\n!0spider!1bird!2fly!3cat!4dog!65 and !5iggled!7 swallow".split("!"):r=r.replace(i[0],i[1:])
print r

Try it online!

officialaimm

Posted 2011-09-18T18:25:54.403

Reputation: 2 739

1You can save a lot of bytes by using ~ instead of £ (which is two bytes long as it is not ASCII). – nore – 2017-06-25T16:38:33.283

Woah, Thanks man! Never knew that was an extended chararcter!! – officialaimm – 2017-06-25T16:42:25.123

1

This can still be pretty heavily golfed (a few chars with the symbols at the beginning, 1 by using Python2, and more optimizing replacements)

– nore – 2017-06-25T18:23:25.070

1You don't need a space between in and a string literal. – Zacharý – 2017-06-25T23:30:38.943

1

Groovy, 475 bytes

b="swallowed"
a="There was an old lady who $b a"
c="I don't know why she $b that fly,\nperhaps she'll die."
d="She $b the"
e=" to catch the"
f=" to swallow a"
g="iggled"
h=" spider"
i=" fly"
j=" dog"
k=" cat"
l=" bird"
m="$d$h$e$i,"
n="$d$l$e$h,"
o="$d$k$e$l,"
print"""
$a$i.
$c

$a$h,
That wr$g and $g and j$g inside her.
$m
$c

$a$l,
How absurd$f$l.
$n
$m
$c

$a$k,
Imagine that$f$k.
$o
$n
$m
$c

$a$j,
What a hog$f$j
$d$j$e$k,
$o
$n
$m
$c

$a horse,
She died of course."""

Nothing too interesting, just a lot of string interpolation. Golfing tips on this one are welcome!

staticmethod

Posted 2011-09-18T18:25:54.403

Reputation: 191

did you mean to write swallowed, not shallowed? – Destructible Lemon – 2017-06-25T23:51:36.480

@Destructible Lemon it is fixed now :P – staticmethod – 2017-06-26T06:00:37.230

1

Wolfram Language (Mathematica), 295 bytes

BinaryDeserialize@ByteArray@ToCharacterCode@"8C:xœåPANÃ0<ãW쭗(ï€R‘8o³[ÛÅx+;••ðnÖqª6(NÄ͚ÏÎÌþãáÅqb(˜#H H'† …	Žaê͐ÄÝoQŠ*&ȎïT£Ã±
;óÌÉá9W~çޘïÊgOœ:U«YIÞÚPñHp÷<-o³ªA{³ÿ’…+7cs¼Ÿèqð‰:ó¨ð/‰jŒ…_Ø­È_¾îñËêéI=ôŽÖGnŽ«~Jo՚­ô‡w ±y­NNìz%·V ¦»¥Çük9I™[*ýF Gä¢Xÿ	Tÿ”\""

Try it online!

This solution is a 46-byte decompressor BinaryDeserialize@ByteArray@ToCharacterCode@"..." acting on a 248-byte array masquerading as an ASCII string. Transferring this string between different programs is a bit tricky. TIO, for instance, blows this solution up into 416 bytes using UTF-8 encoding instead of keeping the ASCII string. To get the minimal 295-byte solution, save the text in a variable text and run

BinaryWrite["ThereWasAnOldLady.wl", Join[
  ToCharacterCode["BinaryDeserialize@ByteArray@ToCharacterCode@\""],
  Normal[BinarySerialize[text, PerformanceGoal -> "Size"]] /. {34 -> Sequence[92, 34]},
  ToCharacterCode["\""]]]

then execute the generated file on the command-line with

wolframscript -print -f ThereWasAnOldLady.wl 

Roman

Posted 2011-09-18T18:25:54.403

Reputation: 1 190

1

Python, 484

Ok, I did it but was pretty boring...

The last sentence is always with "fly" so some chars were removed...

f,s,b,c,d=o='fly spider bird cat dog'.split()
x='There was an old lady who swallowed a %s.\n'
t=' to swallow a %s.\n'
r=['That wriggled and iggled and jiggled inside her.\n','How absurd'+t%b,'Imagine that'+t%c,'What a hog'+t%d]
t=("She swallowed the %s to catch the %s,\n"*4%(d,c,c,b,b,s,s,f)).split('\n')
print("I don't know why she swallowed that fly,\nPerhaps she'll die.\n\n".join([x%f]+[x%o[i]+r[i-1]+'\n'.join(t[-i-1:])for i in range(1,5)]+[''])+x%'horse'+'She died of course.')

Less golfed version:

f,s,b,c,d = all = 'fly spider bird cat dog'.split()

what = 'There was an old lady who swallowed a %s.\n'

t = ' to swallow a %s.\n'
comments = ['That wriggled and iggled and jiggled inside her.\n',
            'How absurd' + t%b,
            'Imagine that' + t%c,
            'What a hog' + t%d]

swallowed = "She swallowed the %s to catch the %s,\n"
lines = (swallowed*4%(d,c,c,b,b,s,s,f)).split('\n')

end = '''I don't know why she swallowed that fly,
Perhaps she'll die.\n\n'''

def who_catch_who(i):
    return '\n'.join(lines[-i-1:])

p = end.join([what % f] + 
             [what % all[i] +
              comments[i-1] +
              who_catch_who(i) for i in range(1,5)] +
             [''])

print(p + what % 'horse' + 'She died of course.')

JBernardo

Posted 2011-09-18T18:25:54.403

Reputation: 1 659

1

Haskell, 515 498

Score does not count newlines and spaces added for presentation.

b c a="There was an old lady who swallowed a "++a++c++".\n"
t r a=b(",\n"++r++" to swallow a "++a)a
s(a,b)="She swallowed the "++a++" to catch the "++b++",\n"
z=["fly","spider","bird","cat","dog"]
h=[b"",b",\nThat wriggled and iggled and jiggled inside her",t"How absurd",
 t"Imagine that",t"What a hog"]
v(g,p)=g++(=<<)s(zip p$tail p)++
 "I don't know why she swallowed that fly,\nPerhaps she'll die.\n\n"
main=putStr$(=<<)v(zip(zipWith($)h z)(tail$scanl(flip(:))[]z))++b
 ",\nShe died of course""horse"

Ungolfed:

type Animal = String
type Comment = String

beginning :: Animal -> Comment -> String
beginning animal comment = "There was an old lady who swallowed a " ++ animal ++ comment ++ ".\n"

ending :: String
ending = "I don't know why she swallowed that fly,\nPerhaps she'll die.\n\n"

to_swallow :: String -> Animal -> Comment
to_swallow start animal = ",\n" ++ start ++ " to swallow a " ++ animal

swallowed_to_catch :: (Animal, Animal) -> String
swallowed_to_catch (a, b) = "She swallowed the " ++ a ++ " to catch the " ++ b ++ ",\n"

animals :: [(Animal, Animal -> Comment)]
animals = [("fly",    const "")
          ,("spider", const ",\nThat wriggled and iggled and jiggled inside her")
          ,("bird",   to_swallow "How absurd")
          ,("cat",    to_swallow "Imagine that")
          ,("dog",    to_swallow "What a hog")
          ]

-- Turn [1,2,3,4,5] into [[1], [2,1], [3,2,1], [4,3,2,1], [5,4,3,2,1]]
trail :: [a] -> [[a]]
trail = tail . scanl (flip (:)) []

verses :: [String]
verses = zipWith verse animals (trail $ map fst animals)

verse :: (Animal, Animal -> Comment) -> [Animal] -> String
verse (animal, comment) swallow_chain =
    beginning animal (comment animal) ++
    concatMap swallowed_to_catch (zip swallow_chain (tail swallow_chain)) ++
    ending

poem :: String
poem = concat verses ++ beginning "horse" ",\nShe died of course"

main :: IO ()
main = putStr poem

Joey Adams

Posted 2011-09-18T18:25:54.403

Reputation: 9 929

@ThomasEding or aliasing it to the # operator or something similar – Cyoce – 2017-01-06T23:34:35.757

Aliasing (++) with a shorter identifier might be a good idea. – Thomas Eding – 2011-09-19T20:05:23.280

1

C, for fun (561 chars)


Score does not count newlines and spaces added for presentation.

Thanks to J B for his improvements!

#include <stdio.h>

void main() {
    char *e = "\nShe swallowed the cat to catch the bird,\nShe swallowed the bird to catch the spider,\nShe swallowed the spider to catch the fly,\nI don't know why she swallowed that fly,\nPerhaps she'll die.\n\nThere was an old lady who swallowed a ";
    printf("%sfly.%sspider,\nThat wriggled and iggled and jiggled inside her.%sbird,\nHow absurd to swallow a bird.%scat,\nImagine that to swallow a cat.%sdog,\nWhat a hog to swallow a dog.\nShe swallowed the dog to catch the cat,%shorse,\nShe died of course.", e+191, e+128, e+85, e+41, e, e);
}

Matthew Read

Posted 2011-09-18T18:25:54.403

Reputation: 521

1

Technically new lines and spaces should be removed from answers, if the score does not count them. https://codegolf.meta.stackexchange.com/questions/6886/how-are-line-breaks-and-formatting-counted-for-code-golf-challenges/6893#6893 (I was informed of this myself recently). But you can post the ungolfed version below it.

– Lyndon White – 2017-06-26T08:34:56.093

@LyndonWhite You'll note that this answer predates that one by 4 years. – Matthew Read – 2017-06-26T17:33:01.910

@MatthewRead so it does. – Lyndon White – 2017-06-27T00:13:14.817

@MatthewRead I see no reason why that rule should not be applied to answers that predate it. – pppery – 2020-01-09T02:47:38.640

@pppery If you want to edit every post on the site from prior to 2015, go for it. – Matthew Read – 2020-01-09T18:51:31.243

Are you sure you need all those & and []? – J B – 2011-09-20T07:23:04.523

1@J B is right, you can replace a[] with *a and just remove the &. You should gain 25 chars. – PhiLho – 2011-09-20T12:38:19.297

There's probably something cool to be done in C, with pointers to the middle of a common shared string. – J B – 2011-09-20T13:37:23.013

@PhiLho Thanks, yesterday my brain was a bit fried and I forgot to remove the &s when using pointers and it didn't work :P. JB, I don't know of a method that wouldn't require indexing (and use even more chars). – Matthew Read – 2011-09-20T15:11:46.893

It's not indexing, it's pointer arithmetic. ",*z=" vs +nn – J B – 2011-09-20T16:30:05.177

Indexing is pointer arithmetic depending on how you look at it. But either way it eliminates 24 chars only to add 52 more. – Matthew Read – 2011-09-20T16:39:23.667

1

Something like this. Your version, reordered, 627 chars http://pastebin.com/MQ4LJue7 ; my version, 561 chars http://pastebin.com/7eMAWmAi

– J B – 2011-09-20T18:16:51.500

Ah, I see now with reordering the string. Very clever. I won't steal that but I'll keep it in mind for the future. – Matthew Read – 2011-09-20T18:27:26.497

Steal away! It's really something that's best done in C, it would be a shame not to have it shown off in the page's only C answer. – J B – 2011-09-20T19:41:47.060

1

C#, 556 chars

class P{static void Main(){string a="There was an old lady who swallowed a ",b="I don't know why she swallowed that ",c="She swallowed the ",d=" to catch the ",e="Perhaps she'll die.\n\n",f="fly",g="spider",h="bird",i="cat",j="dog",k=",\n",l=".\n",m="to swallow a ",n=c+g+d+f+k,o=c+h+d+g+k,p=b+f+k,q=c+i+d+h+k,r=n+p,s=o+r,t=q+s,u=e+a;System.Console.Write(a+f+l+p+u+g+k+"That wriggled and iggled and jiggled inside her"+l+r+u+h+k+"How absurd "+m+h+l+s+u+i+k+"Imagine that "+m+i+l+t+u+j+k+"What a hog "+m+j+l+c+j+d+i+k+t+u+"horse"+k+"She died of course.");}}

Tester101

Posted 2011-09-18T18:25:54.403

Reputation: 141

1

Perl, 489 chars

sub Y{$t=pop;my$s;while($b=pop){$s.="She ${W}ed the $t to catch the $b,\n";$t=$b;}$s.=$l{fly}.$/;}$W='swallow';$w='iggled';$q=" to $W a";$o="There was an old lady who ${W}ed a";$h='hat';@f=qw/fly spider bird cat dog/;@l{@f}=("I don't know why she ${W}ed t$h fly,
Perhaps she'll die.$/","T$h wr$w and $w and j$w inside her.","How absurd$q bird.","Imagine t$h$q cat.","W$h a hog$q dog.");map{$m=$f[$_];print"$o $m,
$l{$m}
",$_?Y@f[0..$_]:'';}0..$#f;print"$o horse,
She died of course.$/"

Zaid

Posted 2011-09-18T18:25:54.403

Reputation: 1 015

0

Java, 655 bytes

public class M{public static void main(String[]P){String S="swallowed",T="There was an old lady who "+S+" a |.",e="I don't know why she "+S+" that fly,\n";String[]a={"fly","spider","bird","cat","dog","horse"};String[]q={"","That wriggled and iggled and jiggled inside her.","How absurd |","Imagine that |","What a hog |",null};for(int i=0;i<a.length;i++){p(T.replace("|",a[i]));if(q[i]==null){p("She died of course.");break;}if(!q[i].isEmpty()){p((q[i].replace("|","to swallow a "+a[i])).trim());for(int j=i;j>0;j--){p("She swallowed the "+a[j]+" to catch the "+a[j-1]+",");}}p(e+"Perhaps she'll die.\n");}}static void p(String v){System.out.println(v);}}

This is a golfed version of this answer. There's over 100 bytes saved on minor things.

Zacharý

Posted 2011-09-18T18:25:54.403

Reputation: 5 710

Some more things to golf: public can be removed; class M{public static void main can be interface M{static void main; String S=...,T=...,e=...;String[]a=...;String[]q=...; can be String S=...,T=...,e=...,a[]=...,q[]=...;; for(int i=0;...)...for(int j=i can be for(int i=0,j;...)...for(j=i; for(j=i;j>0;j--)...a[j]...a[j-1] can be for(j=i;j>0;)...a[j]...[a--j]; static void p(String v){...} can be static<T>void p(T v){...} (623 bytes) Try it online.

– Kevin Cruijssen – 2018-01-29T12:05:39.077

0

Charcoal, 369 366 bytes

A”↓0*)B⎚D³9;7Q7∨-f¶_²χ⁶;↧l⁺I´”¦αA“V×q▶²▷O≕⦃0j↖▷(τ⎇⦄4ω\`j0T⁹ψI2b1züρÀ↑‹⁻ê£AZ‹?DOR§1φ”¦βA⟦spider¦bird¦cat¦dog⟧¦λA,¶¦νA⟦”↶7⎇IPVpθθ⪪➙S²p⸿H⁸✂ν‖2↖²φ↘nτME⦄B↓ξlF⁵y”¦”↶7Nl@;⪫λ38N∕´≕⁺)³ nÀ‴⦃”¦”↶7←´<7YKBYχnZ-↖U⎇ι\HUθ%;⟧”¦”↶7∧§‴⟧O×φ¢\`*NQ¶G⁺$π‽ξat”⟧μA”↓/!Zm⪫⟧αÀ⁻Vε>⟲”¦σA”|‽aC-⁴t;Z⌕”¦τA“Y∨↷ur1BO#ÿk»⁻υv‽⌊←zω↘^”¦η⁺αβF⁴«⁺⁺⁺α§λιν§μιF⮌…⁰ι«⁺⁺⁺⁺σ§λ⁺κ¹τ§λκν»⁺⁺⁺σ§λ⁰τβ»⁺αη

Try it online!

Link to the verbose version of the code.

Charlie

Posted 2011-09-18T18:25:54.403

Reputation: 11 448

0

PowerShell, 512 bytes

[IO.StreamReader]::new(([IO.Compression.GZipStream]::new([IO.MemoryStream]::new(([Convert]::FromBase64String('H4sIAAAAAAAEAOVQQWoDMQy8L+wfdMsl5B3tLdBAz8pKsd26VrAdzP4+cm2SbNlDT6WlN6EZzYzmYDkyFEyAAcQTeKQZihVIBb2XwgQIJz/vxuEZSMImw3uQopQZkuUHWraYK3M7DnuOFs+pEjbeAznW83E4fMssnR1x3Fa6CpbojPEVCAQP41ufXUhKB1VWi5cvgbiLQRaYME/2c9cy/tA3RxdJNZ7UBI/pEqlm6YQOrwavwDL2rZdf+KXaVrMPNC5wU128qfjql1Mj3lP3uv56HyRGJV6rGoIVs2xD0dU2qBHvmVut/6c2KzFxj6aXBHKCSS663F0B')),0,249),[IO.Compression.CompressionMode]::Decompress))).ReadToEnd()

Try it online!

Credit to @Chirishman for their post.

root

Posted 2011-09-18T18:25:54.403

Reputation: 241

0

Stax, 195 bytes

ó┤♣≤jß¡εD<Çjò≡²£c¼ìv┴Åô║,·~┼¢╝EΦ5xZ&√σ"ømÿ≡ZπvÅ╦♣1♦>▄\¬◘¡jS¢í╞╟╚);4j↕i¢s♦éÇöy‼ac┴àÇ╩»-ó»ónú¢│g5εÿ╔µ┬bîæ¢k‼f╓fJ○▐═╜<^Γ▀o▀Δnq░╩αÄ&│♣ⁿâmû╣Ç≡*@☺pG_ⁿö┤mσ/V\└?iq┌îB½Ä¿L╙N┐£Ç≥δ2 0δrµLä⌡(⌡▀╬àΦ⌠tƒìg" ⌠ZHó

Run and debug it

Unpacked, ungolfed, and commented, it looks like this.

`]q~*}8x9uA3_P0O`jX         push ["fly", "spider", "bird", "cat", "dog"] and store in X register
{                           start iteration over animal list
  `p{+P91{m@Lwe\Jk?!#8`Yp   Store "There was an old lady who swallowed a " in Y register and print it
  .,.i!@+                   Concatenate "." on the first iteration and "," thereafter to the animal
  P                         Print
  i{                        On all iterations after the first, execute this block
    `r4uB2O'O(4XghNqE PhaMg^-riMgR{N>A8LfCNqh@Rn$=aHX|93@_5d?d7qp2-`
                        Push "That wriggled and iggled and jiggled inside her. How absurd, bird. Imagine that, cat. What a hog, dog. She died of course"
    ',`?~nA${F"`R       Replace "," with " to swallow a"
    .. /                Split on string ". "
    iv@                 Get the (i-1)th element where i is the iteration index
    '.+P                Concatenate "." and print
  }M                    End of conditional block
  x2B                   Get adjacent pairs from x (list of animals)
  i(                    Keep first i pairs where i is the iteration index
  r{                    Iterate over reversed list of pairs
    `_,m+"S3&#`p        Print "She swallowed the "
    Ep                  Print the second animal from the pair
    `p<qr?t`p           Print " to catch the "
    ',+P                Concatenate "," to the first animal from the pair and print
  F                     End iterating block
  `;p(9Cv,77BzpP'kB|"`P Print "I don't know why she swallowed that fly,"
  `%?/3.=iHiS6y!`P      Print "Perhaps she'll die."
  zP                    Print a newline
F                       End outer animal iteration.
yp                      Print y register. ("There was an old lady who swallowed a ")
`zvVH`P                 Print "horse,"
                        Print "She died of course." with an unterminated literal
`AJt6Q.3+$!

Run this one

recursive

Posted 2011-09-18T18:25:54.403

Reputation: 8 616

0

Java 758 chars

Here is my Java effort ( 758 chars )

public class Poem{public static void main(String[] args){String s1="swallowed",st="There was an old lady who "+s1+" a |.",d1="Perhaps she'll die.",d2="She died ofcourse.",e="I don't know why she " + s1 + " that fly,\n";String[] a={ "fly","spider","bird","cat","dog","horse"};String[] q={ "","That wriggled and iggled and jiggled inside her.","How absurd |","Imagine that |","What a hog |",null};for(int i=0;i < a.length;i++){print(st.replace("|",a[i]));if(q[i]==null){print(d2);break;}if(!q[i].isEmpty()){               print((q[i].replace("|","to swallow a " + a[i])).trim());for(int j=i;j > 0;j--){print("She swallowed the " + a[j] + " to catch the " + a[j - 1] + ",");}}print(e + d1 + "\n");}}
static void print(String value){System.out.println(value);}}

user667914

Posted 2011-09-18T18:25:54.403

Reputation: 1

2You can gain some chars... Poem => P, args => x, print => p, value => v, two letters vars => one letter vars, removing more spaces. – PhiLho – 2011-09-21T15:47:36.313

-1

PowerShell, 349 bytes = Script:9 + Archive:340

tar xOf t

Try it online!

The Powershell script to create the archive t (see TIO):

(
@'
There was an old lady who swallowed a fly.
I don't know why she swallowed that fly,
Perhaps she'll die.
......
There was an old lady who swallowed a horse,
She died of course.
'@
) | Set-Content f -Force
tar zcfo t f
Get-ChildItem f,t # output info about archive size

mazzy

Posted 2011-09-18T18:25:54.403

Reputation: 4 832