# Hello world with a twist

Your goal: to write a piece of code that will result in the classic result of "Hello, world!" being printed to STDOUT or equivalent.

Rules: Code must be entirely in printing ASCII. All code must be functional - removal of any single counting character must change the result or cause the code to not function. All variables must be used after assignment. Character and String literals must be necessary to the output - that is, replacement of any character literal or any character within a string literal with another character must be capable of changing the result (and not via the effect of escape sequence - replacing character with backslash or equivalent)

(NOTE: Final rule was edited in)

Scoring: This is where it gets interesting. Highest score wins as determined by number of characters, as per typical code-bowling rules. But repeated use of characters will result in point deductions. Specifically...

1. Repeated use of any alphanumeric character (a-z, A-Z, 0-9) will result in a deduction of 3 points per repeat (first use does not result in a deduction).
2. Repeated use of basic punctuation ([!?.-,":';]) - including the brackets - will result in a deduction of 2 points per repeat.
3. Repeated use of other ASCII characters {~@#$%^&*_+=|\/><} - including the curly brackets - will result in a deduction of 4 points per repeat. 4. Repeated use of spaces, tabs, and newlines will result in a deduction of 1 point per repeat. That is, only the first use of a space, tab, or newline will count towards your total. Note: comments do not count towards total, although the characters marking the start/end of a comment do. For instance, in C/C++, If you have /* This is a comment */, then it will count two slashes and two asterisks, but nothing between them. Some examples (note: using Julia as sample language)... print("Hello, world!");  Total visible characters: 22 Contains Space: +1 Repeated alphanumerics: -12 for llor Repeated punctuation: -2 for " Final score: 22+1-12-2 = 9 print("Hel",char(108),"o, wor",0x108,"d!"); # 0x108 makes a Uint8 that prints as ASCII  Total characters: 43 (does not count any characters after #, which is the comment character) Contains Space: +1 Repeated alphanumerics: -18 for rr1008 Repeated punctuation: -24 for ()""""",,,,, Final score: 43+1-24-18 = 2 xy=STDOUT m="Hello, world!" print(xy,m);  Total visible characters: 37 Contains Newline: +1 Contains Space: +1 Repeated alphanumerics: -18 for xyllor Repeated punctuation: -4 for ", Repeated other ASCII: -4 for = Final score: 37+1+1-18-4-4 = 13 A couple of invalid pieces of code... x=2;print("Hello,world!")  Problem: x is assigned, but not used. print("Hello,"*" world!")  Problem: * is unnecessary, result will be the same without it. k=1 if k>0 print("Hello, world!") else print("abcghjmquvxyzABCDEFGIJKLMNOPQRSTUVWXYZ_+*-&|") end  Problem: The second print command will not run. Also, removing characters in quote in second print command will not change output. x="Hello, world!"; print(x)  Problem: removal of newline will not change result or cause error (in Julia, semicolon is only necessary if multiple commands are on the same line, otherwise just suppresses return value). print("Hellos\b, world!")  Problem: s character does not affect result, as it gets erased by \b. This is acceptable if done through code ("Hello",char(100),"\b, world!"), but cannot be done via string literals or character literals. Convenient score-calculator - http://jsfiddle.net/4t7qG/2/ - thanks to Doorknob • Seems awfully close to codegolf.stackexchange.com/questions/19477/… and codegolf.stackexchange.com/questions/18721/… – Kyle Kanos Jun 4 '14 at 17:08 • This seems relevant to your discussion meta.codegolf.stackexchange.com/questions/777/… – Martin Ender Jun 4 '14 at 17:28 • I created a JSFiddle where you can put your code and it will automatically figure out your score. Would you be okay with me editing a link to it it in to the post? – Doorknob Jun 4 '14 at 18:44 • @Dennis - if your program produces a newline because of the command, no problem (for instance, println in Julia prints and then adds a newline on the end). But it shouldn't be part of the string. – Glen O Jun 5 '14 at 3:41 • @ACarter - basically, yes. But the restrictions and the deductions make it non-trivial. – Glen O Jun 5 '14 at 11:56 ## 11 Answers # Perl - 96 (Pretty good, given the theoretical max 97 score) s{}[Hel0o, w3$=d!];y<"#%&'*.124578:?@BCDEFGIJKLMNOQ/-9>(
6PRSTUVWXYZ^_abfghjmqvxz|~\cAk-u)+print


(Note that second line starts with an actual \t tab character)

The code is 98 characters long and contains every ascii char exactly once, plus an extra -.
98 - 2 = 96

There are no string literals here, but removal of any single character breaks the program.

### Deobfuscation

There are 3 statements in this program (well, actually 2 but I abused + as some kind of statement separator)

1. s{}[Hel0o, w3$=d!] This is a very stretched case of the sed operator. It is more commonly written as s/a/b/, or s:a:b:, but perl allows much more fantasy here: s(a)(b) s(a)^b^ s(a)[b], and even s qaqbq. It replaces an empty string (inside {}) with Hel0o w360d! (inside []) ($= interpolates to 60 by default). Because of the lack of an ~= operator, it operates on $_. 2. y<"#%&'*.124578:?@BCDEFGIJKLMNOQ/-9>(\n\t6PRSTUVWXYZ^_abfghjmqvxz|~\cAk-u) This is also a very stretched case, but of a tr operator, which is also called y (y< >( )). Let's look at the replacement table: " # %&'*.124578:?@BCDEFGIJKLMNOQ /-9 \n\t6PRSTUVWXYZ^_abfghjmqvxz|~\cA k-u I have moved some characters around so that existing string is not broken. The only actually working part here is /-9 -> k-u. It replaces 0 with l, 3 with o, and 6 with r. Again because of lack of the ~= operator, it operates on $_
So now we have the complete phrase in the $_ variable. 3. print Lack of arguments makes it print just the $_ variable.

• I don't know Perl enough to comment on this - what is the set of characters between the < and + doing? – Glen O Jun 5 '14 at 3:42
• @GlenO Only /-9 and k-u are actually used to transform the string. The rest is an equally sized garbage. If you remove just one char, the sets will misalign and the program won't output "Hello, world!" anymore. – mniip Jun 5 '14 at 4:26
• In that case, in what way is the "garbage" being executed? That is, in what way is it functional? If it's just filler that gets jumped over by the code, then it's equivalent to non-running code within a conditional. – Glen O Jun 5 '14 at 4:32
• @GlenO It's not. To the spec: <...> removal of any single counting character must change the result or cause the code to not function. Removal of 1 character anywhere breaks it. You can make it work by removing 2 characters, but that's not in the rules. – mniip Jun 5 '14 at 4:43
• All code must be functional. You're clearly bending the rules, at the very least. I'm not saying "it breaks the rules" outright, but it's definitely questionable. – Glen O Jun 5 '14 at 5:19

This answer was created before adding of the rule about string literals and does not participate in the contest.

#include <iostream>
int main(){std::cout<<56+"  !$%^&*?12347890-_QWERTYUIOPASDFGJKLZXVBNM,.qypfghjk:zvbHel\x6Co, world!";}  It's completely legit. :P If you remove any character from that string, it will print ello, world!. • Please include the score of your code in your answer. – ProgramFOX Jun 4 '14 at 17:24 • Also it won't change your score, but the the spaces around << need to be removed. – Martin Ender Jun 4 '14 at 17:30 • Hmmm... while I do applaud your answer, it has primarily revealed a minor hole in my restrictions. I'm going to give you an upvote, and I'm happy for others to do the same if they like it, but I'll be editing in an additional restriction. – Glen O Jun 4 '14 at 17:30 • OK, further to my previous comment, I've now added a restriction stating that string and character literals must be relevant - replacement of characters within them must be able to change the result. This allows if 'x'>'w' techniques, but blocks "k\bH" to result in "H", for instance. Feel free to contribute a second answer following the added restriction. – Glen O Jun 4 '14 at 17:39 # CJam, 94 {'H"EJO, WoRLD!"el96A+c/~_-3=0$@}"#
&^<>|;:?.()[]\1aBCdfFgGhiIjkKmMnNpPqQrsStTuUvVwxXyYzZ"254b87%*


Try it online! Note that there should be a tabulator right before the linefeed. SE doesn't like tabulators, so you'll have to insert it manually.

• 100 characters long
• repeated alnum: -0 ()
• repeated punctuation: -6 (""")
• repeated other: -0 ()
• repeated whitespace: -0 ()

Total score: 94

I've used the following code to check that none of the characters inside the string can be removed:

"#
:A,,{_A\<A@)>+254b87%}%


It prints an array showing the number of times Hello, world! would get printed if the character corresponding to the index were removed.

• When I run it in your link, it produces "Hello, world!" six times in a row. Also, what is the string of characters doing? – Glen O Jun 5 '14 at 3:54
• I'm guessing the newline is the mistake - removing it makes it work. – Glen O Jun 5 '14 at 4:03
• Copy-paste issue. There should be a tabulator right before the LF. It looks like SE won't let me do that... The string is considered a base-254 number (254b). The final result modulus 7 should be 1, so the previous code block is executed once. I'll need a modulus to make each character necessary. – Dennis Jun 5 '14 at 4:04
• Well, after adding in the missing tab (which does "fix" the code), removing the Z, the T, or probably a few other characters doesn't change the result. – Glen O Jun 5 '14 at 4:09
• I had horribly misinterpreted a part of your question. It's fixed now. – Dennis Jun 5 '14 at 4:30

# Ruby, 28 41

Just to start off the answers with a solution in the spirit of the question:

print"He#{?l*2}o, "+'world!'if[$&(9<=>6)^7|~8-5/3.1%0x4]  Scoring (I think I got this right): • 57 characters long • repeated alnum: -12 (orli) • repeated punctuation: -4 ("') • repeated other: -0 • repeated whitespace: -0 • Looks fine to me, scoring-wise. No need to include penalties that don't apply, but no harm in including them. – Glen O Jun 4 '14 at 18:11 • The . in 3.1 can be removed without issue. As can the x in 0x4 or the - in 8-5. – user12166 Jun 4 '14 at 22:17 # PHP, 1 (yes, one point!) Using magic characters to generate a checksum, which in binary form matches "Hell", "o, w", "orld", and "! ". Usually I like to find loopholes, but this time I decided to play by the spirit and intent of the contest. Every character and its position is essential to the output. The only places you can substitute are variable names which are not literal values, the whitespace between php and foreach which PHP treats as equivalent, and use of ' vs " which PHP treats as similar. <?php foreach(array('_MC:~+V4@SbHR/l[J','dN#UB5!Rv^NG@D}','9gm6L&-kuD','8OM97g.q]XQ0')as$j)print(hash("crc32",$j,1))?>  FYI, these are some other magic strings and hashes of interest: E.D}S: Hell 9UDIRQ: Hell N\7&*%: orld UWX[E^O: orld mAHzDEb: ! uLJ7Ck&: Hell B+bG5mYJ: Hell :OvMzuOR: ! TgYR9g!6k: o, w NkFN!8mI: o, w N#VA\j~}J[: Hell vEl*]@0XQ5: o, w 9gm6L&-kuD: orld *}{Xg@HN\: ! Pj@Y44uA6YJ: Hell |7OX0VF8gv}: ! DLRJAjgMj}\: ! !0bT*D}O4Lw: orld YGN97^v7ZY: Hell ++~bL/kP:|]W: o, w 8OM97g.q]XQ0: ! l^m-DqZ^g[&+: ! Ewu]Rv~*DHQ7: Hell JIqjgF|S!\8l: Hell b4l!MEG7vTu6/: Hell +B:zEq*J\k-Cm: ! _}E7wZD76^Y9AU: orld q:Nq-~+_S7~N9Hz: !  • The code still functions if I remove the \t, \n, or the space. Not a PHP expert, but ; seems optional as well. – mniip Jun 5 '14 at 14:18 • @mniip - Edits made. I was not aware the semicolon was optional in some cases. – Yimin Rong Jun 5 '14 at 14:37 # Befunge-98, 97 points! "v!dlrow ,h B[CDEFGIJkLMNOPH$<QRSTUV@|5cg1fe':-%\64*ab+7_/89}{0  j2
WXYZK.=#>]
s()impq	n 3~
Atuxz&;y^ ?


Try it online!

The tab is between the q and the n.

Uses a similar trick to the previous Befunge answer to pad the lines with the leftover characters, but avoids using duplicate characters in the executing section. Removing any of the non-executing characters results in the executing parts being out of place, usually ending up in infinite loops or printing the wrong output.

### How It Works

Really, the only executing part looks like:

"v!dlrow ,h
k     H
$< @|5cg1fe':-%\64*ab+7 >] ^ ?  First it uses a wrapping string literal to add , world! to the stack. This avoids two "s. $<      @|5cg1fe':-%\64*ab+7


This adds Hello to the stack using a variety of methods to avoid duplicate characters. $ pops the excess space caused by the wrapping string literal. 7+ adds 7 to the h from the end of the string literal to create the o . ba*46\%: calculates 111, the ascii value of l and duplicates it. 'e adds e to the stack. f1g gets the character at 1,15 which is the H It then reuses the , in the string to print out the whole Hello, world!. The rest is just direction changes to navigate to the ending @. # PHP, 2257 Loophole: the backslash was omitted from the specifications and the score calculator! This code counts the number of occurrences of backslashes in each string and prints an ASCII equivalent. Replacing any backslash with another character, or deleting a backslash, either causes a parse error or changes the result. A neat feature about backslashes and PHP is that they need to be escaped, so that doubles the score automatically! You can re-double, triple, etc., the score by multiplying the number of backslashes, but didn't want to be greedy, and I think it might exceed the limits of what you can enter. <?php foreach(array('\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\','\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\','\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\','\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\','\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\','\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\','\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\','\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\','\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\','\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\','\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\','\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\','\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\')as$x)print(chr(substr_count($x,"\\")))?>  • It's clearly nothing more than a typo in the description, not a loophole. What's more, you knew that already. The description does explicitly say "other ASCII characters". By the time you read this, it'll have been edited to include it. – Glen O Jun 6 '14 at 15:23 • In particular, backslash was in the source of the question, but I hadn't realised that it had treated it as an escape sequence. – Glen O Jun 6 '14 at 15:24 • This isn't a change in rules, it's correcting a minor typo. The backslash was in the rules, it just wasn't displaying (to see this for yourself, click on the "edited" button, then click on "side-by-side markdown"). And the others aren't exploiting loopholes, they're exploiting features of their languages. – Glen O Jun 6 '14 at 17:05 # Befunge - 87 "dlrow ,olleH"bk, v !#$%&'()*+-./0123456789:;  <=>?ABCDEFGIJKLMNOPQRSTUVWXYZ[\]^_acfghijmnpqstuvxyz{|}~@


The first line is worth four points due to all the repetition, but there are no duplicated characters on the second line. The only string literal in this code is dlrow ,olleH, which gets reversed and printed as output. Removing any one character will disconnect the v at the end of the first line from the @ at the end of the second, causing the program to never terminate. If the v itself is removed, then the code will go in to an infinite loop printing the correct output.

# Ruby, 78

More rules abuse, I feel like, not sure exactly what the patch'd be. Takes a long string and checks the sum of the result, so any deletion or change will cause the program to fail. Could probably be optimized a little to remove duplication of some letters and get whitespace in there.

puts('Hello, world!')if%["\#\$&*+-/:;<>?@ABCDEFGIJKLMNOPQRSTUVWXYZ^_abcghjknqvxyz{|}~123].sum==4980

• The problem is, everything after and including the if can be removed. – seequ Jun 4 '14 at 20:58
• @TheRare - nothing wrong with that, so long as the if does actually function and the stuff after it still obeys the rules. – Glen O Jun 5 '14 at 11:58
• @GlenO But isn't it counted as "removable code"? Just puts('Hello, world!') would work. I think the rules need clarifying if this is legit. – seequ Jun 5 '14 at 12:53
• @TheRare - in hindsight, I probably should have used a sweeping "a subset of the code should not be capable of producing the same output", but I don't think I should continue to change the rules. As they stand, as long as the code is functional and non-arbitrary, and follows the other rules, it's legitimate. At the very least, this method of solution isn't achievable in most languages (the edit I did make closed a loophole that works in most languages). – Glen O Jun 5 '14 at 13:00
• @GlenO You're the judge. Just ask me to delete these comments if you feel they're unnecessary. – seequ Jun 5 '14 at 13:05

# Aceto, 3

Finally managed to get a positive score!

"Hello, "-J' sJ"world!"∑-JUJpn


Try it online!

• ∑ isn't in printing ASCII – L3viathan Feb 10 '18 at 18:33

# Acc!!, -138 (and yes that's negative 138)

While this may not exactly be the best score I've ever gotten in PPCG, I doubt it can get any higher than this in Acc!!

108
Write 72
Write 101
Count i while i-2 {
Write _
}
Write _+3
Write 44
Write 32
Write 119
Write 111
Write 114
Write _
Write 100
Write 33
`

Try it online!