136
\$\begingroup\$

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

Leaderboard

Here is a Stack Snippet to generate both a regular leaderboard and an overview of winners by language.

/* Configuration */

var QUESTION_ID = 307; // Obtain this from the url
// It will be like https://XYZ.stackexchange.com/questions/QUESTION_ID/... on any question page
var ANSWER_FILTER = "!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe";
var COMMENT_FILTER = "!)Q2B_A2kjfAiU78X(md6BoYk";
var OVERRIDE_USER = 48934; // This should be the user ID of the challenge author.

/* App */

var answers = [], answers_hash, answer_ids, answer_page = 1, more_answers = true, comment_page;

function answersUrl(index) {
  return "https://api.stackexchange.com/2.2/questions/" +  QUESTION_ID + "/answers?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + ANSWER_FILTER;
}

function commentUrl(index, answers) {
  return "https://api.stackexchange.com/2.2/answers/" + answers.join(';') + "/comments?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + COMMENT_FILTER;
}

function getAnswers() {
  jQuery.ajax({
    url: answersUrl(answer_page++),
    method: "get",
    dataType: "jsonp",
    crossDomain: true,
    success: function (data) {
      answers.push.apply(answers, data.items);
      answers_hash = [];
      answer_ids = [];
      data.items.forEach(function(a) {
        a.comments = [];
        var id = +a.share_link.match(/\d+/);
        answer_ids.push(id);
        answers_hash[id] = a;
      });
      if (!data.has_more) more_answers = false;
      comment_page = 1;
      getComments();
    }
  });
}

function getComments() {
  jQuery.ajax({
    url: commentUrl(comment_page++, answer_ids),
    method: "get",
    dataType: "jsonp",
    crossDomain: true,
    success: function (data) {
      data.items.forEach(function(c) {
        if (c.owner.user_id === OVERRIDE_USER)
          answers_hash[c.post_id].comments.push(c);
      });
      if (data.has_more) getComments();
      else if (more_answers) getAnswers();
      else process();
    }
  });  
}

getAnswers();

var SCORE_REG = /<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/;

var OVERRIDE_REG = /^Override\s*header:\s*/i;

function getAuthorName(a) {
  return a.owner.display_name;
}

function process() {
  var valid = [];
  
  answers.forEach(function(a) {
    var body = a.body;
    a.comments.forEach(function(c) {
      if(OVERRIDE_REG.test(c.body))
        body = '<h1>' + c.body.replace(OVERRIDE_REG, '') + '</h1>';
    });
    
    var match = body.match(SCORE_REG);
    if (match)
      valid.push({
        user: getAuthorName(a),
        size: +match[2],
        language: match[1],
        link: a.share_link,
      });
    
  });
  
  valid.sort(function (a, b) {
    var aB = a.size,
        bB = b.size;
    return aB - bB
  });

  var languages = {};
  var place = 1;
  var lastSize = null;
  var lastPlace = 1;
  valid.forEach(function (a) {
    if (a.size != lastSize)
      lastPlace = place;
    lastSize = a.size;
    ++place;
    
    var answer = jQuery("#answer-template").html();
    answer = answer.replace("{{PLACE}}", lastPlace + ".")
                   .replace("{{NAME}}", a.user)
                   .replace("{{LANGUAGE}}", a.language)
                   .replace("{{SIZE}}", a.size)
                   .replace("{{LINK}}", a.link);
    answer = jQuery(answer);
    jQuery("#answers").append(answer);

    var lang = a.language;
    if (/<a/.test(lang)) lang = jQuery(lang).text();
    
    languages[lang] = languages[lang] || {lang: a.language, user: a.user, size: a.size, link: a.link};
  });

  var langs = [];
  for (var lang in languages)
    if (languages.hasOwnProperty(lang))
      langs.push(languages[lang]);

  langs.sort(function (a, b) {
    if (a.lang > b.lang) return 1;
    if (a.lang < b.lang) return -1;
    return 0;
  });

  for (var i = 0; i < langs.length; ++i)
  {
    var language = jQuery("#language-template").html();
    var lang = langs[i];
    language = language.replace("{{LANGUAGE}}", lang.lang)
                       .replace("{{NAME}}", lang.user)
                       .replace("{{SIZE}}", lang.size)
                       .replace("{{LINK}}", lang.link);
    language = jQuery(language);
    jQuery("#languages").append(language);
  }

}
body { text-align: left !important}

#answer-list {
  padding: 10px;
  width: 290px;
  float: left;
}

#language-list {
  padding: 10px;
  width: 290px;
  float: left;
}

table thead {
  font-weight: bold;
}

table td {
  padding: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b">
<div id="answer-list">
  <h2>Leaderboard</h2>
  <table class="answer-list">
    <thead>
      <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr>
    </thead>
    <tbody id="answers">

    </tbody>
  </table>
</div>
<div id="language-list">
  <h2>Winners by Language</h2>
  <table class="language-list">
    <thead>
      <tr><td>Language</td><td>User</td><td>Score</td></tr>
    </thead>
    <tbody id="languages">

    </tbody>
  </table>
</div>
<table style="display: none">
  <tbody id="answer-template">
    <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr>
  </tbody>
</table>
<table style="display: none">
  <tbody id="language-template">
    <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr>
  </tbody>
</table>

\$\endgroup\$
15
  • 9
    \$\begingroup\$ I guess import in python is not permitted. \$\endgroup\$
    – Alexandru
    Feb 1, 2011 at 0:07
  • 29
    \$\begingroup\$ Does these rules apply to language keywords as well? \$\endgroup\$
    – hallvabo
    Feb 1, 2011 at 13:04
  • 10
    \$\begingroup\$ are those case insensitive restrictions? \$\endgroup\$
    – Rommudoh
    Aug 4, 2011 at 14:22
  • 24
    \$\begingroup\$ 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. \$\endgroup\$ Aug 5, 2011 at 23:01
  • 6
    \$\begingroup\$ @trinithis, and others, ASCII character 72 is "H" which is why I chose those two \$\endgroup\$ Sep 18, 2011 at 23:18

144 Answers 144

1
\$\begingroup\$

Tellurium, 16 bytes

µUryyb Jbeyq~r^

This basically encodes "Uryyb Jbeyq" with ROT-13 (Hello World) and displays the result.

\$\endgroup\$
1
\$\begingroup\$

Python 2, 39 chars

print'\x48e\x6c\x6co %cor\x6c\x64'%-~86

Breaks rule 3-1.

Ungolfed versions

print '%ce%c%co %cor%c%c' % (0x48, 0x6c, 0x6c, 0x56 + 0x1, 0x6c, 0x64)
print '%ce%c%co %cor%c%c' % (68 + 4, 108, 108, 86 + 1, 108, 100)

Normal version (-2) (18 chars)

print'Hello World'

Ungolfed

print 'Hello World'
\$\endgroup\$
0
1
\$\begingroup\$

Vim, 31 keystrokes

ia<C-v><C-v>92<esc>22<C-a>SU<C-o>@"yyb Jb<C-v>x65yq<esc>g?g

This was really fun! I'll write an explanation a little bit later.

\$\endgroup\$
1
\$\begingroup\$

Perl 6, 86 bytes

I chose to break the second rule.

my &a={$*IN.gist.substr($_,1)};say a(4)~"e"~a(8)~a(8)~"o "~a(36-9).uc~"or"~a(8)~a(8-1)

Calling gist on $*IN (neither of which has any forbidden characters) gives this string:

IO::Handle<IO::Special.new(what => "<STDIN>")>(opened, at octet 0)

So I pieced together parts of this string to get the desired message. There is no capital W, but luckily uc doesn't have any forbidden characters either.

\$\endgroup\$
1
\$\begingroup\$

Pushy, 16 bytes

Note that this solution is non-competing as the language postdates the challenge.

`Ifmmp!Xpsme`Kt"

Try it online! Here's the basic rundown:

`Ifmmp!Xpsme`     \ Push these character codes to the stack
             Kt   \ Subtract one from all
               "  \ Print as string

The main string is just Hello, World!, with all its characters moved 1 space up the ASCII table - hence why we subtract 1 from all the character codes.

This solution satisfies the first and third criteria - it would even match the second, if not for that single e at the end of the string.

\$\endgroup\$
1
\$\begingroup\$

AWK, 164 bytes

#!/bin/awk -f
BEGIN{n++
system("awk 'printf(\"%c",$n)}'<<<\""69+3"\n"98+3"\n"36*3"\n"36*3"\n"36*3+3"\n"35-3"\n"84+3"\n"36*3+3"\n"36*3+6"\n"36*3"\n"94+6"\n"6+4"\"")}

Usage: Place the code in a file, FILE, and set the 'executable-bit' to true. Sending a single string input will print Hello World. Multi-line input results in the string being printed once for each line.

Example:

File <<< "42"

Since a program was requested, I assume the code is running on some UNIX-like environment with the awk executable available at /bin/awk. I further assume that /bin is in your path.

Not sure if this really counts as just an AWK program, since it is using the system command, but at least the system call is calling AWK. :)

I do violate the second rule, simply because I couldn't come up with a way around using the printf command. :(

\$\endgroup\$
1
\$\begingroup\$

><> (Fish), 39 bytes

'Tqxx{,c{~xp'bv
ii*p:?!;{c-þi+>aa*b+b

I wanted to add a shorter solution that does not violate any rules. First line adds each letter of the encoded 'Hello World' and initializes the 'counter'.

The second line loops, outputting the next letter until counter hits 0. The thorn is overwritten with 'o', ><>'s output instruction once every loop, but that doesn't hurt anybody.

To get around the inability to use '1' while saving characters, I used the operation 'i', which tries to read stdin and pushes '-1' to the stack when it finds nothing there.

\$\endgroup\$
1
  • \$\begingroup\$ I like that you stayed within the rules more so than the earlier one. \$\endgroup\$
    – Abraxas
    Jan 17, 2017 at 5:54
1
\$\begingroup\$

PHP, 36 34 bytes

not the shortest PHP answer, but unique enough for a post.

H<?=hhhh3lll^zsspw_gz^wwwwdddd,ld;

and

H<?=hhhh3lll^zsspw_gz^wwwwdddd?>ld

violate rule #1.

There are of course less "violent" operand combinations; but if you must sin, make it worth it!

other versions:

for(;$c="Fkbba.Ya|bj"[$i++];)echo$c^_^Q;    # 40 bytes, violates rules #1 and  #2
for(;$c="Fkbba.Ya|bj"[$i++];)print$c^_^Q;   # 41 bytes, violates rule #2
<?="Fkbba.Ya|bj"^___________^QQQQQQQQQQQ;   # 41 bytes, no violation
<?=____YzffR__^TQQQF3nnQQQ^Ckbbpi_gqbj;     # 39 bytes, no violation
H<?="kbba.Ya|"^________^QQQQQQQQ,ld;        # 36 bytes, violates rule #1
\$\endgroup\$
1
\$\begingroup\$

Octave, 103 bytes

This one adheres to all three rules and should be fairly obfuscated.

Strings can be created in Octave by concatenating a vector with a string. So, why not concatenate it with the string 'PPCG'? I added ... so that it's possible to read it without scrolling to the side. It can be removed along with the line break.

['PPCG',3336,3848,5384,6664,584,5896,584,869,364,364,3848,364,4463,544,343,343, ...
3336,4463,3954,3948,356]

ans = Hello World

I'll post an explanation for this in one week. Until then, try figuring it out by yourself. Note, this doesn't work on any of the online interpreters I tried, but it works fine on GNU Octave 4.2.0.

\$\endgroup\$
4
  • \$\begingroup\$ Just curious, do you have any idea why the online interpreters output differently? (I got PPCGHHelllo WWorld from TIO) \$\endgroup\$
    – user41805
    Jan 27, 2017 at 18:25
  • \$\begingroup\$ I'm guessing they can't handle ASCII control characters, but I'm not sure... \$\endgroup\$ Jan 27, 2017 at 18:31
  • \$\begingroup\$ Aah, the famous backspace, nice idea :) \$\endgroup\$
    – user41805
    Jan 27, 2017 at 18:38
  • \$\begingroup\$ But where's the backspace? :-P \$\endgroup\$ Jan 27, 2017 at 19:08
1
\$\begingroup\$

VBScript, 58 Bytes

Only breaks rule 2:

msgbox unescape("%48e%6C%6Co%"&19+1&"%5"&(6+1)&"or%6C%64")
\$\endgroup\$
1
\$\begingroup\$

05AB1E, 5 bytes (non-competing)

Breaks none of the rules, code:

”Ÿ™‚ï

Uses CP-1252 encoding. Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ This is invalid. The expected output isn't Hello Dc. You must use ”Ÿ™‚ï instead. \$\endgroup\$ Apr 26, 2017 at 16:44
  • \$\begingroup\$ @EriktheOutgolfer Thanks, I have corrected it. \$\endgroup\$
    – Adnan
    Apr 26, 2017 at 16:55
1
\$\begingroup\$

Brainf*** (106 characters)

++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.
\$\endgroup\$
2
  • \$\begingroup\$ Welcome to PPCG! \$\endgroup\$
    – FlipTack
    Nov 11, 2017 at 19:53
  • 1
    \$\begingroup\$ BTW, there's an open-ended +500 bounty for anyone beating the current Brainfuck "Hello, World!" record (78 bytes -- with a comma and an exclamation point). \$\endgroup\$
    – Arnauld
    Nov 11, 2017 at 20:01
1
\$\begingroup\$

Data URI 28 bytes

data:;base64,SGVsbG8gV29ybGQK

Copy and paste into the browser url bar

\$\endgroup\$
1
\$\begingroup\$

Befunge-93, 24 bytes

9"mu{x`)xuunQ">9#,-#$:_@

Try it online!

Violates no rules. Simply pushes the text shifted by 9 and subtracts 9 from each character before printing.

\$\endgroup\$
1
\$\begingroup\$

Japt, 9 bytes

`HÁM WŽld

Try it online!

The built-in shoco compressor just did the perfect job to remove eor.

Alternatively, slightly less obvious:

16 bytes

"Ifmmp!Xpsme"c_É

Try it online!

c maps over the charcodes, and is a decrement function. É is a shorthand for -1.

\$\endgroup\$
0
1
\$\begingroup\$

Z80Golf, 21 bytes

Contains unprintable bytes, so here's xxd (breaks rule 1):

00000000: 0063 6b71 6e56 1f6e 6b6b 6447 2e0b 7e3c  .ckqnV.nkkdG..~<
00000010: ff2d 20fa 76                             .- .v

Try it online!

    nop
    ld h, e ; 'Hello World' backwards if you add 1 to each byte
    ld l, e ; execution falls through
    ld (hl), c
    ld l, (hl)
    ld d, (hl)
    rra
    ld l, (hl)
    ld l, e
    ld l, e
    ld h, h
    ld b, a
    ld l, loop - 3
loop:
    ld a, (hl)
    inc a
    rst $38
    dec l
    jr nz, loop
    halt
\$\endgroup\$
1
\$\begingroup\$

DOS .com executable: 31 bytes

BE 13 01 AC B4 02 34 FF 88 C2 75 03 80 C4 4A CD
21 EB F0 B7 9A 93 93 90 DF A8 90 8D 93 9B FF

Stores the string byte-inverted, outputs using DOS syscalls. Contains none of the banned characters.

source:

.code16
.org 0x100
start:
 movw $str, %si
l:
 lodsb
 mov $0x02, %ah
 xor $0xff, %al
 mov %al, %dl
 jnz 1f
 add $0x4a, %ah
1: int $0x21
 jmp l
str:
.ascii "\xb7\x9a\x93\x93\x90\xdf\xa8\x90\x8d\x93\x9b\xff"
\$\endgroup\$
1
\$\begingroup\$

Runic Enchantments, 39 bytes

\>`''`
\+kw+kwb8qn;' 83*´34 f-;@

Try it online!

As seen in Notepad++ to better distinguish the non-printing bytes:

Notepad++ view

Violates only rule 1. I had fun computing the first line (a sequence of raw byte values). Alternatively I could have violated rule 2, but I felt that doing so was less obfuscated. There's four different methods used in the 39 byte solution for generating integer values, making it hard to figure out what's going on (compared to just some mathematical operators in the 17 byte solution).

39 byte solution must occupy two lines.

\$\endgroup\$
1
\$\begingroup\$

Gol><>, 21 bytes

"mu{x`)xuunQ"T:Z;9-ot

This is a program that JoKing made, golfing the heck out of it.

Try it online!

Old version, 37 bytes

"Fcjjm"b3+s"Umpjb"c&rT&M:&33-)QPPot|;

This is a really simple, not very creative way of doing this, all it does is just encode everything 2 below their actual ascii encoding, the hardest part is not using 'l', which in gol><> is the length of the stack!

Try it online!

\$\endgroup\$
0
1
\$\begingroup\$

naz, 80 bytes

9a8m1o9a9a8a3a1o6a1a1o1o3a1o0m9a4m8a1o9s3s1o3m9s1o9a9a6a1o3a1o6s1o8s1o0m4a8m1a1o

Breaks rule 2 only.

\$\endgroup\$
1
\$\begingroup\$

TeX, 39 bytes

Meets conditions 1 and 2:

^^48^^%^^,^^,^^/ ^^57^^/^^2^^,^^$\by^^%

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Pxem, 0 bytes (content) + 41 36 bytes (filename).

Inspired by @MD FX.

  • Filename (escaped): ayIfmmp!Xpsme?.z\001.-.t.v.m.v.c?.a.s.p
  • Content: empty

What it does

  • Push next characters
  • Decrement each of them
  • Output them finally

Try it online!

Previously

41 bytes

\$\endgroup\$
1
\$\begingroup\$

K (ngn/k), 22 bytes

{`c$-4+"Lipps${svph%"}

Try it online!

Quite straightforward.

\$\endgroup\$
1
\$\begingroup\$

(,) 352 304 294 Chars or \$294\log_{256}(3)\approx58.25\$ Bytes

(()()(),()()()()()()())((),(()()())()()())((()),(())(())(()))(((())),((()))((()))(()))(,,,(((())))()())(()(),(((())))((()))())(,,,(()()))(,,,(()())(()()()),(),,()())(,,,(()())(()))(,,,((()))()())(,,,(((())))(())(()()()))(,,,(()())(()))(,,,(()())(())()()())(,,,(()())(()()()))(,,,(((())))((())))

This is shorter than my normal hello world program (because we don't have ! or ,). Also, finally under 300 chars!
TIO

\$\endgroup\$
0
\$\begingroup\$

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.

\$\endgroup\$
0
\$\begingroup\$

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!
\$\endgroup\$
0
\$\begingroup\$

Ruby (42 chars, rules I & III)

puts"\x48e\x6c\x6co #{'V'.succ}or\x6c\x64"
\$\endgroup\$
0
\$\begingroup\$
void main(){
int a[100]={4,1,8,8,11,-68,19,11,14,8,0,0,0};
for(;a[13]<a[4];a[13]++)
{
    printf("%c",100+a[a[13]]);
}

}

Funny,isn't it?

\$\endgroup\$
0
\$\begingroup\$

XeTeX

Compile with xetex, output is in generated PDF. Of course, this still breaks some of the rules (still uses forbidden digits) and could be obfuscated and compacted a lot more, but I am tired and have to go to bed. Well, maybe you like it anyway :-)

\let~\def
\toksdef\|0
\let\ea\expandafter
~\>{\uppercase{\|\ea{\the\|.}}} 
~\.{\uccode`.\numexpr32+}
~\u#1{\|{}\ea\v\number`#1 \^^J{\iffalse}..\fi\relax}
~\v1#1#2#3#4{\.#1#2\>\.#3#4\>\ea\v\number`}
\u{㛵䔌䘣䘾䔄}\the\|
\bye
\$\endgroup\$
0
\$\begingroup\$

Brainfuck, 94 Characters

++++++++[>++++[>++>+++>+++>+++>+<<<<<-]>+>+>+>-[<]<-]
>>.>---.>++++..+++.>>.<-.<.+++.------.<-.

Obvious, being BF it breaks none of the rules.

If I lowercase the output it's only 86, but I don't think that's allowed.

>+>++>++>+++[>[->+++<<+++>]<<]
>--.---.>>+++..+++.>-.<++++++++.--------.+++.------.<<-.

The first one is a balanced nested loop generator, the second is a slipping (or sliding) loop generator

NB: The newlines in the code are for this message, they should be removed for running or counting.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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