Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Input

A string that contains at most one of each of the letters A, B, and C. They may be in any order. The empty string is valid input.

Note: A previous version of this challenge used the letters LEJ instead of ABC and they may still be used if desired.

Output

A string of the A, B, C letters that were not present in the input. They may be in any order.

If the output would be the empty string then simply giving no output is valid, if that makes sense for your implementation. (e.g. you don't need to actually call print on an empty string.)

Examples

  • If the input is B then the output should either be CA or AC since A and C are not present in the input.
  • If the input is the empty string then the output should be ABC or any permutation since none of the three letters are present in the input.
  • If the input is CAB then the output should be the empty string because all three letters are present in the input.

Test Cases

There are so few input cases that we can enumerate all of them:

in -> out1 | out2 | out3 | ...
ABC -> ""
ACB -> ""
BCA -> ""
BAC -> ""
CAB -> ""
CBA -> ""
AB -> C
AC -> B
BC -> A
BA -> C
CA -> B
CB -> A
A -> BC | CB
B -> CA | AC
C -> AB | BA
"" -> ABC | ACB | BCA | BAC | CAB | CBA

All valid outputs for each input are given, separated by |'s. "" represents the empty string

Scoring

The shortest code in bytes wins. But keep in mind that you may get more recognition for solving the challenge in a unique way rather than in a short way ;)

share|improve this question
    
Is a list of characters acceptable for output, or must it be a string? – Mego 18 hours ago
    
@Mego It must be a string (or be displayed as a string by default). – Helka Homba 18 hours ago
1  
Cumbersome I/O format – Mego 18 hours ago
1  
The task is set difference between a constant and an input. Requiring that everything be done in strings is cumbersome with regards to the difficulty of the actual task. – Mego 18 hours ago
2  
I vaguely remember a more exact dupe match where you had to subtract the input from a constant set. – xnor 18 hours ago

34 Answers 34

Python 3, 29 27 22 bytes

lambda x:{*"ABC"}-{*x}

-2 bytes thanks to Jonathan Allan

-5 bytes thanks to Rod

share|improve this answer
    
print(*{*"LEJ"}-{*input()}) saves 2. (tested on 3.5 and 3.6). – Jonathan Allan 18 hours ago
    
10  
I love python ❤️ – theonlygusti 12 hours ago

05AB1E, 6 bytes

…LEJI-

Try it online! or as a Test suite

Note that the empty string as input does not work on TIO but it does in the offline interpreter.

share|improve this answer
    
Shouldn't an input of only J return EL, LE? – carusocomputing 12 hours ago
2  
Nice! Just as an FYI, inputs can also be represented as """{input}""", which also works for empty strings :). – Adnan 11 hours ago
    
@carusocomputing: It can return either (in this case it returns LE). – Emigna 11 hours ago
    
@Adnan: Good point. Never used the triple-string input except with multiline input. Will have to remember that :) – Emigna 11 hours ago
    
I find it hard to believe there isn't a built in to push ABC that is less than 4 bytes. •CÞ•h is 5... 2ÝAè is lowercase and still 4... – carusocomputing 9 hours ago

Actually, 7 bytes

"LEJ"-Σ

Try it online!

"LEJ"-Σ
"LEJ"    the letters
     -   exclude letters present in input
      Σ  concatenate
share|improve this answer

Retina, 14 bytes

Byte count assumes ISO 8859-1 encoding.

$
¶ABC
D`.
A1`

Try it online!

Explanation

$
¶ABC

Append a second line containing ABC.

D`.

Deduplicate the characters. This deletes every character from the second line which already appears in the first line.

A1`

Discard the first line.

share|improve this answer
    
How exactly does the 1` part of the antigrep stage work? – Kritixi Lithos 12 hours ago
    
@KritixiLithos Numbers in the configuration string are limits. 1 generally means "only do X once". How exactly limits work (i.e. what X is) depends on the stage type you're using. For antigrep stages, Retina first checks which lines match the regex (here, every line, since the regex is empty), but then the limit means "only discard the first matching line". Similarly, if it was a grep stage it would mean "only keep the first matching line". The semantics of all limits are listed on the wiki. – Martin Ender 12 hours ago

Pyth, 5 bytes

-"ABC

Test it here

Expands to

-"ABC"Q
-       # Filter on absence
 "ABC"  # Literal string 
      Q # Input
share|improve this answer
    
abc can be written as <G3 – Maltysen 4 hours ago
    
@Maltysen yeah muddyfish used that, but it is lowercase anyway =\ – Rod 16 mins ago

Java 7, 73 58 bytes

String c(String s){return"EJL".replaceAll("[ "+s+"]","");}

15 bytes saved thanks to @KritixiLithos.

Test code:

Try it here.

class M{
  static String c(String s){return"EJL".replaceAll("[ "+s+"]","");}

  public static void main(final String[] a) {
    System.out.print("LEJ=" + c("LEJ") + "; ");
    System.out.print("LJE=" + c("LJE") + "; ");
    System.out.print("EJL=" + c("EJL") + "; ");
    System.out.print("ELJ=" + c("ELJ") + "; ");
    System.out.print("JLE=" + c("JLE") + "; ");
    System.out.print("JEL=" + c("JEL") + "; ");
    System.out.print("LE=" + c("LE") + "; ");
    System.out.print("LJ=" + c("LJ") + "; ");
    System.out.print("EJ=" + c("EJ") + "; ");
    System.out.print("EL=" + c("EL") + "; ");
    System.out.print("JL=" + c("JL") + "; ");
    System.out.print("JE=" + c("JE") + "; ");
    System.out.print("L=" + c("L") + "; ");
    System.out.print("E=" + c("E") + "; ");
    System.out.print("J=" + c("J") + "; ");
    System.out.print("\"\"=" + c(""));
  }
}

Output:

LEJ=; LJE=; EJL=; ELJ=; JLE=; JEL=; LE=J; LJ=E; EJ=L; EL=J; JL=E; JE=L; L=EJ; E=JL; J=EL; ""=EJL
share|improve this answer
1  
Can you do "["+s+"]" instead of s.replaceAll("(.)","$1|")? – Kritixi Lithos 18 hours ago
    
@KritixiLithos Smart. It fails for the empty String, but by adding a space (or any other character that isn't EJL) it works again, which is still a lot shorter. :) – Kevin Cruijssen 18 hours ago

MATL, 10 8 bytes

Saved two bytes thanks to Suever. setdiff is shorter than ismember.

'ABC'iX-

Try it here!

Explanation

'ABC'      % Create a string literal
     i     % User input
      X-   % Set difference, between two elements of the stack 

Yes, this might have been a trivial task, but I'm quite satisfied I managed to solve it with MATL all by myself. I never said it was the shortest solution... Thanks Suever!

share|improve this answer

Jelly, 4 bytes

Thanks to @DuctrTape for the prod about the change and the presence of "ABC" in Jelly's dictionary.

“ḃ»ḟ

Try it online!

“ḃ» looks up the entry "ABC" in Jelly's dictionary, is the filer discard dyad which discards the characters found in the input from that list of characters. The result is implicitly printed.


For a lower case version the dictionary entry to use can be either of "abac" (“c») or "abaca" (“i»).


When the challenge was "LEJ" only 6 bytes could be achieved in the upper case variant, since no dictionary entries exist with that set of characters, leaving us to create the list of characters “LEJ” (or a permutation thereof).

The lowercase variant faired better at 5 bytes due to the presence of the word "jell" (“ẎṄ»).

share|improve this answer

Bash + coreutils, 15 bytes

tr -d x$1<<<LEJ

Try it online!

I'd like to omit the x, but then tr -d would be missing an argument when the input string was empty. (The x doesn't do any harm, since there aren't any x's in the here-string LEJ.) I'd normally write tr -d "$1", but doing it the way I did is one byte shorter than that.

share|improve this answer
    
I had the same thoughts - even with the quotes - immediately, too. – rexkogitans 11 hours ago

V, 10 bytes

CLEJ<ESC>Ó[<C-r>"]

Try it online!

Hexdump:

00000000: 434c 454a 1bd3 5b12 225d                 CLEJ..[."]

Explanation

Input is on the first line of the buffer. So something like:

EL

and the cursor is on the first character. So we delete the input (which stores it in register ") and enter insert mode simultaneously using C.

Once in insert mode, the characters LEJ are inserted, after which I return to normal mode using <ESC>.

Now we have to remove all the characters that are present in the input.

Ó                       " remove every
 [<C-r>"]               "  character that appears in the input
                        " synonym of Vim's :s/[<C-r>"]//g

And once this happens, we are left with the remaining letters in the buffer.

share|improve this answer

JavaScript ES6, 41 39 Bytes

s=>"ABC".split(RegExp(`[${s}]`)).join``

Saved 2 bytes thanks to Arnauld.

f=s=>"ABC".split(RegExp(`[${s}]`)).join``

console.log(f("AB"));

share|improve this answer
    
I'm on mobile, so I can't test my code, but this should work I think: s=>eval`'ABC'.replace(/[${s}]/g,'')` – LarsW 4 hours ago

Carrot, 15 bytes, non-competing

non-competing because of a bug I found with returning matches and empty strings. So I just fixed it

ABC^//[^#]/gS""

Try it online! (copy & paste)

Explanation

ABC^                   //sets stack (just a string, not an array) to "ABC"
    /                  //return match(es) of:
     /[^#]/g           // `#` is the placeholder for the input
                       // so effectively, this returns the matches of any character not present in the input
                       // applied on the stack
                       //this returns an array of all the matches of the regex
            S""        //join all the elements of the array using "", the empty string
share|improve this answer

CJam, 7 bytes

"ABC"l-

Try it online! (As a linefeed-separated test suite.)

share|improve this answer

Ruby, 27 19 18 bytes

->s{"ABC".tr s,""}

-1 byte thanks to Martin Ender

share|improve this answer

Octave, 29 27 bytes

Saved two bytes thanks to Suever, by creating the string 'ABC', inside the ismember call.

@(s)x(~ismember(x='ABC',s))

We use ~ismember() as logical indices to the variable x. The peculiar thing is, we create x='ABC' inside ismember, not in front of it. The order Octave sees this:

@(s)                        % Anonymous function that takes a string s as input
                x='ABC'     % Create a variable x with the characters 'ABC'
       ismember(x='ABC',s)  % True for elements that are in both x and s. False otherwise.
      ~ismember(x='ABC',s)  % Negate this, so that we keep the characters that aren't in s
@(s)x(~ismember(x='ABC',s)) % Use the logical vector as indices to x and return the result
share|improve this answer

Haskell, 27 26 bytes

import Data.List
("ABC"\\)

Try it online! Usage: ("ABC"\\) "CB" yields "A".

\\ is the set difference operator, the parenthesis form a so called section which is a short form for the lamda (\x -> "ABC" \\ x).


Without import: (same byte count thanks to @nimi)

f x=[c|c<-"ABC",all(/=c)x]

Try it online! Usage: f "CB" yields "A".


Other approaches:

f x=filter(`notElem`x)"ABC"
(`filter`"ABC").flip notElem
f x=[c|c<-"ABC",notElem c x]
share|improve this answer
    
I hope (\\) will be moved to Prelude soon. – theonlygusti 12 hours ago
    
@theonlygusti I hope it won't; this isn't really a sensible operation for lists (at least not unless you explicitly state you want list-as-set). The default operation for that task should be Data.Set.difference. – ceased to turn counterclockwis 10 hours ago
    
@ceasedtoturncounterclockwis why is it not sensible? Besides, the only reason I desire it moved is because it is useful, frequently. – theonlygusti 9 hours ago
    
@theonlygusti it's not sensible in the sense that if you find yourself using it, it's a sign that you're probably using the wrong data structure. Lists can have duplicate elements, an order, and they may be lazily constructed (even infinite). (\\) respects none of this. Data types that are intended for this behaviour have a structure that makes them generally quite a bit more effecient, safer (because no possible stability etc. assumptions can be broken) and exposing a more comfortable interface. – ceased to turn counterclockwis 9 hours ago
1  
@Laikoni: I think the import should be counted as 17 bytes, so that there's no difference compared to using it in source code where you need either a NL or ; as a separator. If declaring "plus the 16-byte import" would be fine, we could use it also for other things to save the NL/;, like "plus the 9-byte definition of r=reverse". BTW: f x=[c|c<-"ABC",all(/=c)x]. – nimi 8 hours ago

Mathematica, 37 bytes

Complement@@Characters@{"ABC",#}<>""&
share|improve this answer
    
Is there a reason you used strings here rather than lists of characters? – Greg Martin 8 hours ago
    
@GregMartin habit, I guess – Martin Ender 8 hours ago
    
just that I think it comes out shorter if you can avoid Characters – Greg Martin 8 hours ago

APL, 7 bytes

'ABC'∘~

~ is set subtraction, is compose, so this is a function that returns ABC minus the characters in its input.

share|improve this answer

Jellyfish, 9 bytes

PNI
 "ABC

Try it online!

In more conventional notation, this program translates to:

P(N("ABC", I))

I is the input, N is list difference, and P is output.

share|improve this answer

Perl 5.9.9 79 38 37 35 bytes

perl -le '$_="ABC";eval"y/$ARGV[0]//d";print'

(not sure of the counting rules here - have included switches but not the perl command).

> perl -le '$_="ABC";eval"y/$ARGV[0]//d";print' AB
C
> perl -le '$_="ABC";eval"y/$ARGV[0]//d";print'
ABC

(adjusted counts after adjudication comment below)

share|improve this answer
    
Will that work for empty input? – Titus 13 hours ago
    
Now I fixed the transcription error (had "..", typed {,,} here...) – Tom Tanner 12 hours ago
    
Your code is 35 bytes long. (34 +1 for the -l flag). :) – Paul Picard 12 hours ago
    
Thanks. The -l is for prettification (as in a newline at the end of the output.). wasn't sure if that was necessary from the contest rules. – Tom Tanner 12 hours ago
    
With 5.14+, you can do perl -pe'$_=eval"ABC=~y/$_//dr"' for only 23 bytes (22 + 1 for -p). – ThisSuitIsBlackNot 6 hours ago

MATLAB / Octave, 20 bytes

@(x)setdiff('ABC',x)

Online Demo

share|improve this answer

Common Lisp, 71 bytes

The largest entry at the moment, but at least it is readable ;-)

(lambda(s)(coerce(set-difference'(#\A #\B #\C)(coerce s'list))'string))
share|improve this answer

Japt, 13 12 bytes

"ABC"r"[{U}]

Saved a byte thanks to ETHproductions.

Try it online!

share|improve this answer
    
Nice, thanks for using Japt! You can remove the trailing quote to save a byte. – ETHproductions 12 hours ago

Brain-Flak, 120 + 3 = 123 bytes

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

It is run with the -c flag, adding 3 bytes

Try it online!

Explanation coming soon...

share|improve this answer

C, 53 bytes

b=64;c(char*a){while(b<67)putchar(++b*!strchr(a,b));}

If implicit declarations of string.h are not allowed, 72 bytes, to add #include<string.h>

Try it online!


or something a bit more fun at 75 bytes

a[128]={};b=64;c(char*d){while(*d)++a[*d++];while(b<67)putchar(b*!a[++b]);}

Try it online!

share|improve this answer

GNU sed, 34 29 bytes

Includes +1 for -r

-5 thanks to Digital Trauma

s/^/ABC/
:
s/(.)(.*)\1/\2/
t

Try it online!

For some reason TIO doesn't work with extended regex (-r), so I had to wrap it in BASH.


s/^/ABC/        # put ABC at the beginning of the string
:               # nameless label
s/(.)(.*)\1/\2/ # remove a duplicate letter
t               # branch to the nameless label if something changed
share|improve this answer
    
The newline, -n and P are unnecessary. Also you can wrap this up in bash to get it to work in TIO. No idea why -r doesn't work. tio.run/nexus/bash#DcmxDYAwDATA/qdIR4JELCjp7F8jooIFCPubb@/… – Digital Trauma 7 hours ago
    
@DigitalTrauma Thanks! I was thinking there would be characters besides A, B, and C when I wrote this. – Riley 7 hours ago

Lua, 41 bytes

print((('LEJ'):gsub('['..(...)..']',''))
share|improve this answer

PHP, 43 bytes

all regex approaches will fail if empty input is not treated separately, so ...

<?=str_replace(str_split($argv[1]),"",ABC);
  • str_split splits input to array of single characters
  • str_replace replaces all occurences of each array element in ABC with the empty string
share|improve this answer

Befunge, 40 39 bytes

~2p~2vv:<_>"C"-#v_@
8p2~p<>,0^g2::+1<*8

Try it online!

share|improve this answer

VB.Net, 65 bytes

Sub F(s)
Console.Write(String.Join("","ABC".Except(s)))
End Sub

A subroutine (function) that takes the input string, and removes each character present in the input from the string "ABC". Then it joins the resulting characters back into a string, before printing them to the console.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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