221
\$\begingroup\$

Your task is to build a program (using only printable ASCII characters and/or tabs and newlines) that prints out exactly the characters in the printable ASCII space (0x20 to 0x7e) that don't appear in your program's source code (in any order, however many times you want).

The shortest code to do this in any language wins.

\$\endgroup\$
  • 19
    \$\begingroup\$ They are, but they're not in the range 0x20 to 0x7e, which are defined as the "printable ASCII characters". Technically tabs and newlines are actually control characters. \$\endgroup\$ – Joe Z. Aug 23 '13 at 19:22
  • 3
    \$\begingroup\$ Are we allowed to print newlines (or any other unprintable ASCII characters)? \$\endgroup\$ – flornquake Aug 24 '13 at 0:30
  • 1
    \$\begingroup\$ Tabs and newlines do not render in such a way that they occupy a printing position. They move the position. See the ANSI C "isprint" function. \$\endgroup\$ – Kaz Aug 24 '13 at 2:00
  • 1
    \$\begingroup\$ How did this question get revived? It's started getting upvotes again. \$\endgroup\$ – Joe Z. Jan 31 '14 at 16:38
  • 3
    \$\begingroup\$ @Timwi: If you wanted to do that, you'd have to output all the characters in the CJK character space too (excluding the ones appearing in your code). It's too complicated to manage, so I restricted it to just ASCII. \$\endgroup\$ – Joe Z. Feb 1 '14 at 3:01

106 Answers 106

1
\$\begingroup\$

Javascript/coffeescript/actionscript/more, 96

// #qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890~`!@$%^&*()-_=+[{]}\|;:'",<.>?


Other languages it works in are basically anything with // comments (and doesn't need something like class a{public static void main(String[]a){) This also works in Perl 5 (Thanks @BradGilbertb2gills for pointing that out!)

\$\endgroup\$
  • \$\begingroup\$ I was just about to comment that this would work in almost any language... \$\endgroup\$ – Sparr Nov 18 '15 at 23:47
  • \$\begingroup\$ # qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890~`!@/$%^&*()-_=+[{]}\|;:'",<.>? Python - 95 bytes EDIT: Damn code blocks \$\endgroup\$ – DJgamer98 Nov 19 '15 at 14:59
  • \$\begingroup\$ If you placed the # character before qwerty then it will also work in Perl 5. \$\endgroup\$ – Brad Gilbert b2gills Nov 29 '15 at 19:16
  • \$\begingroup\$ @BradGilbertb2gills cool! \$\endgroup\$ – ev3commander Nov 29 '15 at 21:17
  • \$\begingroup\$ Perl 5 will either see // as a null regex, or a defined-or operator. (say undef // 1) I'm not sure which. ( If it is the latter, it may only work on 5.10 or newer ) \$\endgroup\$ – Brad Gilbert b2gills Nov 29 '15 at 21:41
1
\$\begingroup\$

Lua, 94 bytes

f="l=...for i=32,126 do c=string.char(i)io.write(l:find(c,0,1)and\"\"or c)end"loadstring(f)(f)

Writes the algorithm in a string and uses loadstring to run it as a function passing in its string definition as the argument.

\$\endgroup\$
  • \$\begingroup\$ Hello, and welcome to Programming Puzzles and Code Golf! Great answer! \$\endgroup\$ – NoOneIsHere May 10 '16 at 23:25
1
\$\begingroup\$

Smalltalk - 47

^#DI,($ to:$~)difference:thisContext sourceCode

This works in Squeak 6.x and produces the String:

'!"%&''*+-./0123456789;<=>?@ABEFGHJKLMNOPQRSTUVWXYZ[\]_`abgjklmpqvwyz{|}'
  • ($ to:$~) forms a left String ranging the 95 characters
  • thisContext sourceCode produces a decompileString of the snippet
  • difference: reject all the caracters from the left String that appears in the decompileString.
  • #DI, which concatenates a Symbol with letters D and I to left String is here to make those 2 letters appear in code.
    It is necessary because the decompileString prefixes the snippet with DoIt ^ which is the name of the pseudo-method. Those letters will thus be removed.
    Same for the leading ^ that indicates to return the result, it is in the decompileString so has to be in the code even if optional
    Letters o and t are already in source code, so it's OK.
  • 'DI', would work but result string is printed with quotes ' so source must not have quotes
  • "DI" would be even shorter, unfortunately decompileString remove comments
  • We could eliminate method name with ($ to:$~)difference:(thisContext sourceCode last:52) but it is longer (52)

The code consumes 25 different characters, and thus produces 70 different characters (among 73, quote ' appearing 3 more times for printing the String)

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

RProgN 2, 24 bytes

{`{.` `~Rx={x\-`x=};x.}{

Try it online!

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

brainfuck, 126 bytes

The polyglot that lists all the printable ASCII characters and prints nothing is shorter, but this uses only valid brainfuck commands and prints the rest.

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

Try it online!

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

J, 24 bytes

Another J solution in 24 characters:

'''{a.239-'-.~93{.32}.a.
  • a. is the alphabet, this is, character 0 to 255 where some characters are replaced with box-drawing characters.
  • 32}.a. drops the first 32 characters of a. (the box-drawing and control characters)
  • 93{.32}.a. takes the first 93 characters of what remains. That is, ASCII characters 32 to 126. We don't take the tilde ~ or the closing curly brace } because they are part of the program.
  • '''{a.239-'-.~94{.32}.a. removes the set of the characters '{.a239- (the remaining ASCII characters that are part of the program) from the character set generated in the previous step, yielding all ASCII characters that are not part of this program.
\$\endgroup\$
1
\$\begingroup\$

A Pear Tree, 86 bytes

`~1!2@3#4$5%6^7&8*9(0)-_=+[]{}\|;':",./<>?bcfhjklmnoqsuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ

It appears the only error message is "a partridge".

Try it online!

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

Flipbit, 369 bytes

^>>>>>.^.^<^>.^.^<^<^>>.^.^<^>.^.^<^<^<^>>>.^.^<^>.^.^<^<^>>.^.<^>.>^<[^<]^>>>>.^.^<^>.^.^<^<^>>.^.^<^>.^.^<^<^<^>>>.^.^<^>.^.<^<^>>.<^>.<<<<^>^>^>^>^>.^.<^>.^.^<^<^>>.^.^<^>.^.^<^<^<^>>>.^.^<^>.^.^<^<^>>.^.^<^>.^.<<<<^>>>>.<^>.^.<<^>^>^.^.<^>.^.<<<^>>>.^.<^>.^.<<^>^>.<^>.^.<^>.<<^<<^<^>>>>>.^.<^>.^.<<^>>.^.<^>.^.^<<^<^>>>.^.<^>.^.<<^>>.^.<^>.^.<^>[^<].<<<<^>>>^.<^>.

Try it online!

Assumes that the output can contain characters outside the ASCII range, so here is a hexdump:

00000000: 2021 2223 2425 2627 2829 2a2b 2c2d 2f30   !"#$%&'()*+,-/0
00000010: 3132 3334 3536 3738 393a 3b3d 3f41 4042  123456789:;=?A@B
00000020: 4344 4546 4748 494a 4b4c 4d4e 4f5f 5d5c  CDEFGHIJKLMNO_]\
00000030: 5b5a 5859 5150 5253 5557 5654 6061 6362  [ZXYQPRSUWVT`acb
00000040: 6667 6564 6968 6a6b 6f6e 6c6d 7071 7273  fgedihjkonlmpqrs
00000050: 7475 7677 7879 7a7b 7d7f c0c1 c3c2 c5c4  tuvwxyz{}.......
00000060: c7c6 c9c8 cbca cdcc cfce dedc ddda dbd9  ................
00000070: d8d0 d1d3 d2d4 d6d7 d5e1 e0e2 e3e7 e6e4  ................
00000080: e5e8 e9eb eaee efed ec7e 7c              .........~|

Don't you dare ask me how it works. As this (ab)used a bug which has no been fixed, test with this commit.

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

Perl 5, 66 bytes

$s=q{$_=chr,"\$s=q{$s};eval\$s"!~/\Q$_/&&print for 32..126};eval$s

Try it online!

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

Stax, 12 bytes

Vp.."-"Vp-"-

Run and debug online!

Added for completeness, feel free to mark it as non-competing if necessary.

Vp in Stax is the set of all printable ASCII characters, .." is the two character string literal (of .") in Stax.

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

Japt, 20 bytes

#[o_d#$ k"[o_d$k1!"1

Try it online!

How it works

#[o_d#$ k"[o_d$k1!"1

#[o                   Map range(91) with...
   _d#$                 Apply chr(n+36)...
        k"[o_d$k1!"     and remove these chars from it...
                   1    in case sensitive mode.
                      Implicit output (result is Array; comma-joined)

Dealing with the quotes turned out to be nasty, so I reduced the range to start at $ (36) instead of (32).

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

PHP, 70 bytes

for($c=31;++$c<127;)count_chars(file(__FILE__)[0])[$c]||print chr($c);

PHP, 80 bytes

<?=join(array_diff(range(" ","~"),str_split(count_chars(file(__FILE__)[0],3))));

Try them online.

Require PHP 5.4 or later (released 2012-03-01) for indexing the function result.

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

Ruby, 46, 37

puts (?!..?~).to_a-IO.read($0).chars

Creates a range of characters from ! to ~, reads the current file and subtracts the characters in the current file from the range, then prints them all out.

Inspiration from prior Ruby post of Doorknob.

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

PHP, 80

Compliant with current rules, I think, no loopholes anyway

<?=join(array_diff(range(' ','~'),str_split(' \'(),;<=?\_acdefghijlnoprsty~')));

Just gets the difference between the full set and the chars I used.

Self Tests like this, if first and second line of output match, the first line is a valid solution

<?=join(array_diff(range(' ','~'),str_split(' \'(),;<=?\_acdefghijlnoprsty~')));

$used = count_chars(file(__FILE__)[0],3);
$ascii = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
$unused = str_replace(str_split($used), '', $ascii);

echo "\n".$unused;
echo "\n".$used;
echo "\n";
\$\endgroup\$
  • \$\begingroup\$ does neither use nor print the space character (0x20), but can be fixed without adding bytes. \$\endgroup\$ – Titus May 17 '18 at 16:36
  • \$\begingroup\$ Good catch. Replacing ! with ` ` seems to resolve it. \$\endgroup\$ – Umbrella May 18 '18 at 13:24
1
\$\begingroup\$

T-SQL, 79 bytes:

PRint upper('abcdefghijlkmnoqstuvwxyz')--!"#$%&*+,./0123456789:;<=>?@[\]^_`{|}~

Kinda cheaty, everything after -- is a comment.

Less cheaty, much longer (143 bytes):

WITH UX AS(SELECT 33D union ALL SELECT D+1FROM UX WHERE D<126)
select CHAR(D)from UX where charindex(char(D),'acdefhilmnorstuwx()+<,''=01236')=0

Must be run on a case-insensitive database. This uses a recursive number table to generate values from 33 to 126, and displays the CHAR() of each, excluding any that are in a string (that simply re-lists all characters used elsewhere in the code).

SQL keywords are not case-sensitive, so I vary the case to cover both upper and lower of each letter used. CHARINDEX on a case-insensitive database then excludes both the upper and lower of each in the string, saving me some characters.

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

Python 3, 65

print(''.join(set(map(chr,range(32,127)))-set(open('q').read())))

Name the file 'q'. Run with python3 q. If 'q' is an unacceptable filename the file can be named '.py' for an additional 2 characters.

\$\endgroup\$
  • \$\begingroup\$ reading own source code is boring. \$\endgroup\$ – qwr Jun 20 '18 at 4:30
1
\$\begingroup\$

Ruby, 46 bytes

$><<([*?%...?~]-"#%><chars.[*?!-]()".chars)*""

Try it online!

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

Powershell, 60 bytes

Inspired by Iszi's answer. See also AdmBorkBork's answer with another approach.

$t=gc(gv My* -v|% I*e)|% t*y
[char[]](32..126)|?{$_-notin$t}

where:

  • gv My* -v is alias and shortcut for Get-Variable MyInvocation -Value.
  • |% I*e is shortcut for |% InvocationName.
  • |% t*y is shortcut for |% ToCharArray.
  • and first line means: store to the variable $t a char array that is read from a file with a name that is taken from the properties of the current script.
\$\endgroup\$
1
\$\begingroup\$

Japt, 13 bytes

Bah! Stoopid k and its stoopid case-insensitivity costing me 2 bytes!

;EkQ+"+QkE;"E

Try it

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

Perl 6, 59 56 bytes

say [~] keys (" ".."~") (-)"say o(\\\".~)-cmbkey[]".comb

Try it online!

\$\endgroup\$
  • \$\begingroup\$ you didn't update the TIO link \$\endgroup\$ – ASCII-only Apr 15 '19 at 1:12
  • \$\begingroup\$ Updated the link, thanks \$\endgroup\$ – bb94 Apr 15 '19 at 2:18
1
\$\begingroup\$

Clam, 14 bytes

pE'a-"pE'a-\""

Just performs a diff between all printable ASCII character and the few unique chars in this program.

Explanation

pE'a-"pE'a-\""
p              - Print...
  'a-          -   Printable ASCII range
 E             -   That isn't found in...
     "pE'a-\"" -   The characters used in this program
\$\endgroup\$
  • \$\begingroup\$ Hm, does this remove \ from the printable ASCII character set? \$\endgroup\$ – Erik the Outgolfer May 3 '19 at 20:41
1
\$\begingroup\$

VTL-2, 194 bytes

33 ~=#-1
51 ~=~+1
53 #=51*((~=35)+(~=(35+1))+(~=(35+5))+(~=(35+5+1))+(~=(35+5+1+1))
55 #=51*((~=(35+5+3))+(~=(35+5+5))+(~=(51-1-1))+(~=51)+(~=53)
111 #=51*(55+5+1=~
113 $=~
115 #=51*(1-(~=(115+5+5

Prints !"%&',./0246789:;<>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}. It's about double the length of the comment approach, but much more interesting. I had to use some digits, and restricting it to 1, 3, and 5 seemed to work the best... though I haven't proven this. Line-by-line explanation:

33: Assigns the variable ~ to the current line number (#) less 1. Originally I was going to use ! and be able to start printing from 34 on, but... ! is a system variable.

51: Increments the value in ~

53, 55, 111: These all basically say IF ~ == 35 OR ~ == 36 OR ~ == 40 [...] GOTO 51. VTL relies heavily on system variables. # is the line number variable - as in line 33, we can pull the value of the current line number, but if we assign a value to #, it's a GOTO. The initial #= is this assignment, everything else is evaluation. Any given ~=35 type evaluation returns one for true (equality) or zero otherwise. We do as many of these as fit in a line (72 characters), sum them, and multiply this by our target line number. If any of those evaluations were true, we end up with #=51; if not, we end up with #=0, essentially a NOP.

113: Output character corresponding to code point.

115: Same sort of GOTO construction as above, except we're looping back IF ~ != 125. So, first we have to see if ~ does equal 125, then subtract that from 1 to make it a NOT.

Keeping in mind the line length restrictions, the lazy commented version comes in at 93 bytes:

12340 )"#$%&'(*+,-./:;<=>?ABCDEFGHIJKLMNOPQRSTU!
56789 )VWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~@

...although I can't actually enter this because the @ chokes it. And now I know why: "At any time before hitting Return, the entire line may be erased by typing the At-signcharacter ‘@’ (Shift-P or “Cancel” on some terminals.)". So the non-printing commented version is purely theoretical, and some code would have to be written to at least print the @... which would mean code to print the characters used in that code, etc...

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

Perl 6, 43 bytes

<say |keys (" "..<~>) (-).comb#EVAL>~~.EVAL

Try it online!

Uses the standard Perl6 quine format.

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

JavaScript: (96 bytes long, prints nothing, throws an error)

 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~

or

Valid JavaScript (97 bytes long, prints nothing)

' !"#$%&()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~'
\$\endgroup\$
0
\$\begingroup\$

F# - 66

Set.iter(printf"%c")(set[' '..'~']-set"Set.ir(pnf\"%c)s[' ~]-\\")
\$\endgroup\$
0
\$\begingroup\$

Javascript 94

a="",r="for(v=32;v<128;)c=String.fromCharCode(v++),a+=r.indexOf(c)<0?c:\"\"; alert(a)";eval(r)
\$\endgroup\$
0
\$\begingroup\$

PHP (110 characters)

<?php
$w=file_get_contents(__FILE__);
$i=32;
while ($i++<126)
echo(strpos($w,chr($i))===false)?chr($i):'';
\$\endgroup\$
0
\$\begingroup\$

Ruby, 43 characters

$><<([*' '..?~]-open($0).read.split(''))*''

Output:

!"#%&+,/123456789:;=@ABCDEFGHIJKLMNOPQRSTUVWXYZ\^_`bcfghjkmquvwxyz{|}
\$\endgroup\$
0
\$\begingroup\$

k4 (31)

-1 x@&~(x:"c"$32+!95)in*0:.z.f;

save in a file, name doesn't matter (except that the extension has to be .k), and run with q.

$ q aq.k 2>/dev/null
#%',/4678<=>?ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abdeghjklmopqrstuvwy{|}

works by getting the name of current script file, reading it, removing its contents from the list of all printable ascii, and printing what's left.

if we dispense with the trailing newline in the printout, we can save one character (the - at the beginning of the code)

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

PHP - 99 Characters

echo implode('',array_diff(array_map('chr',range(33,126)),str_split(file_get_contents(__FILE__))));
\$\endgroup\$

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.