17
\$\begingroup\$

Simple challenge inspired by the popularity of my previous print invisible text and print real invisible text challenges, and the same length different string challenge.

Given a string consisting of only printable characters (0x20 to 0x7E), print every printable character not present in the string.

Input

A string, or array of characters, consisting of only printable ASCII characters

Output

Every printable ASCII character not present in the input string, in any order.

Testcases

Input:  "Hello, World!"
Output: ""#$%&'()*+-./0123456789:;<=>?@ABCDEFGIJKLMNOPQRSTUVXYZ[\]^_`abcfghijkmnpqstuvwxyz{|}~"
========
Input:  "Hi!"
Output: " "#$%&'()*+,-./0123456789:;<=>?@ABCDEFGIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghjklmnopqrstuvwxyz{|}~"
========
Input:  ""
Output: " !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
========
Input:  " !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
Output: ""

Scoring

This is code-golf so fewest bytes in each language wins

\$\endgroup\$
  • \$\begingroup\$ If returning an array, can we include empty elements in place of the used characters? \$\endgroup\$ – Shaggy May 31 '17 at 14:34
  • \$\begingroup\$ @Shaggy sure, that's fine \$\endgroup\$ – Skidsdev May 31 '17 at 14:37
  • \$\begingroup\$ @Rod don't leak my plans D: \$\endgroup\$ – Skidsdev May 31 '17 at 14:54
  • \$\begingroup\$ Can the output be a Set object of strings of the characters? set( 'a', 'b', 'c' ) \$\endgroup\$ – Brad Gilbert b2gills May 31 '17 at 14:55
  • 1
    \$\begingroup\$ @MikhailV only if your language is unable to output ASCII characters \$\endgroup\$ – Skidsdev Jun 1 '17 at 7:46

42 Answers 42

11
\$\begingroup\$

GS2, 2 bytes

ç7

Try it online!

How it works

    (implicit) Push the sting of all characters in STDIN on the stack.
ç   Push the string of all printable ASCII characters.
 7  Perform symmetric set difference.
    (implicit) Print the result to STDOUT.
\$\endgroup\$
6
\$\begingroup\$

Perl 6, 29 bytes

{[~] keys (' '..'~')∖.comb}

Note that the result is random because Sets are unordered.

Test it

Expanded:

{
  [~]        # reduce using string concatenation
             # (shorter than 「join '',」)

  keys       # get the keys from the Set object resulting from the following

  (' '..'~') # Range of printable characters
  ∖          # Set minus (this is not \ )
  .comb      # split the input into individual characters
}

There is also an ASCII version of (-), but it would require a space before it so that it isn't parsed as a subroutine call.

\$\endgroup\$
6
\$\begingroup\$

Python 3.5, 39 bytes

lambda n:{*map(chr,range(32,127))}-{*n}

Try it online!
Turns input into a set, and remove it from the set containing all ascii characters

\$\endgroup\$
  • \$\begingroup\$ This works after Python 3.5 only. \$\endgroup\$ – Gábor Fekete May 31 '17 at 19:05
5
\$\begingroup\$

Japt, 14 bytes

Ho#_dÃf@bX ¥J

Try it online!

Saved 4 bytes thanks to Shaggy and obarakon

\$\endgroup\$
  • 1
    \$\begingroup\$ No need for the flag (see answer to my comment on the question). Replace 127 with # to save a byte and remove the U to save another. \$\endgroup\$ – Shaggy May 31 '17 at 15:15
  • 1
    \$\begingroup\$ You can use ¦ and rearrange your arguments to save a few bytes. Also, 127 can be shortened TIO \$\endgroup\$ – Oliver May 31 '17 at 15:18
  • 1
    \$\begingroup\$ Got it down to 14 bytes: ethproductions.github.io/japt/… \$\endgroup\$ – Shaggy May 31 '17 at 15:26
  • 1
    \$\begingroup\$ No, you work away with it, Tom - as you said before, I need to learn to post quicker! :D \$\endgroup\$ – Shaggy May 31 '17 at 15:33
  • 1
    \$\begingroup\$ A 10 byte version but unfortunately non-competing: ethproductions.github.io/japt/… \$\endgroup\$ – Shaggy May 31 '17 at 16:27
4
\$\begingroup\$

Haskell, 32 bytes

f x=[y|y<-[' '..'~'],all(/=y)x] 

Try it online!

Boring library function for set difference:

Haskell, 31 bytes

import Data.List
([' '..'~']\\)
\$\endgroup\$
4
\$\begingroup\$

MATL, 5 bytes

6Y2X~

Try it online!

Thanks to Luis Mendo for golfing 8 bytes off!

Explanation:

   X~   % The symmetric set difference
6Y2     % Between all printable ASCII
        % And the input string (implicit)
        % Implicitly display

Symmetric set difference will give every element that is present in exactly one of the two input sets. (but not both) This will always give the right answer, since the input set will always be a subset of the second set (all printable ASCII).

Original version:

32:126tGom~)c

Explanation:

32:126          % Push the range 32-126
      t         % Duplicate it on the stack
       G        % Push the input
        o       % Convert it to character points
         m      % Is member (0 for each char that isn't in input, 1 for each char that is)
          ~     % Logical NOT
           )    % Take the truthy elements of this array from the previous array (All Printable ASCII)
            c   % Display as a string
\$\endgroup\$
3
\$\begingroup\$

Brachylog, 5 bytes

ẹ;Ṭ↔x

Try it online!

Explanation

ẹ          Split the input string into a list of chars
 ;Ṭ↔x      Exterminate the chars from the string Ṭ of printable ASCII chars
\$\endgroup\$
3
\$\begingroup\$

JavaScript (ES6), 74 bytes

I'm sure there's a shorter way to do this!

s=>[...Array(95)].map((_,y)=>s.includes(c=String.fromCharCode(y+32))?"":c)

Try it

let f=
s=>[...Array(95)].map((_,y)=>s.includes(c=String.fromCharCode(y+32))?"":c)
oninput=_=>o.innerText=f(i.value).join``
o.innerText=f(i.value="Hello, World!").join``
<input id=i><pre id=o>

\$\endgroup\$
  • 1
    \$\begingroup\$ Should be Array(95) to include the missing ~ \$\endgroup\$ – Malivil May 31 '17 at 15:15
  • \$\begingroup\$ Was that always there, @Malivil? Could've sworn the last character was } when I wrote this up. Fixed now, thanks. \$\endgroup\$ – Shaggy May 31 '17 at 15:24
  • \$\begingroup\$ Can't believe C# is shorter than JavaScript for this, especially as I have to include my usings. \$\endgroup\$ – TheLethalCoder May 31 '17 at 15:53
  • 1
    \$\begingroup\$ @TheLethalCoder, String.fromCharCode is a git, that's why! :D \$\endgroup\$ – Shaggy May 31 '17 at 15:56
  • \$\begingroup\$ @Shaggy I dunno, I just was looking at your code to see how it worked and I typed literally every symbol on my keyboard and noticed ~ didn't change anything but that it was in the spec. Also, the "Try It" part needs to be updated. \$\endgroup\$ – Malivil May 31 '17 at 16:13
3
\$\begingroup\$

Bash, 47 43 40 bytes

printf %x {32..126}|xxd -r -p|tr -d "$1"

Try it online!

Generates hexa range, inverts hex dump to char an removes characters present in first parameter.

\$\endgroup\$
3
\$\begingroup\$

Octave, 22 20 bytes

Thanks to @Luis Mendo saved 2 bytes.

@(s)setxor(32:'~',s)

Try it online!

Other answer:

@(s)setdiff(' ':'~',s)

Try it online!

\$\endgroup\$
  • 1
    \$\begingroup\$ @(s)setxor(' ':'~',s) saves 1 byte \$\endgroup\$ – Luis Mendo May 31 '17 at 17:58
  • \$\begingroup\$ @LuisMendo Very nice! But I think that is a different thing. I suggest that you post it as a new answer :) \$\endgroup\$ – rahnema1 May 31 '17 at 18:09
  • 1
    \$\begingroup\$ No, it's really just a minor improvement. I'll be happy that you post it if you want. BTW @(s)setxor(32:'~',s) seems to work too --- and same comment for that :-) \$\endgroup\$ – Luis Mendo May 31 '17 at 18:11
  • 1
    \$\begingroup\$ @LuisMendo Thanks, I agree because (Luis) said. \$\endgroup\$ – rahnema1 May 31 '17 at 18:16
2
\$\begingroup\$

PHP, 42 Bytes

Input as array

Output as string

<?=join(array_diff(range(" ","~"),$_GET));

Try it online!

PHP, 53 Bytes

Input as string

Output as string

<?=join(array_diff(range(" ","~"),str_split($argn)));

replace <?=join with print_r for an output as array

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Maybe you should make a golf version of PHP :P \$\endgroup\$ – CalculatorFeline May 31 '17 at 16:05
  • \$\begingroup\$ @CalculatorFeline I am sure that exists but it is not really good \$\endgroup\$ – Jörg Hülsermann May 31 '17 at 16:10
  • \$\begingroup\$ Maybe you should make a good one. Step 1: automatic starting tag. \$\endgroup\$ – CalculatorFeline May 31 '17 at 16:12
  • \$\begingroup\$ @CalculatorFeline I have search the link for you. github.com/barkermn01/PGP-php-CodeGolf I have no interest to make one \$\endgroup\$ – Jörg Hülsermann May 31 '17 at 16:31
  • 1
    \$\begingroup\$ @CalculatorFeline Making PHP a golfing language destroys what is the fun in golfing with PHP (at least for me): you have to constantly balance between calling functions (which often have long names), using loops, different input methods and so on. Step 1: automatic starting tag well php -r ... but e.g. in this example it doesn't pay of because echo is longer than <?=. \$\endgroup\$ – Christoph Jun 2 '17 at 14:12
2
\$\begingroup\$

CJam, 8 bytes

'␡,32>q^

Where is a literal delete character.

Try it online!

'␡,       e# The range of all characters up to ~.
   32>    e# Slice it to be the range of all characters from space to ~.
      q^  e# Symmetric set difference with the input.
\$\endgroup\$
  • \$\begingroup\$ Just as a note, - works instead of ^. \$\endgroup\$ – Esolanging Fruit May 31 '17 at 15:20
2
\$\begingroup\$

Perl, 39 bytes

s!.*!"pack(c95,32..126)=~y/$_//dr"!ee

Run with perl -pe.

\$\endgroup\$
  • \$\begingroup\$ I get the error message 'Bareword found where operator expected at (eval 1) line 2, near "y/Hello World!//dr"' when I run this... \$\endgroup\$ – Chris Jun 1 '17 at 15:19
  • \$\begingroup\$ Full command-line: echo 'Hello World!' | perl -pe 's!.*!"pack(c95,32..126)=~y/$_//dr"!ee'. This works for me on both Perl v5.14 and v5.24. \$\endgroup\$ – Grimy Jun 1 '17 at 18:56
  • \$\begingroup\$ It's Perl v5.10 that's not working... Must be a change made between 5.10 and 5.14. \$\endgroup\$ – Chris Jun 2 '17 at 0:23
2
\$\begingroup\$

brainfuck, 120 bytes

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

Try it online!

Wrapped:

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

Explained:

+[+[>+<+<]>]>-         initialize what we will now consider cell 0 to 95
[[>>]+[<<]>>-]         initialize cells 2 4 etc 95*2 to 1; end on cell 0 at 0
,[                     main input loop (for each char of input)
  <+++++[>------<-]>-  subtract 31 from the input
  [>[>>]+[<<]>-]       lay a trail of (input minus 31) ones in the empty spaces
  >[>>]<[-]<[-<<]>     use the trail to clear the appropriate "print" flag
,]                     keep reading input until it ends
++++++++[->++++<]>     initialize the cell directly before flag 1 to 32
[                      we'll let the accumulator overflow; no harm done
  >[-<.>]              print the accumulator if the flag is still set
  <[->>+<<]>>+         shift over the accumulator and increment it
]
\$\endgroup\$
2
\$\begingroup\$

Ohm, 3 bytes

α@─

Try it online!

Note: you can also enter your input as a string (example), but it fails for the empty input case.

\$\endgroup\$
2
\$\begingroup\$

Ruby, 23 18 17 bytes

->s{[*' '..?~]-s}

Uses a lambda function as per @sethrin's comments.

Previous versions:

[*' '..?~]-s.chars

(' '..'~').to_a-s.chars
\$\endgroup\$
  • \$\begingroup\$ Doesn't s have to be either read from STDIN or supplied as a function argument? The challenge also specifies that the input may be given as an array of characters. Converting to a stabby lambda and dropping chars gives a 16-byte solution. \$\endgroup\$ – sethrin May 31 '17 at 17:30
  • \$\begingroup\$ I wasn't really sure how the input was to be addressed, given that it wasn't explicitly specified. There are a few other answers that assume the existence of the input in a variable. Is there a codegolf convention? I don't do this much. \$\endgroup\$ – Mark Thomas May 31 '17 at 18:54
  • \$\begingroup\$ @sethrin With a stabby lambda wouldn't it be 20 chars? ->(s){[*' '..?~]-s)} \$\endgroup\$ – Mark Thomas May 31 '17 at 18:58
  • \$\begingroup\$ All of the parentheses in your lambda are optional. But I may have miscounted a byte. Other languages either accept input implicitly or have stdin bound to a global variable. In Ruby $< is a shortcut for stdin but lambdas tend to be shorter. The conventions on input and output are here. I also don't do this much, so if the rules aren't what I think do let me know. \$\endgroup\$ – sethrin May 31 '17 at 21:27
2
\$\begingroup\$

APL, 13 bytes

⍞~⍨⎕UCS31+⍳95

Straightforward:

       31+⍳95  ⍝ A vector 32 .. 126
   ⎕UCS        ⍝ as characters
 ~⍨            ⍝ without
⍞              ⍝ those read from character input.
\$\endgroup\$
1
\$\begingroup\$

R, 50 bytes

function(s)intToUtf8(setdiff(32:126,utf8ToInt(s)))

returns an anonymous function. Converts the input string to integers, computes the set difference between the printable range and the input values, and then converts them back to a string and returns it.

Try it online!

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

PHP, 53 bytes

for($k=31;$k++<126;)~strstr($argn,$k)?:print chr($k);
# or
for($k=31;$k++<126;)echo~strstr($argn,$k)?"":chr($k);

Run as pipe with -r.

\$\endgroup\$
  • \$\begingroup\$ I have left no more playground \$\endgroup\$ – Jörg Hülsermann May 31 '17 at 16:23
  • \$\begingroup\$ @JörgHülsermann You do. You just have to share it. \$\endgroup\$ – Titus Jun 1 '17 at 11:35
1
\$\begingroup\$

C#, 74 71 bytes

using System.Linq;s=>new int[95].Select((n,i)=>(char)(i+32)).Except(s);

Old version with creating a range for 74 bytes:

using System.Linq;s=>Enumerable.Range(32,95).Select(n=>(char)n).Except(s);
\$\endgroup\$
1
\$\begingroup\$

05AB1E, 5 4 bytes

-1 thanks to Emigna

žQsK

Try it online!

žQ   # Push all printable characters
  s  # Swap input to the top
   K # Push a with no b's (remove input characters from all printable character)
\$\endgroup\$
  • \$\begingroup\$ @FrodCube Oops... I forgot to update the link. It should work now. TIO (empty input) \$\endgroup\$ – Riley May 31 '17 at 16:43
1
\$\begingroup\$

V, 20 bytes

òiÎflax
òcH ¬ ~@"<

Try it online!

Hexdump:

00000000: f269 ce66 1b6c 6178 0af2 6348 20ac 207e  .i.f.lax..cH . ~
00000010: 1b40 223c                                .@"<
\$\endgroup\$
1
\$\begingroup\$

C (gcc), 75 72 70 68 50 bytes

i;f(s){for(i=31;++i<127;strchr(s,i)?:putchar(i));}

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Can you use || to make this work on "standard" C? \$\endgroup\$ – Neil Jun 1 '17 at 8:58
  • \$\begingroup\$ @Neil Yes || also works. Isn't ?: part of "standard" C? \$\endgroup\$ – cleblanc Jun 1 '17 at 13:13
  • \$\begingroup\$ I always thought it was a gcc extension. \$\endgroup\$ – Neil Jun 1 '17 at 13:16
  • \$\begingroup\$ @Neil That's correct. ?: is a GNU extension. It works as well in clang and tcc though. \$\endgroup\$ – Dennis Jun 1 '17 at 16:16
1
\$\begingroup\$

Jelly, 8 bytes

Really, 8 bytes? Please, tell me I missed something!

32r126Ọḟ

Try it online!

How?

32r126Ọḟ - Main link: list of characters s
32r126   - inclusive range from 32 to 126 = [32,33,...,125,126]
      Ọ  - cast ordinals to characters = list of printable characters
       ḟ - filter discard if in s

Alternatively

“ ~‘r/Ọḟ - Main link
“ ~‘     - code-page indexes = [32,126]
    r/   - reduce by inclusive range = [32,33,...,125,126]
      Ọ  - cast from ordinals to characters = list of printable characters
       ḟ - filter discard if in s

Since this challenge a new atom which yields all printable ASCII characters, ØṖ, has been introduced making the following work for 3 bytes:

ØṖḟ
\$\endgroup\$
  • \$\begingroup\$ No you didn't miss anything. \$\endgroup\$ – Erik the Outgolfer May 31 '17 at 14:43
1
\$\begingroup\$

Charcoal, 18 15 10 8 bytes

Fγ¿¬№θιι

Try it online! Link is to verbose version of code. Edit: Saved 3 bytes by ranging over characters instead of integers. Saved a further 5 bytes when I discovered the undocumented γ variable which holds the printable ASCII characters. Saved a further 2 bytes when @ASCII-only fixed predefined inputs in verbose mode (the answer is still valid as it stands, it's only the try it online link that wouldn't have worked at the time).

\$\endgroup\$
  • \$\begingroup\$ 8 bytes (unless preinitialized inputs weren't working back then) \$\endgroup\$ – ASCII-only Jun 17 '17 at 7:47
  • \$\begingroup\$ @ASCII-only They weren't working in verbose mode... they would probably have worked in succinct mode, but I like the verbose links. \$\endgroup\$ – Neil Jun 17 '17 at 10:36
0
\$\begingroup\$

Mathematica, 35 bytes

20~CharacterRange~126~Complement~#&

Anonymous function. Takes a list of characters as input and returns a list of characters as output.

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

Lua, 78 bytes

s=io.read()for i=32,126 do c=string.char(i)io.write(s:find(c,1,1)and""or c)end
\$\endgroup\$
0
\$\begingroup\$

shortC, 33 bytes

i;AOi=31;++i<'~';strchr(*@,i)?:Pi

Conversions made in this program:

  • A -> int main(int argc, char **argv) {
  • O -> for(
  • @ -> argv
  • P -> putchar
  • Auto-inserted closing ));}

The resulting program looks like:

i;int main(int argc, char **argv){for(i=31;++i<'~';strchr(*argv,i)?:putchar(i));}

Try it online!

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

Pyth, 17 bytes

Vr32 127I!}CNzpCN

The naive approach.

Explanation:

Vr32 127I!}CNzpCN
Vr32 127             For N in [32, 127[
           CN        Get the ASCII character for the code N
        I!}  z       If it is in the input string...
              pCN    ...then print it

Test it online!

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

Clojure, 60 or 49 bytes

#(apply str(sort(apply disj(set(map char(range 32 127)))%)))

These "apply"s are killing me :/ Oh, if returning a list is fine then this is a bit shorter.

#(sort(apply disj(set(map char(range 32 127)))%))
\$\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.