215
\$\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\$
  • 18
    \$\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

103 Answers 103

0
\$\begingroup\$

QBIC, 61 bytes

[32,126|B=chr$(a)~instr(A,B)|\?B}##$(),1236=?ABB[\achinrst|}~

Are we allowing new languages on old challenges yet?

Explanation

[32,126|      FOR a = 32 TO 126
B=chr$(a)       Set B$ to the char code a
~instr(A,B)   IF A$ contains B$
|             THEN do nothing
\?B}          ELSE print B$
#             Define a literal A$ that has every char in this program once.
 #$(),1236=?ABB[\achinrst|}~

Usually, QBIC would delimit a literal with a backtck ('`'), so that's the one char we can't have in a literal. However, the backtick is auto-added on open literals at EOF.

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

PHP, 81 bytes

<?php $w=file(__FILE__)[0];foreach(range(' ','')as$i){echo!strpos($w,$i)?$i:'';}

Shortest by-the-book PHP submission so far, built upon @michal.hubczyk 's answer with a few golf twists. Interestingly enough, adding the <?php prolog saves some bytes off the whole solution, thanks to the use of file()[0] modern php array-dereferencing on the one-liner file instead of the classic file_get_contents().

Try it online!

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

Brain-Flak, 155 bytes

Includes +1 for -A

((((((()()()()){}){}){})<>[()()()])[()])((((()()()){})){}{})<>((()()()()){}){({}[()]<(({})())>)}{}({}()())<>{{({}<>[()]<(({})())><>)}{}<>(({}())()())<>}<>

Try it online!

# Push 32 on this stack and 18, 28 and 29 to the other
# 18, 28 and 29 are the distances between the sets of braces 
((((((()()()()){}){}){})<>[()()()])[()])((((()()()){})){}{})<>

# For 0 to 8
((()()()()){}){({}[()]<

    # Push TOS, TOS + 1
    (({})())

# end For 0 to 8
>)}{}

# Push TOS + 2 
# skips '(' and ')'
({}()())

# For each value on the off stack (18, 28, 28)
<>{

    # For 0 to that number
    {({}<>[()]<

        # Push TOS, TOS + 1
        (({})())

    # End for 0 to that number
    ><>)}{}

    # Push TOS + 1, TOS + 3 (skips this set of braces)
    <>(({}())()())<>

# End for each value on the off stack (18, 28, 28)
}<>
\$\endgroup\$
0
\$\begingroup\$

MATLAB/Octave, 45 44 41 bytes

setdiff([33:126 ''],'setdif([3:126''],)')

Try it online!

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

SmileBASIC, 78 63 bytes

FOR I=32TO 126?CHR$(I)*(INSTR(LOAD("TXT:_",0),CHR$(I))<0);
NEXT

Assumes the program is saved in a file named _ (which sounds like cheating to me but apparently this is ok)

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

JavaScript, 96

eval(l="for(e=32,x='';e<127;e++)v=eval('\"\\\\x'+e.toString(16)+'\"'),x+=-1==l.indexOf(v)?v:''")
\$\endgroup\$
0
\$\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
0
\$\begingroup\$

Ruby, 46 bytes

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

Try it online!

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

Japt, 13 bytes

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

;EkQ+"+QkE;"E

Try it

\$\endgroup\$
0
\$\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 at 1:12
  • \$\begingroup\$ Updated the link, thanks \$\endgroup\$ – bb94 Apr 15 at 2:18
0
\$\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 at 20:41
0
\$\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\$
-2
\$\begingroup\$

Groovy: 52 chars

print(((' '..'~')-new File('a').text.grep()).join())

// print all characters from '#' to '~', except those present in the file itself (the name of the source file is 'a').

\$\endgroup\$
  • \$\begingroup\$ Why the downvote ? \$\endgroup\$ – Stéphane Gourichon Mar 19 '15 at 19:38
  • 1
    \$\begingroup\$ @StéphaneGourichon because it's assuming that file a has all the missing characters in it. This solution exploits a common loophole, and is therefore invalid. \$\endgroup\$ – Magic Octopus Urn Aug 3 '17 at 14:52
  • \$\begingroup\$ @Magic Octopus Urn - No. The file 'a' is the name of the program itself. The program simply reads itself, and then removes all the characters it contains from the specified range of characters. \$\endgroup\$ – br2000 Aug 10 '17 at 11:41

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.