32
\$\begingroup\$

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.

Rules

  • 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
\$\endgroup\$
6
  • \$\begingroup\$ So a list of characters isn't allowed if there is a string type? Just making sure \$\endgroup\$
    – noodle man
    Nov 7 at 13:01
  • \$\begingroup\$ Is printing "c " instead of "c" okay? \$\endgroup\$
    – Lynn
    Nov 7 at 22:08
  • \$\begingroup\$ @noodleman correct \$\endgroup\$
    – Sisyphus
    Nov 7 at 23:31
  • \$\begingroup\$ @Lynn I think I'll insist the output/return value should be exactly c \$\endgroup\$
    – Sisyphus
    Nov 7 at 23:32
  • 1
    \$\begingroup\$ Can we input the list of elements as well as the string to be tested \$\endgroup\$
    – Graham
    Nov 8 at 15:30

33 Answers 33

30
+250
\$\begingroup\$

Python,  55  51 bytes

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

Attempt This Online!

Explain:

  • 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.

Logs:

  • 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!

Logs:

  • Saved 2 bytes thank to Jonathan Allan's tip.
\$\endgroup\$
6
  • 5
    \$\begingroup\$ Very nice. You can remove the [] to join generated results. \$\endgroup\$ Nov 7 at 18:02
  • 1
    \$\begingroup\$ -1 byte \$\endgroup\$
    – xnor
    Nov 8 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
    Nov 8 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\$ Nov 8 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
    Nov 8 at 11:34
18
\$\begingroup\$

JavaScript (ES6), 59 bytes

s=>(s+"aaabbabbc").replace(q=/c|../g,s=>(q[s]^=1)?o=s:0)&&o

Try it online!

Commented

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.

s=>(216-`0x${s}`.replace('c','0c')%255).toString(16)

Try it online!


JavaScript (ES6), 64 bytes

My original answer.

s=>"b__c__aab"[q=s.replace(/c|../g,s=>'0x'+s|0)%9]+["ab"[q%7%5]]

Try it online!

How?

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

Output

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

"b__c__aab"[q=...]

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

"bac"[7/(q=...)|0]

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

["ab"[q%7%5]]
\$\endgroup\$
15
\$\begingroup\$

Stax, 11 bytes

ù¢╓┘0ï<ΣEZ1

Run and debug it

Unpacked (13 bytes):

'c|^2/M{{SkmT

Explanations:

'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

\cÞ⊍C2ẇƒ꘍C∑Ǎ

Try it Online!

Bitstring:

011010100001110110101010000101011001101011111101101001000110111010111001101110101010000

Explanations:

\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".
\$\endgroup\$
11
\$\begingroup\$

Jelly, 15 14 bytes

ḟ”cQp`ḟs2$Ʋȯ”c

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

Explanation

ḟ”cQp`ḟs2$Ʋȯ”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

œ^”cs2œ^"/

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.

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

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!

How?

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.

\$\endgroup\$
2
  • 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
    Nov 8 at 0:40
  • \$\begingroup\$ @xnor Obviously, I'm waiving the promised bounty now that I've myself been outgolfed so comprehensively. \$\endgroup\$ Nov 9 at 8:41
6
\$\begingroup\$

Vyxal, 106 bitsv2, 13.25 bytes

‛ab2↔\cpṖ'ḣ∑?=;hh

Try it Online!

Bitstring:

1010100100110111101010010101000011000010000011011100110001101010100111101011100111001010011100110100101110

Explained

«F^ǒ⇩v«2ẇṖ'ḣ∑?=;hh­⁡​‎‎⁡⁠⁣⁢‏‏​⁡⁠⁡‌⁢​‎‎⁡⁠⁡‏⁠‎⁡⁠⁢‏⁠‎⁡⁠⁣‏⁠‎⁡⁠⁤‏⁠‎⁡⁠⁢⁡‏⁠‎⁡⁠⁢⁢‏⁠‎⁡⁠⁢⁣‏‏​⁡⁠⁡‌⁣​‎‎⁡⁠⁢⁤‏⁠‎⁡⁠⁣⁡‏‏​⁡⁠⁡‌⁤​‎‎⁡⁠⁣⁣‏⁠‎⁡⁠⁤⁤‏‏​⁡⁠⁡‌⁢⁡​‎‎⁡⁠⁣⁤‏‏​⁡⁠⁡‌⁢⁢​‎‎⁡⁠⁤⁡‏‏​⁡⁠⁡‌⁢⁣​‎‎⁡⁠⁤⁢‏⁠‎⁡⁠⁤⁣‏‏​⁡⁠⁡‌⁢⁤​‎‎⁡⁠⁢⁡⁡‏⁠‎⁡⁠⁢⁡⁢‏‏​⁡⁠⁡‌­
         Ṗ          # ‎⁡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.

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

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

\co2ẇHƒ꘍12∴k6τ

Try it Online!

Bitstring:

011010100001111110010011010110100010110000110101011111111011101001101110100010100100100101011011010

Literal translation of the J solution above.

\co2ẇHƒ꘍12∴k6τ
\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"
\$\endgroup\$
4
  • 1
    \$\begingroup\$ This is excellent. \$\endgroup\$
    – Jonah
    Nov 8 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
    Nov 8 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
    Nov 8 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
    Nov 8 at 4:25
5
\$\begingroup\$

TypeScript's Type System, 144 bytes

type F<S,X=0&1>=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.

\$\endgroup\$
5
\$\begingroup\$

Jelly,  20 18  17 bytes

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

⁾abp`”cṭŒ!F=¥Þ⁸ṪṪ

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.

How?

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?)...

ḟ”cOḤÐoS;Ḥ$%5Qị“bbaac

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.

How?

ḟ”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"

Examples:

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

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

Ruby, 41 bytes

->s{"%x"%(726-s.scan(/c|../).sum(&:hex))}

Try it online!

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

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

Go, 209 bytes

import."strings"
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}}
return"c"}

Attempt This Online!

Explanation

import."strings"
func f(s string)string{
// remove "c" from the input. guaranteed to be even length
r:=ReplaceAll(s,"c","")
// map to keep track of seen pairs
S:=map[string]int{"aa":0,"ab":0,"ba":0,"bb":0}
// for each pair of chars...
for i:=0;i<len(r);i+=2{
// get the pair
k:=r[i:i+2]
// 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"
return"c"}
\$\endgroup\$
4
\$\begingroup\$

Uiua, 31 29 bytes

Two bytes saved by replacing "ab" with ⊝.

⊔⊡⊗0⊐⊃∊'⊂⊙"c"∩(↯~2)⊞⊟.⊝.▽≠@c.

Try it online!

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

Explanation

                          ▽≠@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
\$\endgroup\$
3
  • \$\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
    Nov 7 at 22:46
  • \$\begingroup\$ @ovs For ', yes, though it's deprecated since 0.1.0. \$\endgroup\$
    – Bubbler
    Nov 7 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
    Nov 8 at 0:02
4
\$\begingroup\$

Uiua, 27 bytes

?"c"⍜(-@a)(◿2/+↯~2▽<2.)=8⧻.

Try it online!

Explanation:

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

Example:

Input: "cbbbaab"

Operation Stack (top on left):
"cbbbaab"
⧻. 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"
\$\endgroup\$
4
\$\begingroup\$

Retina 0.8.2, 29 23 bytes

$
¶aaabbbbac
D`c|..
1A`

Try it online! Link includes test cases. Explanation:

$
¶aaabbbbac

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

D`c|..

Remove duplicate elements from the copy.

1A`

Remove the original input.

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

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)

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

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!

Formatted:

    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";
    };

Logs:

  • 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)
\$\endgroup\$
9
  • 2
    \$\begingroup\$ Welcome to Code Golf! \$\endgroup\$ Nov 8 at 17:11
  • \$\begingroup\$ @RydwolfPrograms thank you. :) ... hope, the idea of the approach is understandable. \$\endgroup\$
    – Tobias321
    Nov 8 at 17:17
  • \$\begingroup\$ The variables b and p might also be inline => new length: 251 bytes. \$\endgroup\$
    – Tobias321
    Nov 8 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
    Nov 8 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
    Nov 8 at 19:24
3
\$\begingroup\$

Ruby, 64 bytes

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

Attempt This Online!

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

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.

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

Python 3, 73 bytes

b,*l=0,{'c'},{0}
for c in input():l[b]^={c};b^=c<'c'
print(str(l)[3::10])

Try it online!

71 bytes

b=k=62
for c in input():k^=ord(c)*b;b^=c<'c'
print("babbaac"[k%7:][:2])

Try it online!

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

Charcoal, 19 15 bytes

⌊⁻⪪”&∨O⊕”²⪪⁻Sc²

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.

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

Google Sheets, 80 bytes

=substitute(regexreplace("aa|ab|ba|bb|c",regexreplace(A1,"(c|..)","$1|"),),"|",)

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

s=>(r=(x,y,z)=>x.replace(RegExp(y,'g'),z||''))(r('aa#ab#ba#bb#c',r(s,'(c|..)','$1|')),'#')
\$\endgroup\$
3
\$\begingroup\$

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

(-.~,&;(,{;~'ab')-._2<\-.)&'c'

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.

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

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'.

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

Uiua, 38 characters (62 bytes)

("c";|⊢▽¬∊,⊃(↯¯1_2▽∊,)(/⊂⊞⊂.)"ab")∊@c.

Uiuapad

("c";|⊢▽¬∊,⊃(↯¯1_2▽∊,)(/⊂⊞⊂.)"ab")∊@c.­⁡​‎‎⁡⁠⁡‏⁠‎⁡⁠⁢⁢‏⁠‎⁡⁠⁣⁡⁢‏⁠‎⁡⁠⁣⁡⁣‏⁠‎⁡⁠⁣⁡⁤‏⁠‎⁡⁠⁣⁢⁡‏⁠‎⁡⁠⁣⁢⁢‏‏​⁡⁠⁡‌⁢​‎‎⁡⁠⁢‏⁠‎⁡⁠⁣‏⁠‎⁡⁠⁤‏⁠‎⁡⁠⁢⁡‏‏​⁡⁠⁡‌⁣​‎‎⁡⁠⁣⁤‏⁠‎⁡⁠⁢⁢⁣‏⁠‎⁡⁠⁢⁢⁤‏⁠‎⁡⁠⁢⁣⁡‏⁠‎⁡⁠⁢⁣⁢‏⁠‎⁡⁠⁢⁣⁣‏⁠‎⁡⁠⁢⁣⁤‏⁠‎⁡⁠⁢⁤⁡‏⁠‎⁡⁠⁢⁤⁢‏⁠‎⁡⁠⁢⁤⁣‏⁠‎⁡⁠⁢⁤⁤‏⁠‎⁡⁠⁣⁡⁡‏‏​⁡⁠⁡‌⁤​‎‎⁡⁠⁣⁤‏⁠‎⁡⁠⁤⁡‏⁠‎⁡⁠⁤⁢‏⁠‎⁡⁠⁤⁣‏⁠‎⁡⁠⁤⁤‏⁠‎⁡⁠⁢⁡⁡‏⁠‎⁡⁠⁢⁡⁢‏⁠‎⁡⁠⁢⁡⁣‏⁠‎⁡⁠⁢⁡⁤‏⁠‎⁡⁠⁢⁢⁡‏⁠‎⁡⁠⁢⁢⁢‏‏​⁡⁠⁡‌⁢⁡​‎‎⁡⁠⁢⁣‏⁠‎⁡⁠⁢⁤‏⁠‎⁡⁠⁣⁡‏⁠‎⁡⁠⁣⁢‏⁠‎⁡⁠⁣⁣‏‏​⁡⁠⁡‌­
(    |                              )∊@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.
\$\endgroup\$
3
\$\begingroup\$

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
\$\endgroup\$
2
  • \$\begingroup\$ min(...) is a byte shorter than [*...][0]. \$\endgroup\$
    – Neil
    Nov 7 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
    Nov 7 at 22:08
2
\$\begingroup\$

Vyxal v2.21.12, 14 bytes

\cẆǒf«H₴Ǐ3F«ǒ⊍

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

C#, 93 bytes

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

Explanation

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.

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

Nekomata, 12 bytes

ĕ<ĭÐŤʳXH"c"I

Attempt This Online!

The xor trick is borrowed from this answer by Bubbler.

ĕ<ĭÐŤʳXH"c"I
ĕ                   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"
\$\endgroup\$
2
\$\begingroup\$

C# (without Implicit global usings), 241 bytes

var v=new System.Collections.Generic.List<string>();int i=0;while(v.Count<4){if(args[0][i]=='c')v.Add("c");else{v.Add(args[0].Substring(i,2));i++;}i++;}foreach(var k in"aa|ab|ba|bb|c".Split('|'))if(!v.Contains(k))System.Console.WriteLine(k);

This is my first golf, and the language isn't very golfable... be indulgent :-)

I didn't find a online compiler which handle input arguments correctly ; so to test this, paste it in a Visual Studio .cs file.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ You can use tio to simulate the arguments like this. \$\endgroup\$
    – bsoelch
    Nov 9 at 9:26
  • 1
    \$\begingroup\$ You can save a few bytes when you replace the list with an array and a counter for the length and use ?=: instead of if-else tio, 189 bytes \$\endgroup\$
    – bsoelch
    Nov 9 at 9:43
  • \$\begingroup\$ Welcome to Code Golf, and nice answer! \$\endgroup\$ Nov 9 at 14:21
  • \$\begingroup\$ Building on @bsoelch 185 bytes \$\endgroup\$
    – ceilingcat
    Nov 10 at 18:44
2
\$\begingroup\$

APL+WIN, 69, 63, 57 bytes.

A bit more golfing saves another 6 bytes.

Prompts for string:

((8=⍴i)/'c'),(~s∊⊂[2]((⍴v),2)⍴v←(i←⎕)~'c')/s←,'ab'∘.,'ab'

Try it online! Thanks to Dyalog Classic

\$\endgroup\$

Your Answer

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

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