An Old Irish Blessing, reasked (without using encodings)

5

How much can you golf a program to print "An Old Irish Blessing" without using unprintable ASCII characters?

That restricts us to ASCII characters 32-126 (better still, 32,65-90,97-122 and 13(CR))

For reference that version of the proverb is 205 characters long (excl. newlines). I'm curious if anything beats Huffman-encoding incl. spaces.

smci

Posted 2012-01-21T09:15:44.307

Reputation: 169

5(wondering if anyone else sees a need for a 'no-encodings' tag?) – smci – 2012-01-21T09:16:11.717

@Peter: it must use ASCII, and is restricted to characters 32-127. Sound ok? – smci – 2012-01-21T09:41:06.623

2Seems both reasonable and needed. Tagged. – J B – 2012-01-21T10:40:49.940

I guess someone will compress the bitstring into the ASCII range 32..127 then unpack it, but that's frowned upon. Can anyone get below 100% length otherwise? – smci – 2012-01-21T12:36:29.830

1Do note that ASCII 127 is not printable. – J B – 2012-01-21T12:45:10.690

@ J B I know. Just (32..127) gives a range of 96 values, which will be cleaner than 95 for string manipulation or base-changing. To quibble, we also allowed newline which is ASCII 13. – smci – 2012-01-21T12:50:17.890

@smci: ASCII 13 is Carriage Return (CR). Line Feed (LF) aka. newline is ASCII 10 (my answer assumes that's what you meant). – hammar – 2012-01-21T15:54:58.797

@hammar: yes it was – smci – 2012-01-26T20:47:18.410

Answers

3

Golfscript, 198 characters

[]"-!9 4(% 2/!$<)3A50H/ -%%4 9/5
XXXN7).X\"?!,7I3>4UU2I!#+
[[[S35.;(`A[2- 50/.]]]&]%
YO2!U3F|,`/&4ZZZZZK)%,$3
!.$ }4),ze-%%Z!'!k\n-!9 '/S(/]hh )o4(%GG,/7 /&A)3;!v"{.32>{.58<{32+}{56-~1$>2<}if}*+}/+

Output:

$ ruby golfscript.rb blessing.gs
MAY THE ROAD RISE UP TO MEET YOU
MAY THE WIND BE ALWAYS AT YOUR BACK
MAY THE SUN SHINE WARM UPON YOUR FACE
THE RAINS FALL SOFT UPON YOUR FIELDS
AND UNTIL WE MEET AGAIN
MAY GOD HOLD YOU IN THE HOLLOW OF HIS HAND

The poem is compressed to 158 characters by using part of the ASCII range for back-references (of fixed length 2). The coding scheme is as follows:

[10]      : newline (unencoded)
[32]      : space (unencoded)
[33..57]  : literal (33=A, 34=B, ... 57=Y, Z not needed)
[58..126] : back-reference relative to the end of the decompressed string so far. 

The remaining 40 characters make up the decompression code which can probably be golfed a little further, since this is my first attempt at Golfscript.


Case-sensitive version, 207 characters

Same concept, but trading some of the back-reference range for lower case letters at the cost of some compression.

[]"-AY THE ROAD RISaUPhO MEET YOU
xxxnWINxB_ALWiS^TuuRiACK
{{{sSUN[HINa{RM UPON}}}F}E
4HoRAuS fLL SOFTzzzzzkIELDS
!NDlNTIwWE MEEzAGAIN
-AY 'OsHOLxYOU k THEggLOW OF (ISeAND"{.32>{.90<{32+}{88-~1$>2<}if}*+}/+

Output:

$ ruby golfscript.rb blessing-casesensitive.gs
May the road rise up to meet you
May the wind be always at your back
May the sun shine warm upon your face
The rains fall soft upon your fields
And until we meet again
May God hold you in the hollow of His hand

hammar

Posted 2012-01-21T09:15:44.307

Reputation: 4 011

{}{stuff}if can be reduced to !{stuff}*. With 33<{}{stuff}if you can save one character more by changing the test to 32>{stuff}*. Also, you can save that penultimate '' because you'll have an empty string on the stack underneath the array, from the empty stdin. – Peter Taylor – 2012-01-21T15:37:02.210

@PeterTaylor: Awesome, thanks :) – hammar – 2012-01-21T15:46:47.320

And 55\-\.@ can be shortened to 56-~1$. > is an "order" operator, so the array and index can be in either order. However, simply changing \.@ to 1$ causes problems because it's preceded by - and gets tokenised as 55 \ -1 $. – Peter Taylor – 2012-01-21T15:51:34.543

1Nice, but how much extra does it cost to make it case-sensitive? – smci – 2012-01-21T21:30:25.353

@smci: Using some of the back-reference range for lower case letters means I can't reach as far back, so the compressed length becomes 167 for a total of 207 characters, which isn't as bad as I thought, but still just barely too long. – hammar – 2012-01-21T22:05:43.140

1

Python, 263 chars

t="""01road rise2 to34
01w5d be always at4r back
01s7 sh5e warm284r9ce
The ra5s9ll soft284r fields
And 7til we3 aga5
0God 6d4 5 16low of His hand"""

for k,v in enumerate("May ,the , up, meet, you,in,hol,un,on, fa".split(',')):
    t = t.replace(str(k),v)
print t

which was an 'improvement' on my 261-char quick hack, obviously inferior to a simple print.

s="""12road rise up to34
12wind be always at4r back
12sun shine warm54r face
The rains fall soft54r fields
And until we3 again
1God hold4 in 2hollow of His hand"""

for k,v in {1:"May ",2:"the ",3:" meet",4:" you",5:" upon"}.items():
    s = s.replace(str(k),v)
print s

enumerate() takes almost as many chars in creating the dict/sequence, on a short example like this.

smci

Posted 2012-01-21T09:15:44.307

Reputation: 169

I think this is poor in that it takes more characters to generate the blessing than printing the blessing by itself (which is 221 chars) – Blazer – 2012-01-23T06:03:05.500

@Blazer, I remarked exactly that ('obviously inferior to a simple print'). I also remarked that bitpacking would get it smaller (before overhead), since the message has only 28 symbols, thus 4.8 bits of entropy per character. Can you do better (in Python)? – smci – 2012-01-23T12:14:57.903

I posted my answer @smci – Blazer – 2012-01-24T09:00:51.170

1

Perl, 214 characters

s//01road rise2 to 34
01w5d be always at4r back
01s7 sh5e warm284r face
The ra5s fall soft284r fields
And 7til we 3 aga5
0God 6d4 5 1 6low of His hand/;s/\d/('May ','the ',' up',meet,' you',in,hol,un,on)[$&]/eg;say

Toto

Posted 2012-01-21T09:15:44.307

Reputation: 909

2 chars shorter if you add encoding 9 for ' fa' – smci – 2012-01-21T12:53:22.893

@smci:Thanks, but it's giving the same count. – Toto – 2012-01-21T13:04:33.653

True, my mistake. – smci – 2012-01-21T13:09:53.957

1

PHP, 203

Base64 is ASCII only, but I'd still consider this slightly exploitive.

<?=gzinflate(base64_decode('TY5BDsMwCATvecV+hcQkRsWmMras/P8jpW5V9bhidodCN3pmNKOEJs4YT3RDYe64bWzlC0ypCTuDdNLtoHVt2Ol4/BgfFZ6lBk2txJLVD3XSwdvSkFSPqAq3s/8jwpp8o7CM2kUx+fMEXdFZissSsml6FyB1KSOrTdiJLI4c9Rc'));

Proof it works.

Mr. Llama

Posted 2012-01-21T09:15:44.307

Reputation: 2 387

Case-sensitive? – smci – 2012-01-24T01:39:41.487

That's 171 chars for the string + 32 overhead. I guess this string is too small and non-redundant to break even. – smci – 2012-01-26T20:45:24.073

0

Python, 224 chars

print'''1road rise up to meet you
1wind be always at your back
1sun shine warm upon your face
The rains fall soft upon your fields
And until we meet again
May God hold you in the hollow of His hand'''.replace('1','May the ')

Instead of wasting characters on for loops or multiple replaces, I only have one replace with the single most common combinations of words May the

Blazer

Posted 2012-01-21T09:15:44.307

Reputation: 1 902