Tell me more ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

Create the shortest possible obfuscated program that displays the text "Hello World".

In order to be considered an obfuscated program, it must meet at least two of the following requirements:

  • Does not contain the characters: "h", "l", "w" and "d" in any case
  • Does not contain the characters: "e", "o", "r", "0", and "1" in any case
  • Does not contain the characters: "2" or "7"

Input:
none

Output:
Hello World

share|improve this question
I guess import in python is not permitted. – Alexandru Feb 1 '11 at 0:07
What is the difference between letters, characters and numbers. – Alexandru Feb 1 '11 at 0:08
@Alexandru: Just consider them all to be characters, and you'll be fine. – Chris Jester-Young Feb 1 '11 at 0:10
8  
Does these rules apply to language keywords as well? – hallvabo Feb 1 '11 at 13:04
7  
Could someone explain why 2 and 7 are not allowed? I'm just curious as I don't see why those were chosen in particular. – Thomas Eding Aug 5 '11 at 23:01
show 8 more comments

54 Answers

1 2

C, 160 chars

Works only on little-endian machines with 4-byte int:

main(){int a='a',b=a/a,c=b+b,f=c+c,g=f+f,i=g+g,j=i*i,k=j*j,m=a+g+b+c,n=m+b+c;int p[]={a+g-b+(a+f)*j+m*k*(j+b),n+i*c*j+k*(n+g+n*j),a+i+b+m*j+(a+f-b)*k};puts(p);}

Satisfies all three rules.

share|improve this answer

Whitespace (167 characters)

To obtain the WS program, substitute a Space, Tab, or Linefeed character for S, T, L, respectively, in the following string:

SSSTSSTSSSLTLSSSSSTTSSTSTLTLSSSSSTTSTTSSLTLSSSSSTTSTTSSLTLSSSSSTTSTTTTLTLSSSSSTSSSSSLTLSSSSSTSTSTTTLTLSSSSSTTSTTTTLTLSSSSSTTTSSTSLTLSSSSSTTSTTSSLTLSSSSSTTSSTSSLTLSSLLL

or download the "raw" whitespace-only program in the text-file hello.ws.

When executed by this WS interpreter, this program prints "Hello World".

Explanation (ignore the whitespace here!):

SSS TSSTSSSL TLSS  <-- output H (ascii code 72 in decimal, 1001000 in binary) 
SSS TTSSTSTL TLSS  <-- output e (ascii code 101 in decimal, 1100101 in binary) 
SSS TTSTTSSL TLSS  <-- etc
SSS TTSTTSSL TLSS
SSS TTSTTTTL TLSS
SSS TSSSSSL TLSS
SSS TSTSTTTL TLSS
SSS TTSTTTTL TLSS 
SSS TTTSSTSL TLSS 
SSS TTSTTSSL TLSS
SSS TTSSTSSL TLSS 
LLL                <-- end the program

The "middle" strings (e.g. TSSTSSSL) are the ascii codes (in binary, with S denoting 0, T denoting 1) for the successive letters in "Hello World". The prefix SSS pushes the number that follows it (terminated by an L) onto the stack. TLSS outputs the character whose ascii code is on top of the stack. Finally, according to this tutorial, a program must end with LLL for a clean exit by the interpreter.

NB: I'm entering this as a separate answer, because the other WS program entry is a 1287-character program that prints "Hello, world of spaces!" instead of the required "Hello World".

share|improve this answer
+1 for limiting to zero visible characters. – GlitchMr Apr 28 '12 at 7:17

C (333 characters)

I decided to emphasize on obfuscate, with golf secondary. This is written entirely in C, and it only breaks rule #2 laid out in the original post. It also breaks I don't know how many C programming rules...

int main(){
int a[]={0x0a004000,0x0fc00109,0x04e01500,0x09e08400,0x03506a61,0x00f00000,0x0f010ae3,0x05f0fb16,0x0beb0030,0x0130a300,0x0bc00500,0x00000000};
int b,c=13,e,x,an;
goto _XX;
_00:an=e,x^=x,b^=b;
_10:if(!an)goto _XX;
b|=!!(an&0xf)<<x++;
an>>=4;
goto _10;
_XX:if(c<=1)goto _40;
if(c<13)printf("%c",b);
e=a[13-c--];
goto _00;
_40:return 0;
}
share|improve this answer

bash 28 chars:

printf 'p|ɹ°M ο||ǝ%b'"\x48"

p|ɹοM ο||ǝH

alternatively with /bin/echo (18 chars) *) see discussion below.

/bin/echo -e 'p|ɹοM ο||ǝ\0110'

Selftest:

echo "printf 'p|ɹοM ο||ǝ%b' "\x48"" | egrep -i "[^hlwd27eor01]"

Harder than thougth! Tools, for turning Words upside down, the tools think an 'H' or 'o' turned upside down is best displayed as H or o. This would be in conflict with group 1 (Hlwd:27:eor01) respectively 3.

H can be displayed with

echo -e "\0127"

but 01 and 2 are poisoned too. Gee! But the bash-buildin echo has not only the option to display octal ascii values, but hexadecimal too:

echo -e "\x48"

But if we use bash as a programming language, the echo command is part of the program, which not only counts to the character count, but also contains the poisoned characters (hlwd:27:eor01) eho from groups 1 and 3.

So this is moment the echo died. Fortunately, there is printf, which knows "%b" to display .

The r is the only problematic character in printf, and belongs to group 3. Since 'o' is in the last group, we could leave it in Hello and in World, but we can use the omicron ο which looks like an o, or ° &deg;.

Links:

share|improve this answer
Would upvote this, but your reputation is too leet. – GlitchMr Apr 28 '12 at 7:18
@GlitchMr: Now you can - I voted something down, and should be seet 500N. :) – user unknown Apr 28 '12 at 9:20
dl.dropbox.com/u/63913412/stilltooleet.png. Also, downvoting questions doesn't decrease reputation. Downvoting answers does nevertheless. – GlitchMr Apr 28 '12 at 9:32
@GlitchMr: Ah, that's it! :) – user unknown Apr 28 '12 at 12:34

FSharp, 83

("(())(((()("|>String.mapi(fun i c->" =CCG/GJC<".[i]+c)).Insert(5," ")|>printf "%s"

Breaks the second rule to use some F# keywords.

share|improve this answer

Haskell, 38

Constraints 1 and 3 followed.

main=putStr$map succ"G\x64kkn\USVnqkc"
share|improve this answer

Groovy - 50 93 96 Characters

'GdkknVnqkc'.bytes.each{System.out<<(char)(it+1)}

Breaks rule 2. I don't see any other option than breaking rule 2, as AFAIK it's necessary to use either System.out or println, and using println will break both rules 1 and 2.

Edit:

s={k,v->for(;v>0;v>>=6)System.out<<(k-(v&63) as byte[])}
s 113,34886441
s 48,16
s 130,509150443

Second attempt: much longer, more obfuscated, and hopefully passes all the rules!

Rule Check:

['2','7','H','h','L','l','W','w','D','d'].collect{
    it in ("""s={k,v->for(;v>0;v>>=6)System.out<<(k-(v&63) as byte[])}
    s 113,34886441
    s 48,16
    s 130,509150443""" as List)
}
share|improve this answer
Also breaks rule 1, because "char" contains an "h". – Luigi Plinge Nov 20 '11 at 15:54
ouch, will take a look – Alison Nov 20 '11 at 18:15
Thanks @Luigi: updated with a different solution – Alison Nov 21 '11 at 17:17
each breaks rules 1 and 2 ... but they are pretty stupid rules, IMO – Luigi Plinge Nov 21 '11 at 17:53
@Luigi good point - have removed each, and corrected the rule check so it actually works – Alison Nov 22 '11 at 6:43

BrainFuck (96 char)

Beside @R. Martinho Fernandes's BrainFuck answer, this is another BF program with 10 less characters

++++++++++[>++++++++++>+++<<-]>++++.---.+++++++..+++.>++.<++++++++.--------.+++.------.--------.
share|improve this answer

Q (40 chars)

Silly answer but it satisfies rule 1 & 2

"c"$(+\)(8*9;10+19;6+1;0;3;10-89;55;10+14;3;-6;-8)
share|improve this answer

J (23 characters)

a.{~<:a.i.'Ifmmp!Xpsme'

It doesn't beat Golfscript, but I figure J deserves an entry anyway. (This is just a minor tweak of the second example on the J vocabulary page for the word i..

share|improve this answer

APL (157 155)

No h, l, r, w, d, 2, 7, e, o, or r, but there is 0 and 1 (so it meets two out of three requirements).

I went for obfuscation rather than size. (If you can't figure out how it works, it is a variation of this guy's method).

⎕UCS{⌈+/96,⍵{⊃a×b○c×1.118×⍺,a b c←⍵}¨,⌿((11-33)13.3 ¯8.5 18(.3×4)16.5 4 8.5 .4 6,[0]10⍴(⍴'⍴⍴')1),[1]⌈.5×⍳10}¨(⍳11)-1

APL (28)

Boring straightforward one, but meets all requirements and is short-ish.

⎕UCS(⎕UCS'Jgnnq"Yqtnf')-.5×4
share|improve this answer
+1 That's a great link. But your code's greek to me. :) (Don't worry, I'll get there. Just got some Iverson from Amazon.) – luser droog Apr 10 at 3:58

C Program (83 Characters)

#include<stdio.h>
void main(){printf("%ce%c%co %cor%c%c",104,108,108,119,108,100);}
share|improve this answer
This program satisfies rules 1 and 3. – Aniket Suryavanshi May 1 '12 at 17:46

C, ??? characters

Not very heavily golfed, but I was going more for obfuscation anyway. Your mileage may vary, you'll probably have to do some crap to get the hardcoded address of printf right. No forbidden characters. You could easily shorten up a lot of stuff by not using different numbers of underscores as variable names and instead using 1 letter things, but I think it looks uglier this way.

int main()
{
    int(*f)(int*,...)=467846797-333333333;
    int _=9-8,__=_<<_,___=__<<_,____=___<<_,_____=____<<_,______=_____<<_,$=_|((_____|____)<<__);

    f("%c", $+(_|__|___)^______);
    f("%c", $+(___));
    f("%c", $+(_|__|____));
    f("%c", $+(_|__|____));
    f("%c", $+(__|___|____));
    f("%c", ______);
    f("%c", $+(__|___|_____)^______);
    f("%c", $+(__|___|____));
    f("%c", $+(_|_____));
    f("%c", $+(_|__|____));
    f("%c", $+(_|__));
    f("%c", ______|_);
}
share|improve this answer
int main()
{printf("%c%c%c%c%c%c%c%c%c%c%c", ('C'+5), ('a'+4), ('i'+3), ('f'+6), ('i'+6), (35-3), ('T'+3), ('j'+5), ('k'+7), ('g'+5), ('f'-2));}
share|improve this answer

This one doesn't pass the rules, but I thought it was interesting anyway (basically a Python implementation of a Caesar cipher, based on gnibbler's answer.)

print "".join([chr(ord(x)-1) for x in "Ifmmp!Xpsme"])

Just got to think of a way to implement keywords without breaking the rules.

share|improve this answer

Assembly: 117 source chars, 29 byte .com file

Assemble using A86.

mov si,273
mov ah,2
mov dl,133
lodsb
add dl,al
int 21h
lodsb
add dl,al
jne 266
ret
sbb ax,7
add si,[bx+di+6199]
add di,dx
clc
pushf
share|improve this answer
I don't have A86. nasm assembles it, but in 31 bytes, and it crashes DOSBox when run. – J B Feb 9 '11 at 19:50
1  
@J B: There's a link to A86 in the post. – Skizz Feb 10 '11 at 9:13
2  
This contains the characters 1 and 2 and therefore violates the rules. Maybe you didn’t mean “assembly” but rather machine code and you only posted the assembly representation of it? You need to say this. Otherwise I can just post some C code and say that the entry is the compiled binary... – Timwi Mar 8 '11 at 20:33
1  
@timwi: it contains 'h', 'd', 'l', '7', 'e' and 'o' as well. But then you'd be hard pressed to write any assembler code that didn't have those characters. Even the machine codes would have 0,1,2 or 7 somewhere. – Skizz Mar 8 '11 at 21:49
I guess that means your entry violates the rules. Sorry. – Timwi Apr 4 '11 at 10:50

Processing, 189 characters

int[]z={104,101,108,108,111,119,111,114,108,100};for(int i=0;i<z.length;i++)if(i==0||i==5)print((char)Character.toUpperCase(z[i]));else if(i==4)print((char)z[i]+" ");else print((char)z[i]);

If I'm not mistaken, this program only violates rule number two... unless of course the 'h' in "Character" is ruled as a violation. First post to CodeGolf!

Ungolfed

int[] z = {104, 101, 108, 108, 111, 119, 111, 114, 108, 100};

for (int i = 0; i < z.length; i++)
{
    if (i == 0 || i == 5) print((char) Character.toUpperCase(z[i]));
    else if (i == 4) print((char) z[i] + " ");
    else print((char) z[i]);
}
share|improve this answer

C: 162 characters (excluding unnecessary newlines)

I opted for readability and transparency when writing this.

a[3],b;main(){b=99
+9;b+=b<<8;b=b<<8|
97|4;b=b<<8|64|8;a
[3^3]=b;b=78+33<<8
;b+=87;b=b<<8|35^3
;b=b<<8|64|47;a[5^
4]=b;b=97+3<<8;b+=
99+9;b=b<<8|66|48;
a[6^4]=b;puts(a);}

It satisfies all three requirements.

share|improve this answer

dc 48

8 9*P101P108P108P111P4 8*P81 6+P111P114P108P100P

One way how to execute:

dc<<<"8 9*P101P108P108P111P4 8*P81 6+P111P114P108P100P"

The solution conforms to the first and the third rule.

share|improve this answer

C code:

#include
main(){int x=0,y[14],*z=&y;*(z++)=0x48;*(z++)=y[x++]+0x1D;*(z++)=y[x++]+0x07;*(z++)=y[x++]+0x00;*(z++)=y[x++]+0x03;*(z++)=y[x++]-0x43;*(z++)=y[x++]-0x0C;*(z++)=y[x++]+0x57;*(z++)=y[x++]-0x08;*(z++)=y[x++]+0x03;*(z++)=y[x++]-0x06;*(z++)=y[x++]-0x08;*(z++)=y[x++]-0x43;*(z++)=y[x]-0x21;x=*(--z);while(y[x]!=NULL)putchar(y[x++]);}

Output :

Hello, world!
share|improve this answer

Ruby (42 chars, rules I & III)

puts"\x48e\x6c\x6co #{'V'.succ}or\x6c\x64"
share|improve this answer

Python: 66 characters

op=""
for i in "Tqxx{,c{~xp":
    op=op+chr(ord(i)-(4*3))
print op
share|improve this answer

Perl:

perl -le 'print map{chr(ord($_)-2)}split //,"Jgnnq\"Yqtnf"'
share|improve this answer
1  
breaks all of he rules! the choice of shifting by 2 almost seems to be trying to break all of them, which would be possibly ok if it was obfuscated – Joel Berger Oct 1 '11 at 17:01
@JoelBerger Or he could've bumped it up to another number and made sure the string contained none of the characters for breaking one of the rules. – Mike Dtrick Jul 18 '12 at 11:31

C

23 Characters

main(){puts(__FILE__);}

Note : Name the File "Hello World"

EDIT: Breaks 2 Rules. :(

share|improve this answer
1  
Technically, its not obfuscated...but i dunno, i think it's good enough. :) – st0le Feb 1 '11 at 5:11
1  
The code breaks two of the rules with __FILE__ alone – Kevin Brown Feb 1 '11 at 17:16
@bass5098, i misread the question...i thought 2 were allowed. doh! :-\ – st0le Feb 2 '11 at 5:07
1  
main(int $,int**_){puts(_[$^$]);} doesn't break any of the rules if the name of the executable is Hello World. It does compile nicely under GCC (entirely without warnings), but not under Clang, as Clang requires the type of the second argument to be char**, which alone breaks two of the rules. – Fors Apr 21 at 11:22
1 2

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.