One element of the list aa, ab, ba, bb, c has been removed, and the remainder shuffled and joined with no separator. Find the missing element.

For example, if the input was aaabbac, this is made by concatenating aa ab ba c, so the output would be bb.


  • Standard I/O rules apply.
  • You must take input as a string (or equivalent in your language), and you must use the characters abc as in the question; you cannot substitute them for others.
  • This is code golf, shortest code in bytes wins.

Test cases

cbbbaab  -> aa
bbbaabc  -> aa
cabbabb  -> aa
baaacbb  -> ab
bbcaaba  -> ab
caababb  -> ab
bbcabaa  -> ba
abcaabb  -> ba
abcbbaa  -> ba
bacaaab  -> bb
aacabba  -> bb
caaabba  -> bb
bbabaaba -> c
aaabbabb -> c
abaabbba -> c
  • \$\begingroup\$ So a list of characters isn't allowed if there is a string type? Just making sure \$\endgroup\$ Commented Nov 7, 2023 at 13:01
  • \$\begingroup\$ Is printing "c " instead of "c" okay? \$\endgroup\$
    – lynn
    Commented Nov 7, 2023 at 22:08
  • \$\begingroup\$ @noodleman correct \$\endgroup\$
    – Sisyphus
    Commented Nov 7, 2023 at 23:31
  • \$\begingroup\$ @Lynn I think I'll insist the output/return value should be exactly c \$\endgroup\$
    – Sisyphus
    Commented Nov 7, 2023 at 23:32
  • 1
    \$\begingroup\$ Can we input the list of elements as well as the string to be tested \$\endgroup\$
    – Graham
    Commented Nov 8, 2023 at 15:30

38 Answers 38


Python,  55  51 bytes

lambda a:'%x'%(-int(a.replace('c','0c'),16)%255-39)

Attempt This Online!


  • Observe that 'a', 'b', 'c' are base 16 digits.
  • I learnt from Albert.Lang's solution that we can use int(a.replace('c',''),x)%(x*x-1) to extract sum of character at odd and even position.
  • Replace 'c' with '0c' allow us to subtract by 39 to get 'c' without affecting other output cases (Original idea is to replace 'c' with '33', by xnor).
  • Finally, '%x'% is used to convert int back to base 16.


  • Saved 4 bytes thank to xnor's suggests.

Python,  94 92 bytes

lambda a:('c'in a)*''.join(chr(390-sum(map(ord,a.replace('c','')[i::2])))for i in(0,1))or'c'

Attempt This Online!


  • Saved 2 bytes thank to Jonathan Allan's tip.
  • 5
    \$\begingroup\$ Very nice. You can remove the [] to join generated results. \$\endgroup\$ Commented Nov 7, 2023 at 18:02
  • 1
    \$\begingroup\$ -1 byte \$\endgroup\$
    – xnor
    Commented Nov 8, 2023 at 6:01
  • 1
    \$\begingroup\$ Maybe there's something with int(a.replace('c','33')) if you can find a decent way to handle the c output case. \$\endgroup\$
    – xnor
    Commented Nov 8, 2023 at 6:17
  • 1
    \$\begingroup\$ Ty, found out we can do int(a.replace('c','0c')) so we subtract by 39 to get 'c' without affecting other output cases. I will edit the answer. \$\endgroup\$ Commented Nov 8, 2023 at 7:05
  • 2
    \$\begingroup\$ IMHO (216-int(a.replace('c','0c'),16)%255) is more readable than (-int(a.replace('c','0c'),16)%255-39). \$\endgroup\$
    – Neil
    Commented Nov 8, 2023 at 11:34

JavaScript (ES6), 59 bytes


Try it online!


s =>              // s = input string
(s + "aaabbabbc") // append all the patterns to s
.replace(         // replace:
  q =             //   we use q as an object to keep track of
                  //   encountered patterns
  /c|../g,        //   a pattern is either 'c' or 2 characters
  s =>            //   for each matched pattern s:
    (q[s] ^= 1) ? //     if this is the first time we see it:
      o = s       //       save it into o
    :             //     else:
      0           //       do nothing
) && o            // end of replace(); return o (i.e. the last
                  // pattern seen for the first time)

JavaScript (ES6), 52 bytes

Porting Phan Trọng Nhân's excellent answer is definitely shorter.


Try it online!

JavaScript (ES6), 64 bytes

My original answer.


Try it online!


Identifying the missing pattern

We look for the relevant patterns in the input string with /c|../g and replace each of them with its decimal value when parsed as hexadecimal.

This gives:

original pattern replaced with
aa 170
ab 171
ba 186
bb 187
c 12

For instance, "abbabbc" is turned into "17118618712".

It is a well known fact that \$n \bmod 9\$ is the sum of the decimal digits of \$n\$ modulo \$9\$. (Obviously, the order of the digits doesn't matter.)

Because each decimal pattern described above has a different remainder modulo \$9\$, we can identify the missing one by just reducing the entire transformed string modulo \$9\$:

\$q=n \bmod 9\$ missing pattern
0 ba
3 c
6 ab
7 aa
8 bb


We use a 9-character lookup string for the first character:


We could also use the following trick, which is unfortunately just as long:


And we use a shorter lookup string with a modulo chain for the 2nd character, wrapped into brackets so that undefined is turned into an empty string for \$q=3\$:


Stax, 11 bytes


Run and debug it

Unpacked (13 bytes):



'c|^         Set xor with "c" without deduplication or changing of order.
2/           Split into 2 character chunks.
M            Transpose (aka zip).
{{Skm        Map by reduce by xor of the character codes.
             The two lines work like reducing by vectorized xor.
T            Trim on the right. For some reasons null bytes are also
             printed as spaces and are also removed.

The difficult part is to find the right language that had all the required features. Many languages have them but they may not be the default behavior of the most obvious operator, so I thought they don't. The most important one is set xor (set symmetric difference) without deduplication. Others are splitting to equally sized chunks, and doing mathematics on character values. But Stax doesn't have map and reduce operators with block starters omitted for a single character operation.

Vyxal, 87 bitsv2, 11 10.875 bytes


Try it Online!




\cÞ⊍         Set xor with "c" without deduplication or changing of order.
C            Convert characters to numbers.
2ẇ           Split into 2 character chunks.
ƒ꘍           Reduce by automatically vectorized xor.
C            Convert back to characters.
∑            Concatenate.
Ǎ            Remove non-letters, i.e. the null byte if the answer is "c".

Jelly, 15 14 bytes


Try it online!

Thanks to @JonathanAllan for saving a byte!

A full program taking a string as its argument and printing the missing piece. (It can also be used as a monadic link, but will return a Jelly string if the result is one of the ab permutations and a single character for c.)


ḟ”c            | Filter out "c"
         Ʋ     | Following as a monad:
  Q            | - Uniquify
   p`          | - Cartesian product with itself
     ḟ         | - Filter out
      s2$      |   - The c-less input split into twos
           ȯ”c | Or "c"

Alternative approach: Jelly, 10 bytes


Try it online!

This is a translation of @jimmy23013’s clever Stax answer; I’ve not replaced my main one since I wanted to preserve my different approach, but this is clearly shorter!

œ^”cŒœœ^/€ would also work for ten.

  • 1
    \$\begingroup\$ Ah, smart using a Cartesian product to get valid non-c pairs. ḟ”cQp`ḟs2$Ʋȯ”c saves a byte. \$\endgroup\$ Commented Nov 7, 2023 at 20:12

Python, 55 bytes

lambda a:f'{int("cc"+(30*a).strip("ab"),16)%255%192:x}'

Attempt This Online!

This produces 15 (= base - 1) on frame and (if c is present) 15 off frame copies of the input. The sum will therefore be 0 modulo 0x11 x 0x0f. .strip("ab") removes one set of on frame copies of all but c. Adding 0xcc which is the sum of the four possible non c terms mod 0xff yields the missing item unless it is c which is dealt with separately.

Python, 57 bytes

lambda s:" aabbcbaba"[int(s.replace("c",""),14)%195%8::5]

Attempt This Online!


First get rid of the evil frame-shifting "c". Afterwards read as base 14 and add all pairs by reducing modulo 195. Further reduce and produce the answer by indexing into a magic string.

  • 2
    \$\begingroup\$ This is certainly shorter than anything I was trying! I'll post a bounty when the question is old enough to allow it. \$\endgroup\$
    – xnor
    Commented Nov 8, 2023 at 0:40
  • \$\begingroup\$ @xnor Obviously, I'm waiving the promised bounty now that I've myself been outgolfed so comprehensively. \$\endgroup\$ Commented Nov 9, 2023 at 8:41

Vyxal, 106 bitsv2, 13.25 bytes


Try it Online!




         Ṗ          # ‎⁡Permutations of
«F^ǒ⇩v«             # ‎⁢The string "aaabbabbc"
       2ẇ           # ‎⁣split into chunks of size 2
          '    ;    # ‎⁤Filtered by:
           ḣ        # ‎⁢⁡  the permutation with the head removed
            ∑       # ‎⁢⁢  joined into a single string
             ?=     # ‎⁢⁣  equals the input.
                hh  # ‎⁢⁤Get the first item of the first item in that list.

Created with the help of Luminespire.

  • 1
    \$\begingroup\$ You can replace the compressed string with a hardcoded version for 106 bits. \$\endgroup\$
    – math scat
    Commented Nov 7, 2023 at 15:45

J 9.4, 25 bytes

(]>.&XOR&.dfh _2]\-.)&'c'

Attempt This Online!

dfh and hfd were recently modified to have each other as inverses. ATO doesn't have the change yet.

J, 26 bytes

12(hfd@>.XOR)_2 dfh\-.&'c'

Attempt This Online!

The XOR of three of aa, ab, ba, bb interpreted as hexadecimal (or any base that is a greater power of 2) is the missing one, and the XOR of all four is zero. When all four are present, the XOR value is replaced with 12 before converting back to hexadecimal.

12(hfd@>.XOR)_2 dfh\-.&'c'    input: a string
                    -.&'c'    remove 'c'
             _2 dfh\          convert each chunk of 2 with "hex->int"
  (      XOR)                 reduce by bitwise XOR
12     >.                     max with 12; if the result is 0, use 12 instead
   hfd@                       convert with "int->hex"

Vyxal, 99 bitsv2, 12.375 bytes


Try it Online!



Literal translation of the J solution above.

\co               remove 'c'
   2ẇ             chunks of 2
     H            convert each with "hex->int"
      ƒ꘍          reduce by bitwise XOR
        12∴      max with 12
            k6τ   into base "lower hex digits"; convert with "int->hex"
  • 1
    \$\begingroup\$ This is excellent. \$\endgroup\$
    – Jonah
    Commented Nov 8, 2023 at 0:55
  • \$\begingroup\$ (](>.XOR)&.dfh _2]\-.)&'c' also for 26, but for some reason fails on ATO though it works locally 9.4.2. \$\endgroup\$
    – Jonah
    Commented Nov 8, 2023 at 2:23
  • 1
    \$\begingroup\$ @Jonah That's because dfh and hfd were recently modified to have each other as inverses. ATO version is presumably older than that. \$\endgroup\$
    – Bubbler
    Commented Nov 8, 2023 at 4:10
  • \$\begingroup\$ I see you managed to shave off another byte from my suggestion by using & on the XOR part too, since it has no effect on single values -- clever! \$\endgroup\$
    – Jonah
    Commented Nov 8, 2023 at 4:25

Go, 209 bytes

func f(s string)string{r,S:=ReplaceAll(s,"c",""),map[string]int{"aa":0,"ab":0,"ba":0,"bb":0}
for i:=0;i<len(r);i+=2{k:=r[i:i+2]
if S[k]<1{S[k]++}}
for k,v:=range S{if v<1{return k}}

Attempt This Online!


func f(s string)string{
// remove "c" from the input. guaranteed to be even length
// map to keep track of seen pairs
// for each pair of chars...
for i:=0;i<len(r);i+=2{
// get the pair
// if pair is not seen yet, increment the counter
if S[k]<1{S[k]++}}
// for each pair...
for k,v:=range S{
// if not seen, return that pair
if v<1{return k}}
// otherwise return "c"

Jelly,  20 18  17 bytes

-3 thanks to Nick Kennedy reminding me to golf the magic table.


A full program that accepts the flattened, redacted permutation and prints the missing item.

Try it online! Or see all twenty four of each of the five choices here.


Brute force...

⁾abp`”cṭŒ!F=¥Þ⁸ṪṪ - Link: list of characters, X
⁾ab               - "ab"
   p`             - Cartesian product with itself -> ["aa","ab","ba","bb"]
     ”cṭ          - tack 'c' character -> ["ab","ba","bb","aa",'c']
        Œ!        - all permutations
             Þ    - sort by:
            ¥ ⁸   -   last two links as a dyad - f(Permutation, X):
          F       -     flatten the Permutation
           =      -     equals X (vectorised)
               Ṫ  - tail -> permutation with matching prefix
                Ṫ - tail -> the missing pair
                  - implicit print

Non-brute-force 21 bytes

I quite like this non-brute force method at 21 bytes though (maybe it can be improved upon?)...


A full program that accepts the flattened, redacted permutation and prints the missing item.

Try it online! Or see all twenty four of each of the five choices here.


ḟ”cOḤÐoS;Ḥ$%5Qị“bbaac - Main Link: list of characters
ḟ”c                   - remove any 'c' character
   O                  - cast to ordinal values ('a' -> 97, 'b' -> 98)
     Ðo               - apply to odd indices (first, third, ...):
    Ḥ                 -   double
       S              - sum
        ;Ḥ$           - concatenate double this value -> [sum, 2×sum]
           %5         - modulo five -> [sum%5, (2×sum)%5]
             Q        - deduplicate
              ị“bbaac - index into "bbaac"


1. missing "c" "aaabbbba"

-> "aaabbbba" (removed 'c'; no change)
-> [97,97,97,98,98,98,98,97] (cast to ordinals)
-> [194,97,194,98,196,98,194,97] (double values at odd indices)
-> 1170 (sum those)
-> [1170, 2340] (concatenate double itself)
-> [0, 0] (modulo five)
-> [0] (deduplicate)
-> "c" (index into "bbaac" - Note that indexing is one-based and modular)

2. missing "bb" "aaacbba"

-> "aaabba" (removed 'c')
-> [97,97,97,98,98,97] (cast to ordinals)
-> [194,97,194,98,196,97] (double values at odd indices)
-> 876 (sum those - i.e. \$1170 - (2 \times 98) - 98 = 876\$)
-> [876, 1752] (concatenate double itself)
-> [1, 2] (modulo five)
-> [1, 2] (deduplicate; no change)
-> "bb" (index into "bbaac")

  • \$\begingroup\$ ؽp3ṭịØaŒ!F=¥Þ⁸ṪṪ` saves two bytes for your brute force solution. I’ve taken a different approach that I’ll post separately. \$\endgroup\$ Commented Nov 7, 2023 at 19:21
  • 1
    \$\begingroup\$ Totally forgot to golf the magic table LOL. \$\endgroup\$ Commented Nov 7, 2023 at 20:33

Ruby, 41 bytes


Try it online!

0xaa+0xab+0xba+0xbb+0xc is 726.


TypeScript's Type System, 144 142 bytes

type F<S,X=0>=S extends`c${infer R}`?F<R,X|"c">:S extends`${infer A}${infer B}${infer R}`?F<R,X|`${A}${B}`>:Exclude<"aa"|"ab"|"ba"|"bb"|"c",X>

Try it at the TypeScript playground.

This is only so long because it has to check for "c" separately because TypeScript annoyingly doesn't let you infer part of a string that is a union of strings of variable length. I also have a different idea that might be shorter, but it's not at all obvious how to accomplish it in TS types so it might take me a while to figure out.


Uiua, 31 29 bytes

Two bytes saved by replacing "ab" with ⊝.


Try it online!

Interestingly, since Uiua has an autoformatter that runs during execution, afterwards it is 30 bytes. (Specifically, '⊂⊙"c" is turned into (⊂⊙"c"))


                          ▽≠@c. # Remove all c from the string
                     ⊞⊟.⊝.      # construct "ab" and generate all pairs of its elements
               ∩(↯~2)           # Simultaneously:
                                  # flatten the table into an array of 2-char strings
                                  # chunk the input (sans c) into 2-char strings
     ⊐⊃∊                        # Both find which of aa,ab,ba,bb are in chunked input...
        '⊂⊙"c"                  # ...and add c to the array of aa,ab,ba,bb
  ⊗0                            # Index of pair that was not found (4 if all were found)
⊔⊡                              # Select from aa,ab,ba,bb,c
  • \$\begingroup\$ Is the ' just syntax for atop (composition of two functions)? Can't find anything in the docs. Also I think "ab" can just be replaced by .. A bit less efficient, but that doesn't matter \$\endgroup\$
    – ovs
    Commented Nov 7, 2023 at 22:46
  • \$\begingroup\$ @ovs For ', yes, though it's deprecated since 0.1.0. \$\endgroup\$
    – Bubbler
    Commented Nov 7, 2023 at 23:18
  • \$\begingroup\$ @ovs I used cartesian product as a sort of shorthand; it's not actually a set operation. There's probably a better word, but it's not coming to me. In any case, it can't just be replaced with .. That does inspire a different length optimization, though! \$\endgroup\$
    – Pseudo Nym
    Commented Nov 8, 2023 at 0:02

Uiua, 27 bytes


Try it online!


For the cases where 'c' is in the string, this uses a little trick by converting 'a' to 0 and 'b' to 1, then the XOR of the three pairs results in the missing pair.

?"c"                    =8⧻.   # If the string length is 8, return "c"
    ⍜(-@a)(           )       # Subtract char 'a' from the string to get an
                               # array where a=0, b=1, c=2. Then perform the
                               # following and add char 'a' back at the end:
                   ▽<2.        # Remove any 2s (char 'c')
                ↯~2            # Reshape to pairs
            ◿2/+               # XOR by adding the pairs and taking modulo 2


Input: "cbbbaab"

Operation Stack (top on left):
⧻. 7 "cbbbaab"
=8 0 "cbbbaab"
?"c" "cbbbaab"
⍜(-@a)( [2 1 1 1 0 0 1]
▽<2. [1 1 1 0 0 1]
↯~2 [[1 1] [1 0] [0 1]]
/+ [2 2]
◿2 [0 0]
) "aa"

Retina 0.8.2, 29 23 bytes


Try it online! Link includes test cases. Explanation:


Append another copy of the whole list on a separate line.


Remove duplicate elements from the copy.


Remove the original input.


Perl 5 (-p), 32, 29 bytes

$_=s/c//?eval s/..\K\B/^/gr:c

Try it online!

If c can't be removed returns c otherwise bitwise xor 2 char strings.

-3 bytes thanks to Kjetil S, changing (?!$) (negative lookahead end anchor) with \B (non-word-boundary)

  • \$\begingroup\$ Nice. Replace (?!$) with \B to save 3. \$\endgroup\$
    – Kjetil S
    Commented Nov 8, 2023 at 16:02
  • \$\begingroup\$ sure, thanks for seeing it \$\endgroup\$ Commented Nov 9, 2023 at 10:39

Python, 83 bytes

lambda a:min({'aa','ab','bb','ba','c'}-{a.replace('c','')[i:i+2]for i in[0,2,4,6]})

Attempt This Online!

  • -17 bytes thanks to Neil
  • \$\begingroup\$ min(...) is a byte shorter than [*...][0]. \$\endgroup\$
    – Neil
    Commented Nov 7, 2023 at 22:07
  • \$\begingroup\$ ... which then allows you to port my Charcoal answer and replace (a.replace('c','')+'c'*('c'in a)) with a.replace('c',''). \$\endgroup\$
    – Neil
    Commented Nov 7, 2023 at 22:08

Java (SE), 164 bytes

b->{if(b.contains("c"))l:for(var c:"aa ab ba bb".split(" ")){for(int i=0;i<6;i+=2)if(c.contains(b.replace("c","").substring(i,i+2)))continue l;return c;}return"c";}

Try it online!


    static Function<String, String> f1 = b -> {
        if (b.contains("c"))
            l:for (var c : "aa ab ba bb".split(" ")) {
                for (int i = 0; i < 6; i += 2)
                    if (c.contains(b.replace("c", "").substring(i, i + 2)))
                        continue l;
                return c;
        return "c";


  • Golfing tips for I/O defaults respected (lambda function b) Thanks @corvus_192 !
  • String replaced with var at one place (-3 bytes)
  • System.out.printlns replaced with returns (-31 bytes) Thanks @ceilingcat !
  • return "c"; replaced with return"c"; (-1 byte)
  • 2
    \$\begingroup\$ Welcome to Code Golf! \$\endgroup\$ Commented Nov 8, 2023 at 17:11
  • \$\begingroup\$ @RydwolfPrograms thank you. :) ... hope, the idea of the approach is understandable. \$\endgroup\$ Commented Nov 8, 2023 at 17:17
  • \$\begingroup\$ The variables b and p might also be inline => new length: 251 bytes. \$\endgroup\$ Commented Nov 8, 2023 at 17:26
  • 1
    \$\begingroup\$ Welcome! We have a page dedicated to golfing in tips in java (and many other languages). Also check out our I/O defaults. In most cases, you can submit a lambda function as the shortest way, like b->{...} \$\endgroup\$
    – corvus_192
    Commented Nov 8, 2023 at 18:50
  • 1
    \$\begingroup\$ 196 bytes: b->{if(b.contains("c"))l:for(var c:"aa ab ba bb".split(" ")){for(int i=0;i<6;i+=2)if(c.contains(b.replace("c","").substring(i,i+2)))continue l;System.out.println(c);}else System.out.println("c");} \$\endgroup\$
    – corvus_192
    Commented Nov 8, 2023 at 19:24

05AB1E, 14 bytes


Port of @Bubbler's J & Vyxal answer, so make sure to upvote that answer as well!

Try it online or verify all possible I/O test cases.


'cK            '# Remove a potential "c" from the (implicit) input-string
   2ô           # Split it into pairs
     H          # Convert each string-pair from hexadecimal to a base-10 integer
      .«        # Reduce this list by:
        ^       #  Bitwise-XORing
         12     # Push 12
           M    # Push the largest value on the stack
            h   # Convert it from a base-10 integer to (uppercase) hexadecimal
             l  # Convert it to lowercase
                # (after which the result is output implicitly)

Ruby, 64 bytes

->s{a=%w[aa ab ba bb c];a.find{[*(a-[_1]).permutation].join[s]}}

Attempt This Online!


Python 3.8, 82 bytes

lambda a:("cbbaa"*469)[(k:=sum(map(ord,(r:=a.replace('c',''))+r[::2])))::k][r==a:]

An unnamed function that accepts the flattened, redacted permutation and returns the missing item.

Try it online!

A port of my non-brute-force Jelly solution.


Python 3, 73 bytes

for c in input():l[b]^={c};b^=c<'c'

Try it online!

71 bytes

for c in input():k^=ord(c)*b;b^=c<'c'

Try it online!


Charcoal, 19 15 bytes


Try it online! Link is to verbose version of code. Explanation:

   ”...”        Compressed string `aaabbbbac`
  ⪪     ²       Split into pairs of characters
 ⁻              Remove elements from
           S    Input string
          ⁻ c   Remove the `c`
         ⪪   ²  Split into pairs of characters
⌊               Take the minimum
                Implicitly print

If all of the a/b pairs were successfully removed then the only remaining element is the trailing c otherwise the minimum element is the missing a/b pair.


Google Sheets, 80 bytes


Put the input in cell A1 and the formula in B1.

Nothing clever here, just two replaces, plus removal of hardcoded separators.

Translation to JavaScript (90 bytes, non-competing):


J, 31 30 29 bytes

(e.~{];,@{@;[email protected]._2<\-.)&'c'

Try it online!

-1 thanks to ovs

  • ,@{@;~@-. All valid 2 char pairs, constructed by the crossing the input with itself after removing 'c'. This will contain dups but is guaranteed to have all the valid pairs.
  • -. Minus
  • _2<\-. All 2 char input pairs, formed after removing 'c'
    • At this point we will either have our answer or the empty list (in the case that 'c' itself is missing)
  • ]; Prepend 'c'
    • Now we will have an answer that looks like c;ab (in the case we're missing a 2 char sequence) or simply c (in the case we're missing 'c')
  • e.~{ If 'c' is an element of the input, take the 2nd element. Otherwise take the first (ie, return 'c' itself).

J, 30 bytes


Try it online!

A similar alternate solution that has unboxed output and no conditional logic. Feels slightly cleaner to me despite being 1 byte longer.

  • 1
    \$\begingroup\$ I think (,{;~'ab') can be replaced with the more inefficient ,@{@;~@-. for -1 \$\endgroup\$
    – ovs
    Commented Nov 7, 2023 at 22:37

Python, 86 bytes

lambda s:[*{'aa','ab','ba','bb'}-{*map(str.__add__,*[filter('c'.__ne__,s)]*2)},'c'][0]

Attempt This Online!

No magic numbers here, just another approach to solving in Python, this one a straightforward-ish golfing of removing each of the pairs in the string (with 'c' removed) from the initial set, and if none are left, defaulting to 'c'.


Uiua, 38 characters (62 bytes)



(    |                              )∊@c.  # ‎⁡Is 'c' a member of the string?
 "c";                                      # ‎⁢If not, just return 'c'
            ⊃            (/⊂⊞⊂.)"ab"       # ‎⁣Else, generate the list L = ["aa" "ab" "ba" "bb"]
            ⊃(↯¯1_2▽∊,)                   # ‎⁤And filter out any the c's from the string (by keeping only members of "ab") and reshape it into a n×2 matrix
      ⊢▽¬∊,                               # ‎⁢⁡Return the element of L which does not appear in this matrix.

AWK, 67 64 bytes

patsplit($0,l,/c|[ab]./){$0="aaabbbbac";for(k in l)sub(l[k],a)}1

Attempt This Online!

Removed a semicolon by moving patsplit out to the pattern part (-1), and golfed the regex a bit (-2).

previous answer, 67 bytes:

{patsplit($0,l,/c|[ab]{2}/);$0="aaabbbbac";for(k in l)sub(l[k],a)}1

Attempt This Online!

  • patsplit($0,l,/c|[ab]{2}/): Split $0 (the input string) into valid chunks and store as a list in l. /c|../ doesn't work because regex matching is done in favor of longer length across all alternatives.

  • $0="aaabbbbac": Replace $0 with this fixed string.

  • for(k in l)sub(l[k],a): For each chunk in l, find and remove once from $0. An uninitialized variable a is used in place of an empty string.

  • 1: An all-match pattern. This causes $0 to be printed as a default action.

Replacing without splitting "aaabbbbac" into chunks first works because

  • there is only one place to be replaced for ab and ba, and
  • for aa and bb, it doesn't matter which part of the runs is removed.

Vyxal v2.21.12, 14 bytes


Try it Online! (code modified to work on current version)

I'm using an older version of Vyxal because for some reason ǒ was modified in a recent version. Also, yes there's another Vyxal answer, but this one's shorter in regular SBCS bytes.

  Ẇ            # Split (keeping delimiter) on
\c             # "c"
   ǒf          # Cut each into chunks of length 2
     «H₴Ǐ3F«   # Compressed string "abaabbbac"
            ǒ  # Cut into chunks of length 2
             ⊍ # Take the set difference

C#, 93 bytes

x=>"aa ab ba bb c".Split().Except(x.Replace("c","").Chunk(2).Select(z=>""+z[0]+z[1])).First()


x =>                         // input string
   "aa ab ba bb c".Split()   // construct array with the four pairs + c
   .Except(                  // remove from it...
       x.Replace("c","")     // remove c from input
       .Chunk(2)             // split into chunks of size 2 (each chunk is a char[])
       .Select(              // transform each item
           z=>""+z[0]+z[1]   // convert char[] to string
   ).First();                // first item remaining. this is c if all pairs were removed

Try it online!

Uses .Chunk which isn't supported on tio.run.


Nekomata, 12 bytes


Attempt This Online!

The xor trick is borrowed from this answer by Bubbler.

ĕ                   Pick one char out from the input string
 <                  Check that all remaining chars are less than the picked char
                    If this does not fail, which means the input contains 'c':
  ĭÐ                    Uninterleave the remaining chars into a pair of strings
    Ť                   Transpose
     ʳX                 Reduce by xor (chars are converted to code points implicitly)
       H                Convert from code points
           I        Otherwise:
        "c"             Return "c"

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.