Dilbert is awesome
source: Dilbert, September 8, 1992

I'm hoping to add a new twist on the classic "Hello World!" program.

Code a program that outputs Hello World! without:

  • String/Character literals
  • Numbers (any base)
  • Pre-built functions that return "Hello World!"
  • RegEx literals

With the exceptions of "O" and 0.

†"O" is capitalized, "o" is not acceptable.

  • 4
    \$\begingroup\$ One of [code-golf] and [code-challenge] please, not both. The point of these tags to to help people find questions with the rules they want to use. Essentially every question on this site should be a game of some kind or another. \$\endgroup\$ Mar 11 '11 at 22:29
  • 4
    \$\begingroup\$ -1 We've already had Obfuscated Hello World, and I think this challenge is too similar. I'd have cast a "close as duplicate" vote, if I weren't a mod. \$\endgroup\$ Mar 11 '11 at 22:35
  • 2
    \$\begingroup\$ @zzzzBov: I don't think it's different enough to warrant another question in the "hello world" theme; a different theme would have been better. But, that's just my opinion. \$\endgroup\$ Mar 11 '11 at 23:39
  • 1
    \$\begingroup\$ I think this is a fine code golf - and better than the prior one. \$\endgroup\$ Mar 12 '11 at 6:58
  • 2
    \$\begingroup\$ Some people seem to assume that "O"* means they can have a string literal with any number of O’s, including zero. I don’t think that was the intention. Please clarify. \$\endgroup\$
    – Timwi
    Mar 12 '11 at 21:12

101 Answers 101


APL (Dyalog Unicode), 35 bytesSBCS

{⍞←⍺,⍵,⍨⊃⍕⍬⋄⍞←!}/⎕NL≡Hello World←⍬0

Try it online!

⍬0 the list [[];0]

Hello World← store those two values in these two variables

the depth of that array; ¯2 (max-depth is 2, negative means ragged)

⎕NL Name List of defined variables (class 2 — negative means return as list of strings)

{}/ apply the following anonymous lambda infix between the two names:

 empty list; []

 stringify; ""

 coerce the first character; " "

⍵,⍨ append the right argument; " World"

⍺, prepend the left argument; "Hello World"

⍞← print that to stdout with no trailing line break


⍞←! print the factorial function to stdout


PHP, 220 202 201 characters

<?$b=++$a+$a;$y=$b+$a;$c=$y+$b;$z=$c*$b;$s=$y*$z+$b;$h=$s*$b+$z-$b;$e=$z*$z+$a;$o=$e+$z;$l=chr($o-$y);echo chr($h).chr($e).$l.$l.chr($o).chr($s).chr($h+$z+$c).chr($o).chr($o+$y).$l.chr(--$e).chr(++$s);

Uses no numbers, string literals, RegEx literals, or pre-built functions that display "Hello World!".

It works: http://codepad.viper-7.com/OhXBkA


Python (169) -- FIXED

Quite a bit longer than the other solutions. But more insane.

from turtle import setworldcoordinates as w
  • \$\begingroup\$ Sorry, typo on my behalf. I've corrected that error now. \$\endgroup\$
    – Jagu
    Mar 19 '11 at 0:35
  • \$\begingroup\$ Nice. I would retract my downvote, but this stupid website doesn’t let me, so don’t blame me... \$\endgroup\$
    – Timwi
    Mar 19 '11 at 17:00
  • \$\begingroup\$ @Timwi: I think if a question/answer is edited, you can undo your vote, can't you? \$\endgroup\$
    – nyuszika7h
    Apr 27 '11 at 5:18

C - 125 128 chars

I didn't see a proper C entry so I wrote this one:

main(){char u='O'/'O',t=u+u+u,h=u<<t,s=h<<u+u,d='O'*'O'+t,l=d+h,o='O'|s,

(As noted below, redefining u via main(u) can save another 9 bytes.)

  • 3
    \$\begingroup\$ Your array isn't NULL-terminated, so it prints junk. Pay 2 chars. Earn them back, and more, by main(u) instead of 'O'/'O'. \$\endgroup\$
    – ugoren
    May 8 '12 at 6:58

C, 190 189 204

  • Must be run with exactly zero command line arguments since it depends on argc being equal to 1.
  • no preprocessor macros
  • Might be system endian dependant (involves cast from integer array to char array)
  • Not memory safe
a,b,c,h,e,l,o;   // variables
i[],m,*j=i;      // array and pointer

main(_)          // if no arguments are given _ will be 1
    o=*"O";      // our one legal string constant
    a=_+_+_;     // a = 3
    b=_<<a;      // b = 8
    c=b*a+b;     // c = 32
    h=(o>>_)^o;  // h = 'h'
    o^=c;        // o = 'o'
    e=h-a;       // e = 'e'
    l=o-h+e;     // l = 'l'
    *j++=h-c|e<<b|l<<b+b|l<<c-b;     // j[0] = 'H' | 'e' << 8 | 'l' << 16 | 'l' << 24
    *j++=o|c<<b|o+b-c<<b+b|o<<c-b;   // j[1] = 'o' | ' ' << 8 | 'W' << 16 | 'o' << 24
    *j=o+a|l<<b|e-_<<b+b|c+_<<c-b;   // j[2] = 'r' | 'l' << 8 | 'd' << 16 | '!' << 24
    puts(i);     // puts("Hello World!\0\0\0\0")


a,b,c,h,e,l,o;i[9],*j=i;main(_){o=*"O";a=_<<_|_;b=_<<a;c=_<<b-a;h=(o>>_)^o;o^=c;e=h-a;l=o-h+e;*j++=h^c|e<<b|l<<b<<b|l<<(c-b);*j++=o|c<<b|(o+b^c)<<b<<b|o<<(c-b);*j=o+a|l<<b|e-_<<b<<b|c+_<<(c-b);printf(i);} /* original */
a,b,c,h,e,l,o;i[4],*j=i;main(_){o=*"O";a=_+_+_;b=_<<a;c=b*a+b;h=(o>>_)^o;o^=c;e=h-a;l=o-h+e;*j++=h-c|e<<b|l<<b+b|l<<c-b;*j++=o|c<<b|o+b-c<<b+b|o<<c-b;*j=o+a|l<<b|e-_<<b+b|c+_<<c-b;puts(i);} /* golfed better */
a,b,c,h,e,l,o;i[],m,*j=i;main(_){o=*"O";a=_+_+_;b=_<<a;c=b*a+b;h=(o>>_)^o;o^=c;e=h-a;l=o-h+e;*j++=h-c|e<<b|l<<b+b|l<<c-b;*j++=o|c<<b|o+b-c<<b+b|o<<c-b;*j=o+a|l<<b|e-_<<b+b|c+_<<c-b;puts(i);} /* removed illegal numeric literal in array size */
  • \$\begingroup\$ i[9] violates the rules. \$\endgroup\$
    – ugoren
    Nov 9 '12 at 18:15
  • \$\begingroup\$ shoot, it does doesn't it. \$\endgroup\$
    – Wug
    Nov 9 '12 at 18:26
  • \$\begingroup\$ i['O'] should be fine. Or i[-~-~-~-~0]. \$\endgroup\$
    – ugoren
    Nov 9 '12 at 21:05
  • \$\begingroup\$ The way that's there works (with the caveat that it starts scribbling over other global variables, but they're not read from again later so I don't care). I could probably reorder them to specifically take advantage of this behavior and make them only overwrite variables that are from-then-on unused. Anyway, at this point it contains no numeric literals and I rather like it that way. \$\endgroup\$
    – Wug
    Nov 9 '12 at 21:57

JavaScript 100 chars (when all in one line)

Borrowing subtly from zzzzBov -- with regard to the -~ trick, not seen that before :) -- this is another way to source those pesky space and exclamation characters.

Relies on the Function.toString() ability:

for(i in{Hello:0,world:"O"}){a+=i+([]+function(){!0}).charAt(c);c+=c>>!0}

JavaScript 89 chars (when all in one line)

Also zzzzBov could slightly improve the first example by using the fact that arrays in JS collapse down to strings when used in a calculation; oh, and not creating needless vars ;)

t=!0<<-~-~-~-~!0;r=[];for(i in{Hello:"O",World:0})r+=i+String.fromCharCode(t++);alert(r)

Java - 147, no literals

class HelloCWorlds{static{char[]a=HelloCWorlds.class.getName().toCharArray();int

Run it like this (after compiling):

java HelloCWorlds 2>/dev/null

If you don't want to ignore stderr, then add System.exit(0); after the last semicolon. It brings the file size to 162 and makes use of the 0 literal.

  • \$\begingroup\$ Nice trick! Just one thing to mention: not works with OpenJDK. pastebin.com/gxE7PrjX \$\endgroup\$
    – manatwork
    Mar 19 '13 at 8:42
  • \$\begingroup\$ @manatwork Hmm I think it's not about OpenJDK, but about java 6 vs 7 \$\endgroup\$ Mar 19 '13 at 8:55
  • \$\begingroup\$ Possible. BTW, I dug out an old “java version "1.4.2_02" Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_02-b03)” to test this – also works fine. \$\endgroup\$
    – manatwork
    Mar 19 '13 at 9:04

Python3, 16 bytes

import __hello__

Note the rule:

pre-built functions that return "Hello World!"

Does not apply since:

  1. That's an import and not a function
  2. It doesn't return anything
  3. It doesn't return the string but simply prints it.

Python 3 – 99 chars

from re import*

Taking advantage of the fact that the re module uses integers as flags, e.g. re.X is 64.


JavaScript, 661 characters (without "O" or 0)

That's not the shortest, but that was funny to make. I tried to make it without 0 or "O".

I'm not really happy with H and W because it's the only ones which uses non-symbols characters, but that works. If anyone has an idea to do it ...

This is javascript code, tested in firefox 27 scratchpad, and running with Ctrl+I (should I add an alert or console.log ?).

(document+[])[(++[[]+[]][+[]])<<(++[[]+[]][+[]])<<(++[[]+[]][+[]])<<(++[[]+[]][+[]])] // H
+((!!{})+[])[((++[[]+[]][+[]])<<(++[[]+[]][+[]]))+(++[[]+[]][+[]])]                   // e
+([]+(![]))[(++[[]+[]][+[]])<<(++[[]+[]][+[]])]                                       // l
+([]+(![]))[(++[[]+[]][+[]])<<(++[[]+[]][+[]])]                                       // l
+([]+{})[++[[]+[]][+[]]]                                                              // o
+([]+{})[((++[[]+[]][+[]]<<(~!+[]))+[])[(++[[]+[]][+[]])<<(++[[]+[]][+[]])]]          //  
+(self+[])[(++[[]+[]][+[]])<<(++[[]+[]][+[]])<<(++[[]+[]][+[]])<<(++[[]+[]][+[]])]    // W
+([]+{})[++[[]+[]][+[]]]                                                              // o
+([]+(!!{}))[++[[]+[]][+[]]]                                                          // r
+([]+(![]))[(++[[]+[]][+[]])<<(++[[]+[]][+[]])]                                       // l
+([][+[]]+[])[(++[[]+[]][+[]])<<(++[[]+[]][+[]])<<(++[[]+[]][+[]])<<(++[[]+[]][+[]])] // d
+((/!/)+[])[++[[]+[]][+[]]]                                                           // !

(the count of 661 of course doesn't include the comments)

  • \$\begingroup\$ I have one in the Obfuscated Hello world task that makes use of assignment. The idea is to use the Function constructor (which is reachable as ""["constructor"]["constructor"]) to allow arbitrary code. You could do something similar perhaps. \$\endgroup\$
    – FireFly
    Feb 5 '14 at 13:49

Heres my Perl entry.

It uses the length of an array to store the ordinal of the character.

use strict;
use warnings;
use 5.010;
my @hello_world = (
say map{ chr @$_ } @hello_world;

That seemed like a lot of writing to me, so I used this to generate the above code:

perl -E'
  say for map{"use $_;"} qw"strict warnings 5.010";
  say "my \@hello_world = (";
  say "  [",join(",",@$_),"]," for map{[(0) x ord]} split //, "Hello World";
  say ");";
  say q"say map{ chr @$_ } @hello_world;"

bash, 66 characters

66 characters, no new lines

Hello(){ H=$FUNCNAME;};World! (){ echo $H $FUNCNAME;};Hello;World!

Previous version (81 characters), left here because I like the $IFS trick :-)

81 characters, no new lines

Hello(){ H=$FUNCNAME;};World! (){ echo $H${IFS:0:$[0**0]}$FUNCNAME;};Hello;World!

81 as well but with (including) new lines and easier to read

Hello(){ H=$FUNCNAME;}
World! (){ echo $H${IFS:0:$[0**0]}$FUNCNAME;}

Commented version

Hello(){ H=$FUNCNAME;}                        # set $H to function name ("Hello")
World! (){ echo $H${IFS:0:$[0**0]}$FUNCNAME;} # print $H, first char of $IFS (" ") & "World!"
Hello;World!                                  # run the stuff

(strictly speaking the calculation 0**0 should be indeterminate but it evaluates to 1 :-D)


Python, 139 bytes

class World():
class Hello(World):
 def __init__(self):
  print(self.__class__.__name__, self.__class__.__base__.__name__)

SmileBASIC, 98 bytes (non-competing)

I admit, this answer is cheating. Labels transparently behave as strings when in an expression, but technically they aren't string or character literals, right? If anyone wants to weigh in feel free but I'm convinced a SmileBASIC answer would just amount to abusing PI() or EXP() to compute every character code.


You could easily golf this more, I'm sure.


Commodore 64 O.0! interpreter

O0 Hello World interpreter

The best I could come up with was to write an interpreter that would accept O and 0 - O starts the counter from 65 (A) and 0 adds 1 to the counter, so you have to enter the following to produce HELLOWORLD**


Which I work out at 124 characters. To use, run the program and start typing with O, enter 0 to increase the character count and begin a new character with O again.

** The current version of the interpreter does not support the space or new line character, and you have to break [RUN/STOP] to stop it


Unlambda, 37 bytes

Note that Unlambda doesn't have string or integer literals; .a is a function with a two-character name that writes a to standard output; it's not a function . that takes a as argument.

`.!`.d`.l`.r`.o`.W`. `.o`.l`.l`.e`.Hi

Try it online


Python 272 chars

print chr(s-g)+chr(s+g*c+a)+chr(s+g*d+a)+chr(s+g*d+a)+chr(s+h*d)+chr(s-h*f+a)+chr(s+h)+chr(s+h*d)+chr(s+g*e)+chr(s+g*d+a)+chr(s+g*c)+chr(s-h*f+b)

Though I'm surprised no one tried this method

Python 31 chars

print f.read()
  • \$\begingroup\$ I don't think '0' is valid. I think only 0 and '0' are valid. \$\endgroup\$ Oct 26 '16 at 17:27

Scala 159

val o='O'/'O'
val t=o+o
val d=t+o
val f=t*t
val e=f*t
val l=' '-d
println (List(-e+o,d*e-t,l,l,' ',-'/',e,' ',' '+d,l,(e-1)*d).map(x=>(x+'O').toChar).mkString)


val one='O'/'O'
val two=one+one
val drei=two+one // tri, three
val four=two*two
val eight=four<<one

val l=' ' - drei
val h=List(-eight+one, four*eight-two, l, l, ' ', -'/'+one, eight, ' ', ' ' + drei, l, (eight-1)*drei)
println (h.map (x=> (x + 'O').toChar).mkString)

Common Lisp, 35

I think nobody tried Common Lisp. Strictly speaking, a symbol is not a string literal, so this is valid:

(print(symbol-name'|Hello World!|))

Second-short if you count the Mathematica one.


Perl, 96 chars

sub AUTOLOAD{my$x++;$y=$x<<$x++;print substr($AUTOLOAD,$x+$y).chr(($x<<$y)+$a++)}

It passes the rules!


Python, 110

def HelloOWorld():B
def B(a):print HelloOWorld.__name__.replace('O',chr(a+~0))+chr(a)

Lua, 36



In Tcl, everything is a string.

puts Hello\ World!

If you disallow this, then this is the only valid Tcl program that can be written:


Javascript, 186

alert("O00O000OO00O0OOO0OO00OO0OO00OO0OOOO0O00000O0O0OOOOO0OOOOOOO00O0OO0OO00OO00O00".replace(/\D/g,-~0).replace(/......./g,function(O){return String.fromCharCode(parseInt(0+O,-~!0));}))

Fish - 270

>"O":l(?!v~~~~~~~lo 00000v |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !<lo0000000000000000000v  |0000000 !<lo000lo~~~~~~lo~~~~~~~~lo~~~~~~~~~v;
^        <|000000000000 !<lo0000000l:oo000lo~~~~~~~~~~~~~~~~~^|000000000000000000 !<lo0000000000^  |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !<lo;

Using |0000000000 !< to double the number of 0's put onto the stack. It will bounce off the mirror, and then jump past the <.


PowerShell: 596 382

Started with Joey's idea (Excel counts 1155 characters!) and cut it by about half with some math, then down to a third with some more math and optimization of my own script.

Original: 596 characters:

My first version was fairly similar to the current one in general theory, but a bit simpler in implementation. I just took each character's ASCII code and broke it into two factors, then converted those into strings of zeroes that were as long as the factors, and made PowerShell put them back together. Some numbers were problematic since the smallest factor pairs I could come up with were pretty high - especially 'e', since 101 is prime.


Current: 382 characters

The current version includes a few optimizations, and a change to more comfortably suit the spirit of the challenge.

  • All factor pairs now end up 23 short of their actual target. This makes every element equate to a composite number, greatly reducing the characters required to build all of them. This alone saved about 156 characters.
  • Used a ForEach-Object loop, via the % alias, instead of for.
  • Replaced the 1 (though it was defining array indexes, and so not strictly a number or string literal) with '0'.length. This may cost me some characters, but it's relatively small in comparison to the overall length of the script and helps to fit in with the theme a bit better.
  • Optimized the multiplication routine by using a % loop instead of individually calling out array elements.
  • Restructured the script so that no defined variables are needed.


-join[char[]](...) will take an array of integers (generated by the script within), convert them to ASCII characters, and put it all together in one string output.

('0000000','0000000'),('000000','0000000000000'),... are pairs of strings of zeroes. Within a pair, the product of each string's length comes 23 short of an ASCII code needed to represent a character in 'Hello World!'.

|%{...} pipes the factor pairs into a ForEach-Object loop.

(($_|%{$_.length})-join'*'|iex) takes the length of each factor in a pair and multiplies them together.

+'00000000000000000000000'.length effectively adds 23 to the product, resulting in our target ASCII code.

Hello World!


C# (169)

class HelloOWorld0
    public static void Main()
        Console.WriteLine(typeof(HelloOWorld0).Name.Replace('O', (char) ConsoleKey.Spacebar).Replace('0', (char) ConsoleKey.PageUp));


class HelloOWorld0{public static void Main(){Console.WriteLine(typeof(HelloOWorld0).Name.Replace('O',(char)ConsoleKey.Spacebar).Replace('0',(char) ConsoleKey.PageUp));}}

Ruby, 115 characters

No numbers or string literals whatsoever.


Ruby, 110 characters (but less awesome)

This one has a zero. :(

  • \$\begingroup\$ z=[z].size is brilliant. \$\endgroup\$
    – Jordan
    Aug 16 '16 at 15:54

Sclipting, 9


Sclipting pushes this into the stack as an array of numbers and returns as a string.

  • 1
    \$\begingroup\$ I would guess this violates the "no number literals" rule? \$\endgroup\$ Nov 2 '15 at 19:37

R, 78


Wanton abuse of deparse (which extracts the literal name of an object, i.e. "de-parsing" it, even if that object doesn't exist) and R's name class, which is not a string literal; is.character(quote(Hello)) returns FALSE. Also ! is a function in R, hence the backticks.

But for a (slightly) more honest solution,

R, 391 after removing whitespace

u = !is.na("O")


In R, there is a built-in object called letters that's, well, a vector of letters. is.na returns FALSE because "O" is not equal to the special value NA, and ! negates the logical (aka Boolean). Then + in R automatically coerces logicals to numerics.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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