Old MacDonald function

16

6

Create a function in your chosen language that prints out the following:

Old MacDonald had a farm, E-I-E-I-O,
And on that farm he had a cow, E-I-E-I-O,
With a moo moo here and a moo moo there,
Here a moo, there a moo, everywhere a moo moo,
Old MacDonald had a farm, E-I-E-I-O!

Where cow and moo are strings in the function parameters, and as such, can be changed to pig and oink or sheep and baa, for example.

It should take into account capital letters, hyphens, punctuation, spaces and line breaks.

Aim to type the fewest amount of Unicode characters in your code.

rybo111

Posted 2014-05-05T09:17:38.077

Reputation: 4 071

1Shouldn't this be [tag:kolmogorov-complexity] though? – mniip – 2014-05-05T09:28:24.053

6You say echoes the following. Do you mean the function should print it out or return it? – cjfaure – 2014-05-05T09:31:23.527

2To make this fair, I think this should have the exact punctuation, spaces and carriage returns in the question. But what do you think about uppercase / lowercase? I thought a single case might be easier and avoid a load of standard applications of base64 or similar. On balance, the only capitals are at the beginning of the line, the word MacDonald and in the E-I-E-I-O, so it may be more interesting to make that exactly per the question too. – Level River St – 2014-05-05T09:45:01.987

Also, given the use of "sclipting" in similar questions, please clarify if this is per Unicode character, ASCII character, or byte. – Level River St – 2014-05-05T09:54:01.023

1Punctuation is essential, as are capitals. The function should print it out. – rybo111 – 2014-05-05T10:20:16.453

4Is it acceptable to output a oink or should that be made to be an oink? – ClickRick – 2014-05-05T16:06:47.817

@ClickRick A pedant may object and the same could be said for examples like some chicks -- perhaps make a "pedants version" which caters for words ending with s and/or beginning with a vowel. – rybo111 – 2014-05-05T17:02:29.127

@rybo111 re pedants version - what about plurals that don't end in "s" - e.g. some sheep or some geese? – Digital Trauma – 2014-05-05T17:29:28.947

@DigitalTrauma good point - I guess the pedants version would need some consideration -- perhaps determine both words in the variable, or have a predefined list of animals and their respective sounds! – rybo111 – 2014-05-05T17:43:30.733

4

@rybo111: Were you aware that the great Donald Knuth wrote an academic paper about this kind of thing? It was actually published in a real journal (admittedly in the April edition). More here including a link to the PDF of the paper: http://en.wikipedia.org/wiki/The_Complexity_of_Songs

– Tom Chantler – 2014-05-06T16:11:14.473

1@Dommer No, I wasn't aware. Interesting! – rybo111 – 2014-05-06T17:42:57.017

Answers

15

Javascript ES6 - 204

Aim to type the fewest amount of Unicode characters in your code.

Not the shorter but probably the most obfuscated.

f=(a,b)=>{for(c=[b,a].concat('!,-ADEHIMOWacdefhilmnortvwy \n'.split(o='')),i=62;i;o+=c[e>>10]+c[e/32&31]+c[e&31])e='ⱞᄤ⒇瓤抣瘭㾭癍㚏᫶⦮函࿋Π疽䌐獲樘ྰ㞠戝晐}疽䌐࿈䌐眲Π疽㛏戝癐Π疽伲࿌⒋ფᲉѽ疽䦯䨝抽瘭䦹容㾷碶ᅣᲉᄤྦྷ㜕㞱㗽㾲妴㣗畍⺏'.charCodeAt(--i);alert(o)}

If your browser do not support ES6 :

function f(a,b){for(c=[b,a].concat('!,-ADEHIMOWacdefhilmnortvwy \n'.split(o='')),i=62;i;o+=c[e>>10]+c[e/32&31]+c[e&31])e='ⱞᄤ⒇瓤抣瘭㾭癍㚏᫶⦮函࿋Π疽䌐獲樘ྰ㞠戝晐}疽䌐࿈䌐眲Π疽㛏戝癐Π疽伲࿌⒋ფᲉѽ疽䦯䨝抽瘭䦹容㾷碶ᅣᲉᄤྦྷ㜕㞱㗽㾲妴㣗畍⺏'.charCodeAt(--i);alert(o)}

Copy/Paste that code into your browser console and try f('cow','moo'), f('pig','oink'), f('sheep','baa')

How it works ?

c is an array of 29 letters plus the animal and its sound (let call this our alphabet).
So, all the 31 characters fit in 5 bits (2^5 = 32).
A Unicode character is 16 bits long, so it can encode 3 characters of our alphabet with a padding bit.
The full text with the new lines is 186 characters of our alphabet, it can be encoded with 62 Unicode characters.

For example, Old is encoded like this :

alphabet value         O      l      d
alphabet index         11     20     15
unicode           0  01011  10100  01111  ===> \u2e8f (⺏)

If you have troubles to read some Unicode chars, install Code2000 font

Michael M.

Posted 2014-05-05T09:17:38.077

Reputation: 12 173

2"cow" and "moo" are supposed to be the function parameters. By getting the caller to pass an array, you're saving characters within the function definition at the expense of adding to the character count of the calling code. This smells like a cheat to me. Taking that approach to the extreme you could define function f(a){alert(a)} (23 characters) and say that it needs to be called like f("Old MacDonald had a ..."). – tobyink – 2014-05-06T11:36:43.227

1I had passed the strings in two separated parameters but after reading the challenge, I saw no reason to not pass the strings in array format, so I edited my answer. This is not cheating, just saving few chars when it's possible. Let @rybo111 decide if this fits the rule or not. – Michael M. – 2014-05-06T11:50:07.813

1@tobyink I did use the term 'string' (not array) in the rules, so I suppose you are right. I think 'cheating' is a bit harsh, though! – rybo111 – 2014-05-06T14:04:13.003

2Why does this have so many votes? It's over 200 and not even the shortest javascript solution. – aditsu quit because SE is EVIL – 2014-05-06T15:56:54.927

Whell thougth and well explained so have my vote too – edc65 – 2014-10-25T13:33:21.270

The character count is incorrect, it's 205, and the second one is 211.

– nyuszika7h – 2014-10-27T21:51:09.070

5

CJam - 142 / GolfScript - 144

{" had| a |farm|68, |68 8|here|Old MacDonald765|, E-I-E-I-O|10,
And on that 5 he7690,
With3 2 and3 t2,
Here4t24everyw23,
10!"'|/~A,{`/\*}/}:F;

Usage: "cow""moo"F
For GolfScript replace '| with "|" and A with 10

Explanation:

The key part is A,{`/\*}/:
A,{...}/ executes the block for each number from 0 to 9 (A=10)
` converts the number to string
/\* does a string replace: if we have on the stack "bar" "foo 1 baz" "1" then / splits the string resulting in ["foo " " baz"], \ swaps this array with the previous item ("bar") and * joins the array resulting in "foo bar baz"

So the code replaces each number in the main string with a string that's previously on the stack. We have the animal and the sound, then " had", " a ", etc and finally ", E-I-E-I-O" and the main string, "10,...!". To avoid using too many quotes, I put all the strings (except the parameters) in one string, then split it and dumped the resulting array ('|/~)

The main string goes through the following transformations:

10,
And on that 5 he7690,
With3 2 and3 t2,
Here4t24everyw23,
10!

replace "0" with ", E-I-E-I-O":

1, E-I-E-I-O,
And on that 5 he769, E-I-E-I-O,
With3 2 and3 t2,
Here4t24everyw23,
1, E-I-E-I-O!

replace "1" with "Old MacDonald765":

Old MacDonald765, E-I-E-I-O,
And on that 5 he769, E-I-E-I-O,
With3 2 and3 t2,
Here4t24everyw23,
Old MacDonald765, E-I-E-I-O!

replace "2" with "here", then "3" with "68 8" etc.

8 corresponds to the sound, and 9 to the animal.

aditsu quit because SE is EVIL

Posted 2014-05-05T09:17:38.077

Reputation: 22 326

Can you explain this? I don't even know what CJam is – Cruncher – 2014-05-05T14:16:28.493

@Cruncher CJam is a language I made, http://sf.net/p/cjam ; I can explain it once I finish golfing it :)

– aditsu quit because SE is EVIL – 2014-05-05T14:17:18.473

1@Cruncher added explanation now – aditsu quit because SE is EVIL – 2014-05-05T15:02:24.610

9♬ and on that five he sev'n six nine, ze e e e ro ♬ – aditsu quit because SE is EVIL – 2014-05-05T17:26:19.877

Can E-I- be a string which is then repeated? :) – rybo111 – 2014-05-07T20:13:51.643

@rybo111 maybe, but I ran out of digits – aditsu quit because SE is EVIL – 2014-05-07T20:19:24.420

5

Bash + iconv, 128 Unicode characters

Takes the below pure-bash/ascii function body and reverse-encodes into unicode chars:

m()(c=`iconv -t unicode<<<㵳⁜屡␠ਲ㵨敨敲攊ⰽ⁜ⵅⵉⵅⵉ੏㵯伢摬䴠捡潄慮摬栠摡愠映牡⑭≥攊档␢Ɐ䄊摮漠桴瑡映牡敨栠摡愠␠␱ⱥ圊瑩⑨⁳㈤␠⁨湡⑤⁳㈤琠栤ਬ效敲猤‬⑴⑨ⱳ攠敶祲⑷⑨⁳㈤ਬ漤™ਠ`
eval "${c:2}")

Defines a shell function m. Call as:

$ m pony neigh
Old MacDonald had a farm, E-I-E-I-O,
And on that farm he had a pony, E-I-E-I-O,
With a neigh neigh here and a neigh neigh there,
Here a neigh, there a neigh, everywhere a neigh neigh,
Old MacDonald had a farm, E-I-E-I-O!
$ 

Pure bash, 171 bytes (ascii-only)

I think its worth noting that the original verse (with "cow" and "moo") is only 203 chars.

m()(s=\ a\ $2
h=here
e=,\ E-I-E-I-O
o="Old MacDonald had a farm$e"
echo "$o,
And on that farm he had a $1$e,
With$s $2 $h and$s $2 t$h,
Here$s, t$h$s, everyw$h$s $2,
$o"!)

Defines the shell function m. Call as:

$ m sheep baa
Old MacDonald had a farm, E-I-E-I-O,
And on that farm he had a sheep, E-I-E-I-O,
With a baa baa here and a baa baa there,
Here a baa, there a baa, everywhere a baa baa,
Old MacDonald had a farm, E-I-E-I-O!
$

Digital Trauma

Posted 2014-05-05T09:17:38.077

Reputation: 64 644

4

C++ (403)

Alright, this is a bit of a long shot, but who doesn't like over-defining?

#define O ", E-I-E-I-O"
#define E O<<","
#define I "Old MacDonald had a farm"
#define H(a) "And on that farm he had a "<<a<<E
#define D(s) s<<" "<<s
#define W(s) "With a "<<D(s)<<" here and a "<<D(s)<<" there,"
#define V(s) "Here a "<<s<<", there a "<<s<<", everywhere a "<<D(s)<<","
#define F I<<O<<"!"
#define N endl
void m(string a, string s){cout<<I<<E<<N<<H(a)<<N<<W(s)<<N<<V(s)<<N<<F<<N;}

einsteinsci

Posted 2014-05-05T09:17:38.077

Reputation: 141

2this.eyes.bleeding = true; – Proxy – 2014-05-05T23:53:55.850

Any defines that could further pack this tighter? – einsteinsci – 2014-05-06T06:06:07.387

1It used to be possible to #define X define and then use #X Y Z. Sadly, those heady IOCCC days are now long past... – nneonneo – 2014-05-06T23:49:47.973

What about using + instead of <<? Or using char* instead of string? // Only one of these can be used at the same time. – Qwertiy – 2014-10-25T12:31:33.130

2

Python, 116 Unicode chars

def f(**a):print u'鱸쿳光䷰癌쿉ы㊲匒ሔ툕謒畲尔㵵䅵忘쮇⼱ⅅ伿⒡넣Ⰴ邩ઑ꩕醪徜妮ꊌ㰺⒳Ⰳ鮕꾟ౙ㎧譒ᕒ끒镈롴쀼怪㪢愐腤닔ꋔ狊兔Ⲹ㾗꽡Ȩ똀䝸å'.encode('u16')[2:].decode('zip')%a

StackOverflow is eating my special characters, though, so here's the file in base64:

77u/ZGVmIGYoKiphKTpwcmludCB1J+mxuOy/s+WFieS3sOeZjOy/idGL44qy5YyS4YiU7YiV6KyS55Wy5bCU47W15IW15b+Y7K6H4ryx4oWF5Ly/4pKh64Sj4rCE6YKp4KqR6qmV6Yaq5b6c5aau6oqM47C64pKz4rCD6a6V6r6f4LGZ446n6K2S4ZWS74yS64GS6ZWI7pKA66G07IC85oCq46qi5oSQ6IWk64uU6ouU54uK5YWU4rK4476X6r2hyKjrmIDknbjDpScuZW5jb2RlKCd1MTYnKVsyOl0uZGVjb2RlKCd6aXAnKSVh

The data is packed using zlib, which efficiently codes repeated strings (zlib is good at compressing text in general). To take advantage of the "Unicode characters" rule, the 121-byte zlib chunk is padded and halved to a 61-character Unicode string by interpreting the bytestring as UTF-16.

Call the function as

f(cow='pig', moo='oink')

nneonneo

Posted 2014-05-05T09:17:38.077

Reputation: 11 445

@nyuszika7h No, it’s 116. You forgot to count the “UTF-8 BOM” (EF BB BF) at the beginning, which is necessary to let Python 2 accept non-ASCII source. (This isn’t Python 3, which doesn’t have .decode('zip').) – Anders Kaseorg – 2016-04-30T22:02:50.360

Nice, but Where cow and moo are strings in the function parameters, and as such, can be changed to pig and oink or sheep and baa, for example. Looks like your output is hardcoded to cow/moo. – Digital Trauma – 2014-05-07T00:05:45.877

@DigitalTrauma: My reading comprehension fail! Fixed. – nneonneo – 2014-05-07T00:15:56.433

thats better :) +1 – Digital Trauma – 2014-05-07T00:23:21.577

115. No need to count the trailing newline. – nyuszika7h – 2014-10-27T21:48:30.613

1

Python, 217

You can't really golf this much. I just took out the blatant front-end repetition and...

m,f="Old MacDonald had a farm, E-I-E-I-O",lambda x,y:m+",\nAnd on that farm he had a %s, E-I-E-I-O,\nWith a %shere and a %sthere,\nHere a %s, there a %s, everywhere a %s %s,\n%s!"%((x,)+((y+' ')*2,)*2+(y,)*4+(m,))

Javascript, 241 - JSCrush cheat

Made this with JSCrush...not really a real answer, it'd just be interesting to see if anybody can beat this in a mainstream language. (EDIT: uh)

_='var f=function(c,a){var b=a "+a;return"Anon that he hadcWith  and tHere  t   everyw!"};OlMacDonalhaa a "+, O,\\nhere+"b farm a, d E-I-';for(Y in $=' ')with(_.split($[Y]))_=join(pop());eval(_)

cjfaure

Posted 2014-05-05T09:17:38.077

Reputation: 4 213

1

Java - 262 258

void m(String...s){String b=s[1],c=b+" "+b,d="E-I-E-I-O",e="Old MacDonald had a farm, "+d;System.out.print(e+",\n"+"And on that farm he had a "+s[0]+", "+d+",\nWith a "+c+" here and a "+c+" there,\nHere a "+b+", there a "+b+", everywhere a "+c+",\n"+e+"!");}

Further optimization is definitely possible.

Ypnypn

Posted 2014-05-05T09:17:38.077

Reputation: 10 485

You could use printf – aditsu quit because SE is EVIL – 2014-05-05T13:51:41.620

Trevin Avery suggested this edit: Java - 243

  • void String...a){String c=" a "+a[1],d=c+" "+a[1],e=", E-I-E-I-O",f="Old MacDonald had a farm"+e;System.out.print(f+",\nAnd on that farm he had a "+a[0]+e+",\nWith"+d+" here and"+d+" there,\nHere"+c+", there"+c+"', everywhere"+d+",\n"+f+"!");}

Further optimization is definitely possible – Justin – 2014-05-05T15:28:42.223

1

Rebol, 206 202

f: func[a b][print reword{$o$e,
And on that farm he had a $a$e,
With a $b $b here and a $b $b there,
Here a $b, there a $b, everywhere a $b $b,
$o$e!}[e", E-I-E-I-O"o"Old MacDonald had a farm"a a b b]]

Usage: f "cow" "moo"

draegtun

Posted 2014-05-05T09:17:38.077

Reputation: 1 592

1

Java, 246

void f(String[] a){String o="Old MacDonald had a farm",e=", E-I-E-I-O",x=" a "+a[1],s=x+" "+a[1];System.out.print(o+e+",\nAnd on that farm he had a "+a[0]+e+",\nWith"+s+" here and"+s+" there,\nHere"+x+", there"+x+", everywhere"+s+",\n"+o+e+"!");}

Usage: f(new String[]{"cow","moo"});

Gayuha

Posted 2014-05-05T09:17:38.077

Reputation: 11

1

JavaScript: 152 chars / ES6: 149 chars

Here's a JS function called "z" that does the job in 214 chars. (don't execute it!)

function z(a,b){c=' a '+b;d=c+' '+b;e=', E-I-E-I-O';f='Old MacDonald had a farm'+e;return(f+',\nAnd on that farm he had a '+a+e+',\nWith'+d+' here and'+d+' there,\nHere'+c+', there'+c+', everywhere'+d+',\n'+f+'!')}

I "packed" it in unicode chars using a technique created by @subzey and I for 140byt.es).

eval(unescape(escape('').replace(/uD./g,'')))

execute that last snippet, then call z("cow","moo"), and you'll get this string:

Old MacDonald had a farm, E-I-E-I-O,
And on that farm he had a cow, E-I-E-I-O
With a moo moo here and a moo moo there,
Here a moo, there a moo, everywhere a moo moo,
Old MacDonald had a farm, E-I-E-I-O!"

More info here: http://xem.github.io/golfing/en.html#compress

ES6 version:

eval(unescape(escape('').replace(/uD./g,'')))

xem

Posted 2014-05-05T09:17:38.077

Reputation: 5 523

I think you didn't copy-paste things correctly, your code seems to have over 250 chars -- oops, maybe not, but my text editor is behaving strangely, I'll investigate. – aditsu quit because SE is EVIL – 2014-05-06T16:52:56.850

Oh, most of your characters are from some astral planes (that's probably why they get counted as 2 characters here)... and unallocated too. This is stretching the rules a bit :) – aditsu quit because SE is EVIL – 2014-05-06T16:59:59.747

Well, I don't think this is cheating: those symbols are unicode chars, and shouldn't count as 2 chars. Also, Twitter counts each of them as 1 char. If you copy the ES6 version in a tweet, it says it's too long by 9 chars. So, 149 it is :) – xem – 2014-05-06T17:31:48.447

1

Perl 5 (UTF-8) - 131 characters, 313 bytes

The script below needs to be saved as UTF-8 with no BOM.

use utf8;use Encode;eval encode ucs2,'獵戠晻③㴤∮灯瀻⑥㴢Ⱐ䔭䤭䔭䤭伢㬤漽≏汤⁍慣䑯湡汤⁨慤⁡⁦慲洤攢㬤ⰽ≥牥⁡∻獡礢⑯Ⰺ䅮搠潮⁴桡琠晡牭⁨攠桡搠愠䁟⑥Ⰺ坩瑨⁡③③⁨␬湤⁡③③⁴桥牥Ⰺ䠤Ⱔ戬⁴栤Ⱔ戬⁥癥特睨␬③③Ⰺ⑯™紱';

Usage: f("cow", "moo");.

Perl needs to have been run with the -M5.010 flag to enable Perl 5.10 features. (This is allowed.)

I quite like the symmetry of the character count (131) and byte count (313). It's very yin and yang.

Perl 5 (ASCII) - 181 characters, 181 bytes

sub f{$b=$".pop;$e=", E-I-E-I-O";$o="Old MacDonald had a farm$e";$,="ere a";say"$o,
And on that farm he had a @_$e,
With a$b$b h$,nd a$b$b there,
H$,$b, th$,$b, everywh$,$b$b,
$o!"}

Usage: f("cow", "moo");.

Again, perl needs to have been run with the -M5.010 flag to enable Perl 5.10 features.

tobyink

Posted 2014-05-05T09:17:38.077

Reputation: 1 233

Hmm, looks familar http://codegolf.stackexchange.com/a/26633/11259 ;-)

– Digital Trauma – 2014-05-06T23:38:21.293

Actually http://codegolf.stackexchange.com/a/26628/12469 was my starting point. I tested a few extra variables that cut down the length further, and then applied the UTF16 trick that several of the other implementations make use of.

– tobyink – 2014-05-07T11:51:15.263

1

CJam (non-ASCII) - 77 chars

"啝裢樃濿䶹讄團챤鋚䖧雿ꆪꆵ䷶텸紎腕Խꍰ搓᩟童䚯⤭刧损⬛豳Ẍ퍾퓱郦퉰怈䡞௳閶蚇⡾쇛蕟猲禼࿆艹蹚㞿䛴麅鞑椢⧨餎쏡첦휽嬴힡ݷ녣㯂鐸㭕"56e3b127b:c~

Usage: "cow""moo"F

The string is my other CJam solution converted from base 127 to base 56000.
A UTF-8 locale might be required.

By the way, now you can try this online at http://cjam.aditsu.net/

aditsu quit because SE is EVIL

Posted 2014-05-05T09:17:38.077

Reputation: 22 326

1

C# - 339 Bytes

void x(string c, string d){var a="Old MacDonald had a farm";var b=", E-I-E-I-O";var f=" a ";var g=" there";Debug.WriteLine(a+b+",");Debug.WriteLine("And on that farm he had"+f+c+b+",");Debug.WriteLine("With"+f+d+" "+d+" here and"+f+d+" "+d+g+",");Debug.WriteLine("Here"+f+d+","+g+f+d+", everywhere"+f+d+" "+d+",");Debug.WriteLine(a+b+"!");

Usage: x("cow","moo");

tsavinho

Posted 2014-05-05T09:17:38.077

Reputation: 163

0

Delphi XE3 (272 252)

procedure k(a,s:string);const o='Old MacDonald had a farm';e=', E-I-E-I-O';n=','#13#10;begin s:=' '+s;write(o+e+n+'And on that farm he had a '+a+e+n+'With a'+s+s+' here and a'+s+s+' there'+n+'Here a'+s+', there a'+s+' every where a'+s+s+n+o+e+'!');end;

Ungolfed

procedure k(a,s:string);
const
  o='Old MacDonald had a farm';
  e=', E-I-E-I-O';
  n=','#13#10;
begin
  s:=' '+s;
  write(o+e+n+'And on that farm he had a '+a+e+n+'With a'+s+s+' here and a'+s+s+' there'+n+'Here a'+s+', there a'+s+' every where a'+s+s+n+o+e+'!');
end;

Teun Pronk

Posted 2014-05-05T09:17:38.077

Reputation: 2 599

0

Cobra - 203

def f(a,b)
    d=" a [b] "+b
    e=", E-I-E-I-O"
    m="Old MacDonald had a farm[e]"
    print "[m],\nAnd on that farm he had a [a][e],\nWith[d] here and[d] there,\nHere a [b], there a [b], everywhere[d],\n[m]!"

Even for a language with little-to-no multi-lining, and strict indentation rules, Cobra still does pretty well.

Οurous

Posted 2014-05-05T09:17:38.077

Reputation: 7 916

0

Lua 237

function f(a,b)c=b.." "..b;d="Old MacDonald had a farm, E-I-E-I-O"print(d..",\nAnd on that farm he had a "..a..", E-I-E-I-O,\nWith a "..c.." here and a "..c.." there,\nHere a "..b..", there a "..b..", everywhere a "..c..",\n"..d.."!")end

By defining c=b.." "..b, I can save a dozen characters. By defining d as I do, I save 23 characters. I do not see how I can shorten this anymore. This is called via f("<animal>","<sound>").

Kyle Kanos

Posted 2014-05-05T09:17:38.077

Reputation: 4 270

0

JavaScript 220

function f(a,b){c=' a '+b;d=c+' '+b;e=', E-I-E-I-O';f='Old MacDonald had a farm'+e;console.log(f+',\nAnd on that farm he had a '+a+e+',\nWith'+d+' here and'+d+' there,\nHere'+c+', there'+c+', everywhere'+d+',\n'+f+'!');}

Called by

f('cow', 'moo');

Trevin Avery

Posted 2014-05-05T09:17:38.077

Reputation: 101

0

Java 8(411)

String m(String...m){LinkedHashMap<String,String>n=new LinkedHashMap<>();n.put("/","( * #, -");n.put("#","farm");n.put("-","E-I-E-I-O");n.put("+","here");n.put("*","had a");n.put("(","Old MacDonald");n.put("|"," a )");n.put(")","moo");n.put("moo",m[1]);n.put("cow",m[0]);m[0]="/,\nAnd on that # he * cow, -,\nWith|) + and|) t+,\nHere|, t+|, everyw+|),\n/!";n.forEach((k,v)->m[0]=m[0].replace(k,v));return m[0];}

Abusing of lambda, putted the replaces in a LinkedhashMap to keep em in a defined order then used a foreach lambda to replace key with value in main String. parameters are added as last 2 replacements in the map. that varargs argument is to shave off some bytes in the method header

Ungolfed version:

String m(String... m)
{
    LinkedHashMap<String, String> n = new LinkedHashMap<>();
    n.put("/", "( * #, -");
    n.put("#", "farm");
    n.put("-", "E-I-E-I-O");
    n.put("+", "here");
    n.put("*", "had a");
    n.put("(", "Old MacDonald");
    n.put("|", " a )");
    n.put(")", "moo");
    n.put("moo", m[1]);
    n.put("cow", m[0]);
    m[0] = "/,\nAnd on that # he * cow, -,\nWith|) + and|) t+,\nHere|, t+|, everyw+|),\n/!";
    n.forEach((k, v) -> m[0] = m[0].replace(k, v));
    return m[0];
}

masterX244

Posted 2014-05-05T09:17:38.077

Reputation: 3 942

0

Pure C, 298 bytes, no unicode

In my function I take a single argument, which is actually a bunch of char*'s packed together. Each string is null terminated, and there's an extra null terminator at the end. This allows me to check strlen(a) at the end of each loop, rather than keeping a counter variable.

mcdonald.c:

m(char*a){while(strlen(a)){printf("Old MacDonald had a farm, E-I-E-I-O\nAnd on that farm he had a %s, E-I-E-I-O,\nWith a ",a);a+=strlen(a)+1;printf("%s %s here and a %s %s there,\nHere a %s, there a %s, everywhere a %s %s,\nOld MacDonald had a farm, E-I-E-I-O!\n",a,a,a,a,a,a,a,a);a+=strlen(a)+1;}}

main.c:

int m(char *v);
int main(int argc, char **argv) {
    m("cow\0moo\0programmer\0meh\0\0");
    return 0;
}

Output:

clang main.c mcdonald.c && ./a.out
Old MacDonald had a farm, E-I-E-I-O
And on that farm he had a cow, E-I-E-I-O,
With a moo moo here and a moo moo there,
Here a moo, there a moo, everywhere a moo moo,
Old MacDonald had a farm, E-I-E-I-O!
Old MacDonald had a farm, E-I-E-I-O
And on that farm he had a programmer, E-I-E-I-O,
With a meh meh here and a meh meh there,
Here a meh, there a meh, everywhere a meh meh,
Old MacDonald had a farm, E-I-E-I-O!

wjl

Posted 2014-05-05T09:17:38.077

Reputation: 171

0

C: 224 bytes

By using the printf precision specifier, we can use the same string as both the printf format string and as two of the parameters.

o(char*x,char*y){char*f="Old MacDonald had a farm, E-I-E-I-O,\nAnd on that farm he had a %s%.13sWith a %s %s here and a %s %s there,\nHere a %s, there a %s, everywhere a %s %s,\n%.35s!\n";printf(f,x,f+24,y,y,y,y,y,y,y,y,f);}

With white space and the string split into lines:

o(char* x, char* y)
{
    char* f=
        "Old MacDonald had a farm, E-I-E-I-O,\n"
        "And on that farm he had a %s%.13s"
        "With a %s %s here and a %s %s there,\n"
        "Here a %s, there a %s, everywhere a %s %s,\n"
        "%.35s!\n";

    printf(f,x,f+24,y,y,y,y,y,y,y,y,f);
}

David Yaw

Posted 2014-05-05T09:17:38.077

Reputation: 931

0

PHP - 272 characters, 272 bytes

function m($q,$w){for($e="@&And on that farm he had^<%&With *h# and*th#&H(th(everywh#^> >&@!",$r=1;;$e=$r){$r=str_replace(["@","#","^","%","<",">","&","*","("],["Old MacDonald had^farm%","ere"," a ",", E-I-E-I-O",$q,$w,",\n","^> > ","#^>, "],$e);if($e==$r)break;}echo $e;}

Usage: m("cow", "moo");, m("fox", "Hatee-hatee-hatee-ho");

Parameters with @#%^<>&*( crash the output.

Snack

Posted 2014-05-05T09:17:38.077

Reputation: 2 142

0

Haskell (282 and still somewhat readable :))

wc -c oldmacdonald.hs
     282 oldmacdonald.hs

The file:

main=mapM putStrLn[s"cow""moo",s"pig""oink",s"sheep""baa"]
s c m=o#",\nAnd on that farm he had"#b c#e#let n=m#" "#m in",\nWith"#b n#" here and"#b n#" there,\nHere"#b m#", there"#b m#", everywhere"#b n#",\n"#o#"!\n"
o="Old MacDonald had a farm"#e
e=", E-I-E-I-O"
b=(" a "#)
(#)=(++)

linse

Posted 2014-05-05T09:17:38.077

Reputation: 171

It's 281, you don't usually count the trailing newline, unless it's a C preprocessor macro or something else that requires newline termination. In most cases, you can just subtract 1 from the byte count returned by wc -c, but I prefer using https://mothereff.in/byte-counter and making sure there's no empty line at the end unless required for the program to work.

– nyuszika7h – 2014-10-27T21:47:32.937

0

ES6, 2 solutions of 179 186 chars without any unicode

f=(a,b)=>alert("325And on that farm he had a025With a11 h4nd a11 th45H41, th41, everywh411532!".replace(/\d/g,x=>[" "+a," "+b,", E-I-E-I-O","Old MacDonald had a farm","ere a",",\n"][x]))

And the second:

f=(a,b)=>alert("3625And on7at6 he ha8025With a11 h4n811745H41,741, everywh4115362!".replace(/\d/g,x=>(` ${a}0 ${b}0, E-I-E-I-O0Old MacDonald had a0ere a0,\n0 farm0 th0d a`).split(0)[x]))

I've added alert call (+7 chars).

Qwertiy

Posted 2014-05-05T09:17:38.077

Reputation: 2 697

I think, it's the shortest solution from non-unicoded ones for now. – Qwertiy – 2014-10-25T13:25:12.517

0

JavaScript (E6) 140 chars

Char counter: https://mothereff.in/byte-counter, 140 chars, 425 bytes in UTF-8

eval(unescape(escape('').replace(/uD./g,'')))

Original ASCII code 188 bytes

f=(a,b)=>alert('0125And on 6at13e3ad7 925Wi6 a88347nd a88 645H478, 6478, everywh47885012!'.replace(/\d/g,c=>('Old MacDonald had a0 farm0, E-I-E-I-O0 h0ere0,\n0th0 a0 '+b+0+a).split(0)[c]))

Compressed with http://xem.github.io/obfuscatweet/

Test in FireFox/FireBug console

f('mosquito','zzz')

Output

Old MacDonald had a farm, E-I-E-I-O,
And on that farm he had a mosquito, E-I-E-I-O,
With a zzz zzz here and a zzz zzz there,
Here a zzz, there a zzz, everywhere a zzz zzz,
Old MacDonald had a farm, E-I-E-I-O!

edc65

Posted 2014-05-05T09:17:38.077

Reputation: 31 086