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

58 Answers 58

13
\$\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\$
7
\$\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\$
1
  • \$\begingroup\$ This works after Python 3.5 only. \$\endgroup\$ Commented May 31, 2017 at 19:05
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\$
5
\$\begingroup\$

Japt, 14 bytes

Ho#_dÃf@bX ¥J

Try it online!

Saved 4 bytes thanks to Shaggy and obarakon

\$\endgroup\$
6
  • 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
    Commented May 31, 2017 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
    Commented May 31, 2017 at 15:18
  • 1
    \$\begingroup\$ Got it down to 14 bytes: ethproductions.github.io/japt/… \$\endgroup\$
    – Shaggy
    Commented May 31, 2017 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
    Commented May 31, 2017 at 15:33
  • 1
    \$\begingroup\$ A 10 byte version but unfortunately non-competing: ethproductions.github.io/japt/… \$\endgroup\$
    – Shaggy
    Commented May 31, 2017 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\$
1
  • \$\begingroup\$ Bottom looks more like an esolang \$\endgroup\$
    – user92753
    Commented Nov 19, 2020 at 16:49
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\$

Perl, 39 bytes

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

Run with perl -pe.

\$\endgroup\$
4
  • \$\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
    Commented Jun 1, 2017 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\$
    – Grimmy
    Commented Jun 1, 2017 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
    Commented Jun 2, 2017 at 0:23
  • 1
    \$\begingroup\$ Nice answer, good use of pack! You can save a few bytes utilising -a too: Try it online! \$\endgroup\$ Commented Sep 4, 2020 at 7:50
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\$
5
  • 1
    \$\begingroup\$ Should be Array(95) to include the missing ~ \$\endgroup\$
    – Malivil
    Commented May 31, 2017 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
    Commented May 31, 2017 at 15:24
  • \$\begingroup\$ Can't believe C# is shorter than JavaScript for this, especially as I have to include my usings. \$\endgroup\$ Commented May 31, 2017 at 15:53
  • 1
    \$\begingroup\$ @TheLethalCoder, String.fromCharCode is a git, that's why! :D \$\endgroup\$
    – Shaggy
    Commented May 31, 2017 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
    Commented May 31, 2017 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\$
4
  • 1
    \$\begingroup\$ @(s)setxor(' ':'~',s) saves 1 byte \$\endgroup\$
    – Luis Mendo
    Commented May 31, 2017 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
    Commented May 31, 2017 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
    Commented May 31, 2017 at 18:11
  • 1
    \$\begingroup\$ @LuisMendo Thanks, I agree because (Luis) said. \$\endgroup\$
    – rahnema1
    Commented May 31, 2017 at 18:16
3
\$\begingroup\$

APL, 13 bytes

⍞~⍨⎕UCS31+⍳95

Straightforward:

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

05AB1E, 4 bytes

žQsм

Try it online!

žQsм  # full program
   м  # remove...
  s   # implicit input...
   м  # from...
žQ    # all ASCII characters
      # implicit output
\$\endgroup\$
0
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\$
6
  • \$\begingroup\$ Maybe you should make a golf version of PHP :P \$\endgroup\$ Commented May 31, 2017 at 16:05
  • \$\begingroup\$ @CalculatorFeline I am sure that exists but it is not really good \$\endgroup\$ Commented May 31, 2017 at 16:10
  • \$\begingroup\$ Maybe you should make a good one. Step 1: automatic starting tag. \$\endgroup\$ Commented May 31, 2017 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\$ Commented May 31, 2017 at 16:31
  • 2
    \$\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
    Commented Jun 2, 2017 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\$
1
  • \$\begingroup\$ Just as a note, - works instead of ^. \$\endgroup\$ Commented May 31, 2017 at 15:20
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\$
4
  • \$\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\$
    – Kaia Leahy
    Commented May 31, 2017 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\$ Commented May 31, 2017 at 18:54
  • \$\begingroup\$ @sethrin With a stabby lambda wouldn't it be 20 chars? ->(s){[*' '..?~]-s)} \$\endgroup\$ Commented May 31, 2017 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\$
    – Kaia Leahy
    Commented May 31, 2017 at 21:27
2
\$\begingroup\$

Julia, 21 bytes

s->setdiff(' ':'~',s)
\$\endgroup\$
1
  • \$\begingroup\$ TIO link for this solution \$\endgroup\$ Commented Jun 28, 2023 at 14:05
2
\$\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\$
1
  • \$\begingroup\$ No you didn't miss anything. \$\endgroup\$ Commented May 31, 2017 at 14:43
2
\$\begingroup\$

Pip, 5 bytes

PADCa

Removes all chacracters in the input from a predefined variable.

Try it online!

Pip, 9 bytes

PARM(X^a)

Converts the characters of the input to regex, and removes the characters from the printable ASCII builtin.

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ DC is your friend for this challenge. ;) \$\endgroup\$
    – DLosc
    Commented Sep 5, 2020 at 20:21
  • 1
    \$\begingroup\$ What a perfect builtin. \$\endgroup\$
    – Razetime
    Commented Sep 6, 2020 at 12:30
2
+100
\$\begingroup\$

APL (Dyalog Extended), 14 10 bytes

⍞~⍨' '…'~'

Try it online!

-4 bytes from Adám!(inclusive range)

Explanation

   ' '…'~'     range of chars in visible ASCII range
  ⍨            flip the arguments of the function on the left
⍞~             Get all characters not in input 
\$\endgroup\$
2
  • \$\begingroup\$ Fixed the mistake.. \$\endgroup\$
    – Razetime
    Commented Sep 4, 2020 at 7:49
  • \$\begingroup\$ -4: ⍞~⍨' '…'~' \$\endgroup\$
    – Adám
    Commented Nov 17, 2020 at 6:03
2
\$\begingroup\$

Pyth, 7 6 bytes

.-srd\
-srd\

.- - Subtract the second string from the first:

  1. srd\ Create a range from space char to the delete char
  2. implicitly read input

Try it online!

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

MUMPS, 35 bytes

r r,! f i=32:1:126 w:r'[$c(i) $c(i)

Explanation

  • Assign input to r and write a newline (!)
  • Loop from 32 to 126 and if r doesn't contain ('[) the character representation of the ASCII value ($char(), can be shortened to $c()), write the that character representation.
  • You can attach conditionals to commands with a colon. So w:1>0 "True" is the same as if 1>0 write "True"

Try the code here

\$\endgroup\$
2
  • \$\begingroup\$ Nice answer & nice explanation. Is there an online interpreter for MUMPS and can you post a link to it so we can play with the code? \$\endgroup\$ Commented Nov 20, 2020 at 8:44
  • \$\begingroup\$ Thanks! I added a link to tio.run. You can change the code / inputs to explore \$\endgroup\$ Commented Nov 20, 2020 at 11:47
2
\$\begingroup\$

PowerShell Core, 39 32 bytes

$a=$args
' '..'~'|?{$_-cnotin$a}

Added splatting and case sensitivity

Try it online!

Inspired by colsw's answer

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

Thunno 2, 3 bytes

kcḍ

Attempt This Online!

Explanation

kcḍ  # Implicit input
  ḍ  # Symmetric set difference with...
kc   # ...all printable ASCII characters
     # Implicit output
\$\endgroup\$
2
\$\begingroup\$

Factor, 26 25 bytes

-1 byte by using from math.unicode instead of diff, as suggested by @chunes

[ 32 126 [a,b] swap ∖ ]

Try it online!

TIO uses an old build of Factor; on the latest version, [a,b] from math.ranges has moved to [a..b] from ranges.

Explanation

Code Explanation Stack
[ ... ] Quotation (anonymous function) "Hello!"
32 126 [a,b] Inclusive range from 32 to 126 "Hello!" T{ range f 32 95 1 }
swap Swap so range is below input T{ range f 32 95 1 } "Hello!"
Set difference " \"#$%&'()*+,-./012..."

This works because in Factor, a string is basically a list of codepoints, and all sequences are sets.

\$\endgroup\$
1
  • \$\begingroup\$ -1 \$\endgroup\$
    – chunes
    Commented Jun 28, 2023 at 17:57
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\$
2
  • \$\begingroup\$ I have left no more playground \$\endgroup\$ Commented May 31, 2017 at 16:23
  • \$\begingroup\$ @JörgHülsermann You do. You just have to share it. \$\endgroup\$
    – Titus
    Commented Jun 1, 2017 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\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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