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\$
  • 1
    \$\begingroup\$ Cumbersome I/O format \$\endgroup\$ – Mego Feb 16 '17 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\$ – Mego Feb 16 '17 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 '17 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\$ – theonlygusti Feb 16 '17 at 13:56
  • 1
    \$\begingroup\$ @theonlygusti The input should only contain ABC \$\endgroup\$ – Calvin's Hobbies Feb 16 '17 at 22:09

47 Answers 47

20
\$\begingroup\$

Python 3, 29 27 22 bytes

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

-2 bytes thanks to Jonathan Allan

-5 bytes thanks to Rod

\$\endgroup\$
  • \$\begingroup\$ print(*{*"LEJ"}-{*input()}) saves 2. (tested on 3.5 and 3.6). \$\endgroup\$ – Jonathan Allan Feb 16 '17 at 8:12
  • \$\begingroup\$ You can also turn into a lambda for -5 bytes \$\endgroup\$ – Rod Feb 16 '17 at 10:06
  • 14
    \$\begingroup\$ I love python ❤️ \$\endgroup\$ – theonlygusti Feb 16 '17 at 14:18
  • \$\begingroup\$ @theonlygusti Whatever happened to <3 and ♥? \$\endgroup\$ – wizzwizz4 Feb 17 '17 at 11:14
  • \$\begingroup\$ @theonlygusti : I would love python if I can replace lamda with 𝛌 \$\endgroup\$ – Fahim Parkar Feb 22 '17 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
    \$\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 '17 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\$
  • \$\begingroup\$ I had the same thoughts - even with the quotes - immediately, too. \$\endgroup\$ – rexkogitans Feb 16 '17 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\$
  • \$\begingroup\$ How exactly does the 1` part of the antigrep stage work? \$\endgroup\$ – Cows quack Feb 16 '17 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\$ – Martin Ender Feb 16 '17 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\$
  • \$\begingroup\$ Shouldn't an input of only J return EL, LE? \$\endgroup\$ – Magic Octopus Urn Feb 16 '17 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 '17 at 14:56
  • \$\begingroup\$ @carusocomputing: It can return either (in this case it returns LE). \$\endgroup\$ – Emigna Feb 16 '17 at 14:59
  • 1
    \$\begingroup\$ Can be 4 bytes now \$\endgroup\$ – Kevin Cruijssen Mar 26 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\$ – Kevin Cruijssen Mar 26 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\$
  • 1
    \$\begingroup\$ Can you do "["+s+"]" instead of s.replaceAll("(.)","$1|")? \$\endgroup\$ – Cows quack Feb 16 '17 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\$ – Kevin Cruijssen Feb 16 '17 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\$
  • \$\begingroup\$ abc can be written as <G3 \$\endgroup\$ – Maltysen Feb 16 '17 at 22:25
  • \$\begingroup\$ @Maltysen yeah muddyfish used that, but it is lowercase anyway =\ \$\endgroup\$ – Rod Feb 17 '17 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\$
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\$
  • \$\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 '17 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 '17 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 '17 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\$
3
\$\begingroup\$

Ruby, 27 19 18 bytes

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

-1 byte thanks to Martin Ender

\$\endgroup\$
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\$
  • 1
    \$\begingroup\$ I hope (\\) will be moved to Prelude soon. \$\endgroup\$ – theonlygusti Feb 16 '17 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\$ – ceased to turn counterclockwis Feb 16 '17 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\$ – theonlygusti Feb 16 '17 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\$ – ceased to turn counterclockwis Feb 16 '17 at 17:05
  • \$\begingroup\$ @ceasedtoturncounterclockwis what, yes it does. "The first instance of..." but nvm \$\endgroup\$ – theonlygusti Feb 16 '17 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\$
  • \$\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\$ – Digital Trauma Feb 16 '17 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 '17 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\$
  • \$\begingroup\$ Is there a reason you used strings here rather than lists of characters? \$\endgroup\$ – Greg Martin Feb 16 '17 at 18:05
  • \$\begingroup\$ @GregMartin habit, I guess \$\endgroup\$ – Martin Ender Feb 16 '17 at 18:15
  • \$\begingroup\$ just that I think it comes out shorter if you can avoid Characters \$\endgroup\$ – Greg Martin Feb 16 '17 at 18:30
2
\$\begingroup\$

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
\$\endgroup\$
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\$
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\$
  • 1
    \$\begingroup\$ That's not a valid answer, it has to be a function or a program, not a code snippet. \$\endgroup\$ – theonlygusti Feb 17 '17 at 8:12
  • \$\begingroup\$ Ah. My bad. First timer here. So i need the print part in it? \$\endgroup\$ – Michael Coxon Feb 17 '17 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 '17 at 21:47
  • \$\begingroup\$ string.Join("",...) -> string.Concat(...) Saves 1 byte \$\endgroup\$ – Embodiment of Ignorance Mar 27 at 5:47
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\$
  • \$\begingroup\$ Will that work for empty input? \$\endgroup\$ – Titus Feb 16 '17 at 13:44
  • \$\begingroup\$ Now I fixed the transcription error (had "..", typed {,,} here...) \$\endgroup\$ – Tom Tanner Feb 16 '17 at 13:52
  • \$\begingroup\$ Your code is 35 bytes long. (34 +1 for the -l flag). :) \$\endgroup\$ – Paul Picard Feb 16 '17 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 '17 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\$ – ThisSuitIsBlackNot Feb 16 '17 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\$
  • \$\begingroup\$ Nice, thanks for using Japt! You can remove the trailing quote to save a byte. \$\endgroup\$ – ETHproductions Feb 16 '17 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
\$\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, privacy policy and cookie policy

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