28
\$\begingroup\$

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 ;)

\$\endgroup\$
16
  • 1
    \$\begingroup\$ Cumbersome I/O format \$\endgroup\$
    – user45941
    Feb 16, 2017 at 8:02
  • 1
    \$\begingroup\$ 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. \$\endgroup\$
    – user45941
    Feb 16, 2017 at 8:09
  • 2
    \$\begingroup\$ I vaguely remember a more exact dupe match where you had to subtract the input from a constant set. \$\endgroup\$
    – xnor
    Feb 16, 2017 at 8:26
  • 1
    \$\begingroup\$ Can inputs contain letters outside of "ABC"? The specification: "A string that contains at most one of each of the letters A, B, and C" does not exclude such inputs. \$\endgroup\$
    – minseong
    Feb 16, 2017 at 13:56
  • 1
    \$\begingroup\$ @theonlygusti The input should only contain ABC \$\endgroup\$ Feb 16, 2017 at 22:09

51 Answers 51

20
\$\begingroup\$

Python 3, 29 27 22 bytes

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

-2 bytes thanks to Jonathan Allan

-5 bytes thanks to Rod

\$\endgroup\$
5
  • \$\begingroup\$ print(*{*"LEJ"}-{*input()}) saves 2. (tested on 3.5 and 3.6). \$\endgroup\$ Feb 16, 2017 at 8:12
  • \$\begingroup\$ You can also turn into a lambda for -5 bytes \$\endgroup\$
    – Rod
    Feb 16, 2017 at 10:06
  • 15
    \$\begingroup\$ I love python ❤️ \$\endgroup\$
    – minseong
    Feb 16, 2017 at 14:18
  • \$\begingroup\$ @theonlygusti Whatever happened to <3 and ♥? \$\endgroup\$
    – wizzwizz4
    Feb 17, 2017 at 11:14
  • \$\begingroup\$ @theonlygusti : I would love python if I can replace lamda with 𝛌 \$\endgroup\$ Feb 22, 2017 at 5:50
10
\$\begingroup\$

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" (“ẎṄ»).

\$\endgroup\$
1
  • 1
    \$\begingroup\$ I like how most of the code just generates the string "ABC", and the actual program itself is one character. Classic jelly. \$\endgroup\$
    – sagiksp
    Feb 19, 2017 at 12:10
6
\$\begingroup\$

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.

\$\endgroup\$
1
  • \$\begingroup\$ I had the same thoughts - even with the quotes - immediately, too. \$\endgroup\$ Feb 16, 2017 at 15:11
6
\$\begingroup\$

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.

\$\endgroup\$
2
  • \$\begingroup\$ How exactly does the 1` part of the antigrep stage work? \$\endgroup\$
    – user41805
    Feb 16, 2017 at 14:35
  • \$\begingroup\$ @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. \$\endgroup\$ Feb 16, 2017 at 14:38
6
\$\begingroup\$

05AB1E, 6 4 bytes

Saved 2 bytes using the new žR command as suggested by Kevin Cruijssen

žRsм

Try it online! or as a Test Suite

Explanation

   м  # remove the character of
  s   # the input
žR    # from the string "ABC"
\$\endgroup\$
9
  • \$\begingroup\$ Shouldn't an input of only J return EL, LE? \$\endgroup\$ Feb 16, 2017 at 14:44
  • 2
    \$\begingroup\$ Nice! Just as an FYI, inputs can also be represented as """{input}""", which also works for empty strings :). \$\endgroup\$
    – Adnan
    Feb 16, 2017 at 14:56
  • \$\begingroup\$ @carusocomputing: It can return either (in this case it returns LE). \$\endgroup\$
    – Emigna
    Feb 16, 2017 at 14:59
  • 1
    \$\begingroup\$ Can be 4 bytes now \$\endgroup\$ Mar 26, 2019 at 14:55
  • 1
    \$\begingroup\$ @Emigna Tbh no. I think it was added because of this challenge perhaps, but I personally haven't used it before. \$\endgroup\$ Mar 26, 2019 at 15:12
5
\$\begingroup\$

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
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Can you do "["+s+"]" instead of s.replaceAll("(.)","$1|")? \$\endgroup\$
    – user41805
    Feb 16, 2017 at 7:55
  • \$\begingroup\$ @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. :) \$\endgroup\$ Feb 16, 2017 at 7:59
5
\$\begingroup\$

Actually, 7 bytes

"LEJ"-Σ

Try it online!

"LEJ"-Σ
"LEJ"    the letters
     -   exclude letters present in input
      Σ  concatenate
\$\endgroup\$
5
\$\begingroup\$

Pyth, 5 bytes

-"ABC

Test it here

Expands to

-"ABC"Q
-       # Filter on absence
 "ABC"  # Literal string 
      Q # Input
\$\endgroup\$
2
  • \$\begingroup\$ abc can be written as <G3 \$\endgroup\$
    – Maltysen
    Feb 16, 2017 at 22:25
  • \$\begingroup\$ @Maltysen yeah muddyfish used that, but it is lowercase anyway =\ \$\endgroup\$
    – Rod
    Feb 17, 2017 at 2:34
4
\$\begingroup\$

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!

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

JavaScript ES6, 41 39 38 Bytes

s=>eval(`'ABC'.replace(/[${s}]/g,'')`)

Saved 2 bytes thanks to Arnauld. Saved 1 bytes thanks to LarsW.

f=s=>eval(`'ABC'.replace(/[${s}]/g,'')`)

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

\$\endgroup\$
3
  • \$\begingroup\$ I'm on mobile, so I can't test my code, but this should work I think: s=>eval`'ABC'.replace(/[${s}]/g,'')` \$\endgroup\$
    – LarsW
    Feb 16, 2017 at 22:08
  • \$\begingroup\$ Nice work! Being able to say .join`` saves you two characters over the solution I had come up with: f=s=>"ABC".replace(RegExp(`[${s}]`,'g'),"") . \$\endgroup\$
    – nnnnnn
    Feb 17, 2017 at 6:11
  • 1
    \$\begingroup\$ @LarsW That exact code didn't seem to work, but adding brackets around the template string did and saved one byte. Thanks! \$\endgroup\$
    – Tom
    Feb 17, 2017 at 7:53
3
\$\begingroup\$

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.

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

Ruby, 27 19 18 bytes

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

-1 byte thanks to Martin Ender

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

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]
\$\endgroup\$
5
  • 1
    \$\begingroup\$ I hope (\\) will be moved to Prelude soon. \$\endgroup\$
    – minseong
    Feb 16, 2017 at 14:25
  • \$\begingroup\$ @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. \$\endgroup\$ Feb 16, 2017 at 16:39
  • \$\begingroup\$ @ceasedtoturncounterclockwis why is it not sensible? Besides, the only reason I desire it moved is because it is useful, frequently. \$\endgroup\$
    – minseong
    Feb 16, 2017 at 16:58
  • 1
    \$\begingroup\$ @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. \$\endgroup\$ Feb 16, 2017 at 17:05
  • \$\begingroup\$ @ceasedtoturncounterclockwis what, yes it does. "The first instance of..." but nvm \$\endgroup\$
    – minseong
    Feb 16, 2017 at 17:35
3
\$\begingroup\$

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
\$\endgroup\$
2
  • \$\begingroup\$ 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@/… \$\endgroup\$ Feb 16, 2017 at 18:55
  • \$\begingroup\$ @DigitalTrauma Thanks! I was thinking there would be characters besides A, B, and C when I wrote this. \$\endgroup\$
    – Riley
    Feb 16, 2017 at 18:59
3
\$\begingroup\$

Brain-Flak, 120 + 3 = 123 bytes

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

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

Try it online!

Explanation

Overall this program pretty much does the right stack set minus the left stack with the right stack initialized to CBA and the left stack initialized to the input.

Annotated Code

<>((((((((()()){}){}){}){}){}())())())<> # Switch to right stack, push CBA, switch back
{({}(<()>)){(([({})]<>({}))){(<({}<>{})<>([{}]{}<>)>)}{}}{}{}<>{}{({}<>)<>}{}}<>

More explanation to come...

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

Mathematica, 37 bytes

Complement@@Characters@{"ABC",#}<>""&
\$\endgroup\$
3
  • \$\begingroup\$ Is there a reason you used strings here rather than lists of characters? \$\endgroup\$ Feb 16, 2017 at 18:05
  • \$\begingroup\$ @GregMartin habit, I guess \$\endgroup\$ Feb 16, 2017 at 18:15
  • \$\begingroup\$ just that I think it comes out shorter if you can avoid Characters \$\endgroup\$ Feb 16, 2017 at 18:30
2
\$\begingroup\$

CJam, 7 bytes

"ABC"l-

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

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

MATLAB / Octave, 20 bytes

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

Online Demo

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

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
\$\endgroup\$
0
2
\$\begingroup\$

C#, 50 Bytes 32 Bytes 47 Bytes 35 Bytes

where i is the input:

i=>string.Join("","ABC".Except(i));

Full app tested in LINQPad

void Main()
{
    var testcases = new Dictionary<string,string[]>
    {
        ["ABC"] = new[]{""},
        ["ACB"] = new[]{""},
        ["BCA"]  = new[]{""},
        ["BAC"]  = new[]{""},
        ["CAB"]  = new[]{""},
        ["CBA"]  = new[]{""},
        ["AB"] = new[]{"C"},
        ["AC"] = new[]{"B"},
        ["BC"] = new[]{"A"},
        ["BA"] = new[]{"C"},
        ["CA"] = new[]{"B"},
        ["CB"] = new[]{"A"},
        ["A"] = new[]{"BC","CB"},
        ["B"] = new[]{"CA","AC"},
        ["C"] = new[]{"AB","BA"},
        [""] = new[]{"ABC","ACB","BCA","BAC","CAB","CBA"},
    };
    
    var output = "";
    
    foreach(var input in testcases.Keys)
    {
        var expect = testcases[input];
        var actual = GetResult(input);
        if(!expect.Contains(actual)) throw new ApplicationException($"{input}:{string.Join(",",expect)}:{actual}");
        output+=$"{input} -> {actual}\n";
    }
    output.Dump();
}

// Define other methods and classes here
private string GetResult(string input){
    return string.Join("","ABC".Except(i));
}

Test results

ABC ->
ACB ->
BCA ->
BAC ->
CAB ->
CBA ->
AB -> C
AC -> B
BC -> A
BA -> C
CA -> B
CB -> A
A -> BC
B -> AC
C -> AB
-> ABC

\$\endgroup\$
4
  • 1
    \$\begingroup\$ That's not a valid answer, it has to be a function or a program, not a code snippet. \$\endgroup\$
    – minseong
    Feb 17, 2017 at 8:12
  • \$\begingroup\$ Ah. My bad. First timer here. So i need the print part in it? \$\endgroup\$ Feb 17, 2017 at 8:31
  • \$\begingroup\$ @MichaelCoxon: You either need to make the entry into an entire program, which compiles (not recommended in C#, it has a lot of boilerplate), or into a function that can be called multiple times; at the moment it's just a statement. In C#, it's nearly always easiest to make it into a function by creating a lambda, that takes input via its arguments, and returns via its return value. \$\endgroup\$
    – user62131
    Feb 17, 2017 at 21:47
  • \$\begingroup\$ string.Join("",...) -> string.Concat(...) Saves 1 byte \$\endgroup\$
    – Gymhgy
    Mar 27, 2019 at 5:47
2
\$\begingroup\$

Carrot, 15 bytes

I found a bug 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
\$\endgroup\$
1
\$\begingroup\$

APL, 7 bytes

'ABC'∘~

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

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

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.

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

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)

\$\endgroup\$
5
  • \$\begingroup\$ Will that work for empty input? \$\endgroup\$
    – Titus
    Feb 16, 2017 at 13:44
  • \$\begingroup\$ Now I fixed the transcription error (had "..", typed {,,} here...) \$\endgroup\$
    – Tom Tanner
    Feb 16, 2017 at 13:52
  • \$\begingroup\$ Your code is 35 bytes long. (34 +1 for the -l flag). :) \$\endgroup\$
    – Sake
    Feb 16, 2017 at 13:59
  • \$\begingroup\$ 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. \$\endgroup\$
    – Tom Tanner
    Feb 16, 2017 at 14:03
  • \$\begingroup\$ With 5.14+, you can do perl -pe'$_=eval"ABC=~y/$_//dr"' for only 23 bytes (22 + 1 for -p). \$\endgroup\$ Feb 16, 2017 at 20:28
1
\$\begingroup\$

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))
\$\endgroup\$
1
\$\begingroup\$

Japt, 13 12 bytes

"ABC"r"[{U}]

Saved a byte thanks to ETHproductions.

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ Nice, thanks for using Japt! You can remove the trailing quote to save a byte. \$\endgroup\$ Feb 16, 2017 at 13:54
1
\$\begingroup\$

Pyth, 4 bytes

-<G3

Try it here!

 <G3 -  alphabet[:3]
-    - input-^

Note this uses lower case which might not be acceptable

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

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!

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

Batch, 101 bytes

@set/ps=
@for %%c in (L E J)do @call set d=%%s:%%c=%%&call:c %%c
:c
@if "%d%"=="%s%" set/pd=%1<nul

Takes input on STDIN, which means that %1 is empty when the code falls through into the helper subroutine and nothing gets printed.

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

R, 47 40 bytes

gsub(paste0("[",scan(,""),"]"),"","ABC")

Try it online!

Replaces any letters in the input string with the empty string.

\$\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.