45
\$\begingroup\$

Given two strings, output a third string that is not equal to either of the two inputs, but has the same length (in characters) as either of the inputs. There is guaranteed to be at least one valid output.

Test Cases

Test cases are quoted to show they are strings. Outputs are one of many possible.

input, input -> output

"test", "test" -> "tttt"
"do", "don't" -> "dnut_"
"ye s", "yes" -> "fals"
"yes", "yes" -> "noo"
"maybe", "mayue" -> "false"
"false", "false" -> "truee"
"false", "true" -> "fatr"
"1", "" -> "0"
"", "t" -> "s"
"", "abcabc" -> "testst"
"abcdefghijklmnopqrstuvwxyz", "aaaaaaaaaaaaaaaaaaaaaaaaaa" -> "zbcdefghijklmnopqrstuvwxya"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" -> "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"

Rules

  • You may chose your input domain, but it must be composed of at least printable ASCII, and your output domain must be the same as your input domain.
  • The input lengths may be the same or different.
  • The output must be valid with probability 1; that is, you may generate random strings until one is valid (and theoretically you might infinite loop), but you can't just output a random string and hope it's valid. Note that this means you output does not need to be deterministic.
  • Automatic trailing newlines allowed, but they do not count towards the length of the output.
  • Due to questions regarding Memory Errors, it must work within 60 seconds up to input lengths of 6. An answer that works for that and theoretically works for longer strings is OK, but something that Memory Errors on modern computer for input length 4 is not valid.

This is , so shortest answer in bytes wins.

\$\endgroup\$
  • 14
    \$\begingroup\$ This seems like another of an interesting new category of questions on this site that are easy for humans and hard for computers. Because computers aren't good at divergent thinking! It reminds me of the Spongebob episode where he's up all night trying to write an essay on what NOT to do at a stoplight. \$\endgroup\$ – geokavel Aug 18 '17 at 22:47
  • 2
    \$\begingroup\$ I understand the output domain can be a subset of the input domain, yes? \$\endgroup\$ – Luis Mendo Aug 18 '17 at 23:21
  • 2
    \$\begingroup\$ Nice question! I like it. \$\endgroup\$ – isaacg Aug 20 '17 at 22:16
  • 2
    \$\begingroup\$ @Quelklef No, that's not different from both inputs. \$\endgroup\$ – Ørjan Johansen Aug 21 '17 at 2:58
  • 3
    \$\begingroup\$ I suggest "", "1" should be added as a test case, since I just realized my answer fails for this even though it works for all the provided test cases \$\endgroup\$ – Slow loris Aug 22 '17 at 23:20

34 Answers 34

3
\$\begingroup\$

05AB1E, 8 7 bytes

øvAyм¬?

Uses the 05AB1E encoding. Try it online!

\$\endgroup\$
  • 1
    \$\begingroup\$ Does this work when one input is the empty string? \$\endgroup\$ – betaveros Aug 21 '17 at 3:52
  • 3
    \$\begingroup\$ Doesn't work if the first string is empty. TIO \$\endgroup\$ – Jo King Mar 26 at 4:30
14
\$\begingroup\$

Haskell, 43 bytes

x!y=[s|s<-(<$max x y)<$>"abc",s/=x,s/=y]!!0

Takes the max (lexicographically later) string, which we know is nonempty; replaces all characters with one of "a", "b", and "c" using <$; and returns the first that is neither of the inputs. I think this is similar to Neil's Charcoal answer and/or geokavel's CJam answer.

(I've lurked for a while but this is my first time answering on this site; hi!)

\$\endgroup\$
9
\$\begingroup\$

Brainfuck, 97 bytes

+>+[-,[>>,]<<[<<]>]>>[>]<<<[<]>[<+>>[-<+<+>>][>]<[->+<]<[-]>>>++<[<]>[.>>]>[>>]]>[+[>]+[<]>[.>>]]

Run code online (note that "dynamic memory" must be selected in the bottom-right)

Awesome challenge! I thought it would be trivial but it ended up being really difficult. I keep coming back to it because I feel like there should be some elegant 20-or-so-byte BF solution. At this point, I'm pretty happy I (seemingly) got it to work at all in BF.

Input is taken as str1 + \0 + str2, where strings are consecutive non-zero 1-byte characters.

Returns (first str1 + first str2) or (first str1 + 1) or 2. This algorithm was thought up by the brilliant @ØrjanJohansen, (presumably) based on my (broken) original one.

Commented:

# Let (Kn) be the nth character of K
# Let (^) designate the pointer
# Let F be the first string inputted
# Let S be the second string inputted

+>+[-  # Twice do
,[>>,]  # Input string (characters separated by 1)
<<[<<]>  # Go to left of beginning of string
]>  # End on first character of second string
# If second string is null we will end one too far to the left
>[>]<<<[<]>  # If first string is null we will end there too
# We will use this to do flow control

[  # Only run if both strings were non null

# Tape:    S0 ' F0 ' S1 ' F1 ' S2 ' F2 ' etc
#          ^

<+>>  # Let F0* = F0 (plus) 1  (is 1 as of now; F0 will be added later)
[-<+<+>>] # Let A = S0 (plus) F0
# A may or may not be zero
# F0* may or may not be zero
# Tape:    F0* ' A ' 0  ' S1 ' F1 ' etc
#                ^

[>]<[->+<]  # Let B = A or F0*
# B may or may not be zero
<[-]>>  # Clear F0*
# Tape:     0 ' B ' 0 ' S1 ' F1 ' etc    (if A was zero)
#               ^
# OR        0 ' 0 ' B ' s1 ' F1 ' etc    (if A was nonzero)
#                   ^

# Let C = B or 2
# C will be guaranteed nonzero and unique from S0 and F0
>++<[<]>  # Create C
[.>>]  # Print (using S or F; does not matter)

>[>>]  # End on a zero cells with zero cells all to the right
# This is necessary for the coming functionality
# also as to not loop
]  # End non null block

# Now we consider if one of the strings was null
# Tape:    0 ' E0 ' 0 ' E1 ' etc    (if one string was null)
#          ^
# Tape:    0 '  0 ' 0 '  0 ' etc    (if neither string was null)
#          ^
# Where E is F or S (we don't care)

>[  # Execute only if one string was null

+  # Let A = E0 (plus) 1
# A may or many not be zero
# Tape: 0 ' A ' 0 ' E1 ' etc
#           ^

[>]+[<]>  # Let B = A or 1
# B is guaranteed nonzero and != E0
# Tape: 0 ' B ' ? ' E1 ' 0 ' E2 ' etc
#           ^

[.>>]  # Print

# End on zero cell as not to loop
]  # End null block
\$\endgroup\$
  • \$\begingroup\$ Your "fact" is wrong, e.g. a=2, b=1. You need to add instead of subtracting. \$\endgroup\$ – Ørjan Johansen Aug 21 '17 at 3:03
  • \$\begingroup\$ I think you can fix the S empty problem by adding > at the start and later doing [<]> on the leftmost byte of S - if that's nonzero it does nothing, otherwise it switches the strings. \$\endgroup\$ – Ørjan Johansen Aug 21 '17 at 3:21
  • \$\begingroup\$ @ØrjanJohansen Oh you're right, it can equal b. But not a. \$\endgroup\$ – Quelklef Aug 21 '17 at 3:36
  • \$\begingroup\$ @ØrjanJohansen Ah, that appears to work! Good thinking! \$\endgroup\$ – Quelklef Aug 21 '17 at 3:41
  • \$\begingroup\$ @ØrjanJohansen Follow up about the fact: Since it's != a only, if I print S/0, S/1, ... instead of S/0, F/1, ... it should work. \$\endgroup\$ – Quelklef Aug 21 '17 at 3:42
6
\$\begingroup\$

Jelly, 8 bytes

żḟ@€ØAZḢ

Try it online!

How?

żḟ@€ØAZḢ - Link: list of characters, a; list of characters, b
ż        - zip a and b
    ØA   - uppercase alphabet
 ḟ@€     - filter discard for €ach (swap @rguments)
      Z  - transpose the result
       Ḣ - head
\$\endgroup\$
  • \$\begingroup\$ It returns B TIO \$\endgroup\$ – Jonathan Allan Aug 19 '17 at 11:35
  • \$\begingroup\$ The algorithm shouldn't anyway, not sure what you did. \$\endgroup\$ – Jonathan Allan Aug 19 '17 at 11:37
  • \$\begingroup\$ nevermind my brain apparently playing tricks since I don't see any X or in there... \$\endgroup\$ – Erik the Outgolfer Aug 19 '17 at 11:39
5
\$\begingroup\$

Python 3, 62 47 57 54 51 bytes

Edit: - 5 bytes thanks to @Mr.Xcoder

Edit: +10 bytes to fix a bug

Edit: -3 bytes thanks to @betaveros

Edit: -3 bytes by using max instead of pop

lambda x,y:max({*"abc"}-{x[:1],y[:1]})+max(x,y)[1:]

Try it online!

\$\endgroup\$
  • \$\begingroup\$ {"a","b","c"} ==> {*"abc"} (57 bytes) \$\endgroup\$ – Mr. Xcoder Aug 18 '17 at 22:35
  • \$\begingroup\$ (x[1:]or y[1:]) ==> max(x,y)[1:]? \$\endgroup\$ – betaveros Aug 19 '17 at 1:43
  • \$\begingroup\$ Or just (x or y)[1:], I think you only need to avoid the empty string. \$\endgroup\$ – betaveros Aug 19 '17 at 1:58
  • \$\begingroup\$ Incidentally, it's a shame Python 2 doesn't have starred set literals, because I really wanted to golf {*"abc"} into {*`id`}... \$\endgroup\$ – betaveros Aug 19 '17 at 20:10
  • \$\begingroup\$ Save 1 with *len(x or y) instead of +max(x,y)[1:]. \$\endgroup\$ – Chas Brown Mar 30 at 22:15
4
\$\begingroup\$

Charcoal, 22 bytes

FEα×ι⌈⟦LθLη⟧¿¬№⟦θη⟧ιPι

Try it online! Link is to verbose version of code. Generates all strings of uppercase characters repeated to the length of the longer input and overprints all those that don't appear in the input. In other words, the output is normally ZZZ... unless that is one of the inputs, in which case it's YYY... unless that is the other input, in which case it's XXX....

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

Mathematica, 111 bytes

(c=Characters;a=#2;While[f=Alphabet[]~RandomChoice~Length@#;f==#||f==c@a]&[#&@@c@{##}~MaximalBy~Length];""<>f)&


try it online (paste code with ctrl+v, place input at the end and hit shift+enter)

input

["test","me"]

thanx @Not a tree for checking and golfing -21 bytes

\$\endgroup\$
  • \$\begingroup\$ How do I test this online again? \$\endgroup\$ – Stephen Aug 18 '17 at 22:29
  • \$\begingroup\$ added link+info \$\endgroup\$ – J42161217 Aug 18 '17 at 22:33
  • \$\begingroup\$ @Jenny_mathy Seems to fail if the first string is the empty string \$\endgroup\$ – Halvard Hummel Aug 18 '17 at 23:10
  • 2
    \$\begingroup\$ @HalvardHummel fixed! \$\endgroup\$ – J42161217 Aug 18 '17 at 23:21
  • 1
    \$\begingroup\$ @Notatree fixed. If you think that "easy golfing" is a reason for downvoting then you are welcome to do so \$\endgroup\$ – J42161217 Aug 19 '17 at 0:44
4
\$\begingroup\$

Perl 6, 38 30 bytes

{(1 x.max.comb...*∉$_).tail}

Try it online!

Anonymous codeblock that takes input as a list of two strings, and returns the first number from 1111... with a non-empty amount of 1s that isn't in the input.

Explanation:

{                          }   # Anonymous code block
  1 x.max.comb                 # String multiply 1 by the size of the non-empty string
              ...              # Create a sequence increasing by 1
                 *∉$_          # Until the number is not in the input
 (                   ).tail    # And take the last number
\$\endgroup\$
  • \$\begingroup\$ Is the incrementor a bigint type, or will this overflow for sufficiently large strings? \$\endgroup\$ – GammaFunction Mar 26 at 5:45
  • 1
    \$\begingroup\$ @GammaFunction In Perl 6, the default number type is Int, which has infinite precision \$\endgroup\$ – Jo King Mar 26 at 5:49
  • \$\begingroup\$ Oh, nice. I was going to adapt this to Zsh, but it uses long long unfortunately. \$\endgroup\$ – GammaFunction Mar 26 at 5:53
  • \$\begingroup\$ You can trim 6 bytes by just taking the first of 00..,111..,22.. instead of counting and sequences: tio.run/… \$\endgroup\$ – Phil H Mar 26 at 10:22
  • \$\begingroup\$ @PhilH Good idea! I've shortened it a bit more by keeping with the sequence idea \$\endgroup\$ – Jo King Mar 26 at 11:46
4
\$\begingroup\$

Zsh, 51 47 37 36 bytes

-4 bytes by using builtin array argv, -10 bytes by using prefix removal and RC_EXPAND_PARAM, -1 byte by inlining the brace expansion.

<<<${${${:-{1..3}${^@#?}}:|argv}[1]}

Try it online!

First, this was an awesome challenge, I went through a ton of ideas before landing on this one.

<<<${${${:-{1..3}${^@#?}}:|argv}[1]}
       ${:-             }            # empty fallback
                 ${ @#?}             # remove first character from each parameter
                 ${^@  }             # enable brace expansion (set -P)
           {1..3}${^@#?}             # expand to 1foo 2foo 3foo 1bar 2bar 3bar
     ${                  :|argv}     # Set difference with 'argv'
   ${                           [1]} # The first found element
<<<                                  # print to stdout

@ and * are not identifiers, so ${ :|@} and ${ :|*} don't work, hence the use of ${ :|argv}

This method will work up to 93 inputs and find a 94th which is unique. Simply replace the {1..3} with the maximum possible range {~..!}.

Zsh, 48 47 bytes*

for ((;$#i<${#${1:-$2}}||$@[(I)$i];i++)):
<<<$i

Try it online!

Completely new method courtesy of JoKing's Perl 6 submission, but doesn't work on large strings (n>20) due to integer size restrictions. $@[(I)$i] is reverse array lookup to largest index, it will output zero (falsy in arithmetic expansion) if $i is not found in the command line parameters.

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

MATL, 12 bytes

c"1Y2@X-1)&h

Input is a cell array of strings containing printable ASCII chars. The output is formed from the letters 'ABC', and so belongs to the input domain.

Try it online!

Explanation

The output is as long as the longest input string. Its n-th character is the first letter from 'ABC' that is different from the n-th character of both input strings.

c        % Concatenate the two strings vertically. If one is shorter it is
         % right-padded with spaces. Gives a 2-row character matrix
"        % For each column
  1Y2    %   Push the string 'ABC...Z' (the upper-case letters)
  @      %   Push current column
  X-     %   Set difference
  1)     %   Get first character
  &h     %   Horizontally concatenate the results so far
         % End (implicit). Display stack (implicit)
\$\endgroup\$
3
\$\begingroup\$

Haskell, 56 52 48 bytes

x#y|_:t<-max x y=[c:t|c<-"abc",c:t/=x,c:t/=y]!!0

Try it online!

Replace the first char of the maximum of the two input strings with a, band c and pick the first one that is different from both input strings.

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

Ruby, 53 bytes

->a,b{([?a,?b,?c].map{|e|e*[a,b].max.size}-[a,b])[0]}

Try it online!

Basically generates the strings a...a, b...b, and c...c and selects the first not in the input.

\$\endgroup\$
  • 1
    \$\begingroup\$ Fails if the first input is the empty string. \$\endgroup\$ – Silvio Mayolo Aug 20 '17 at 3:50
  • \$\begingroup\$ @SilvioMayolo fixed \$\endgroup\$ – Conor O'Brien Aug 20 '17 at 3:53
  • \$\begingroup\$ 42 bytes \$\endgroup\$ – iamnotmaynard Dec 15 '17 at 4:53
3
\$\begingroup\$

ES6, 54 bytes

a=>b=>(a[0]+b[0]|0?'a':9-(a[0]^b[0]))+(a||b).substr(1)
\$\endgroup\$
  • \$\begingroup\$ Welcome to PPCG :) \$\endgroup\$ – Shaggy Aug 22 '17 at 9:57
3
\$\begingroup\$

Pyth, 7 8 bytes

hC-LG.T

1 byte thanks to Jakube

Test suite

We use .T, length preserving transpose, rather than C, truncating transpose, so that it works on inputs where one string is empty.

Given two strings as a tuple, we transpose them (.T), then map the resulting pair of characters or single character by subtracting the character(s) from the lowerase alphabet with -LG, then transpose the resulting list of strings of unused characters with C, then return the first such string with h. This consists of the first letter alphabetically that is not in either string, for each position.

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

Java (OpenJDK 8), 100 73 bytes

-27 bytes thanks to @Nevay's magical touch! :)

a->b->{b=b.length<1?a:b;if(a.length<1||(b[0]^=2)==a[0])b[0]^=1;return b;}

Try it online!

Input domain = Printable ASCII + codepoint 127.

\$\endgroup\$
  • 2
    \$\begingroup\$ 73 bytes \$\endgroup\$ – Nevay Aug 22 '17 at 11:27
2
\$\begingroup\$

Ruby, 56 bytes

->a,b{a,b=b,a if a<b;a[0]=([?a,?b,?c]-[a[0],b[0]])[0];a}
\$\endgroup\$
2
\$\begingroup\$

Pyth, 23 22 bytes

+.)-.{<G3.{,<Q1<KE1t|K

Try it here!

Pyth, 22 bytes

+eS-.{<G3.{,<Q1<KE1t|K

Test Suite!


Explanation

+.)-.{<G3.{,<Q1<KE1t|K  - Full program.
      <G3               - Yields the String "abc"; Alphabet[:3].
    .{                  - Set formed by the above.
         .{,<Q1<KE1     - Set formed by input_1[:1] and input_2[:1]
   -                    - Set subtraction.
 .)                     - Pop the last element.
+                       - Append.
                   t|K  - input_1[1:] or input_2[1:], relying on the result of Logical OR.
\$\endgroup\$
2
\$\begingroup\$

Perl 5, 82 79 bytes

sub{$_=$_[0];$_=$_[1]||$_ if/^(xz*)?$/;s/[^z]/z/||s/./y/;$_ eq$_[1]&&s/./x/;$_}

Takes input as two separate arguments and returns the third string.

The subroutine attempts to produce a string very similar to the first string but with the first non-z character replaced with a z. Then it deals with corner cases by replacing the first character with y or x, as needed, if it finds that one of the inputs was in fact a sequence of all z's.

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

Perl 5, 68 bytes

sub{$_="a"x length $_[0]||$_[1];$_++while $_ eq$_[0]||$_ eq$_[1];$_}

Explanation:

  • starts with (string of letter "a" as long as first string) or second string if that is false i.e. zero-length
  • keeps incrementing that until it's different from both first and second

Starting from "a"s was to avoid incrementing to point where Perl lengthens the string; with only two strings to avoid being same as, it couldn't overflow.

Execute with:

perl -e '$s = ' -E 'sub{$_="a"x length $_[0]||$_[1];$_++while $_ eq$_[0]||$_ eq$_[1];$_}' -E ';say $s->("z", "true")'
\$\endgroup\$
  • 1
    \$\begingroup\$ I think this will fail if the first string is empty. \$\endgroup\$ – Ørjan Johansen Aug 20 '17 at 23:26
  • \$\begingroup\$ Quite right! Fixed. \$\endgroup\$ – Ed. Aug 20 '17 at 23:51
2
\$\begingroup\$

C (gcc), 70 65 73 67 61 bytes

The function needs the provided strings to be mutable (i.e. either arrays or dynamically allocated).

f(a,b)char*a,*b;{a=*a?a:b;*a=*a>70?33:99;*a+=*a==*b;puts(a);}

Try it online!

Works for the standard ASCII range

Explanation:

a=*a?a:b           // If a is empty, point to b instead
*a=*a>70?33:99     // Choose a different value for the 1st character of a,
                   // while giving enough space to increment it without 
                   // going back to its previous value
*a+=*a==*b         // Increment the 1st character of a if the arbitrary
                   // chosen value is equal to the value of the 1st 
                   // character of b
puts(a)            // Outputs a
\$\endgroup\$
  • 1
    \$\begingroup\$ I'm not sure this can be given a consistent input domain satisfying the rules. What if *a==255 and *b==0? \$\endgroup\$ – Ørjan Johansen Aug 21 '17 at 16:04
  • \$\begingroup\$ You're right. Fixed, at the cost of 8 bytes. \$\endgroup\$ – scottinet Aug 22 '17 at 9:33
  • \$\begingroup\$ There. I couldn't let this solution have the same bytecount than the Java one! :-) \$\endgroup\$ – scottinet Aug 22 '17 at 13:10
  • \$\begingroup\$ If you don't restrict to printable ASCII then you could use single-digit numbers. \$\endgroup\$ – Ørjan Johansen Aug 22 '17 at 16:18
  • \$\begingroup\$ Unless I misunderstood, that would be against this challenge rules. \$\endgroup\$ – scottinet Aug 22 '17 at 18:40
2
\$\begingroup\$

R, 89 67 bytes

@Giuseppe saved 9 bytes, @user2390246 saved 13 bytes

function

function(x,y)sub("^.",letters[!letters%in%substr(c(x,y),1,1)][1],x)

demo

# define function
f <- function(x,y)sub("^.",letters[!letters%in%substr(c(x,y),1,1)][1],x)

# test cases
f("test","test")
[1] "aest"
f("do","don't")
[1] "ao"
f("ye s","yes")
[1] "ae s"
f("maybe","mayue")
[1] "aaybe"
f("false","false")
[1] "aalse"
f("false","true")
[1] "aalse"
f("1","")
[1] "a"
f("art","bug")
[1] "crt"
\$\endgroup\$
  • 1
    \$\begingroup\$ You can put x and y within the same substr command. Also, curly braces and return are unnecessary: function(x,y)sub("^.",letters[!letters%in%substr(c(x,y),1,1)][1],x) \$\endgroup\$ – user2390246 Aug 21 '17 at 11:06
  • 1
    \$\begingroup\$ You can get rid of return since this is a function, and the braces since it's a one liner. \$\endgroup\$ – Giuseppe Aug 21 '17 at 13:14
  • \$\begingroup\$ Shoot, I just realized that f("","1") yields "", which is equal to the first input... maybe this should be added as another test case \$\endgroup\$ – Slow loris Aug 22 '17 at 23:19
2
\$\begingroup\$

Java 8, 119 bytes

Lambda (curried) from String to lambda from String to String. Assign to Function<String, Function<String, String>>.

s->t->{String r=s.length()>t.length()?s:t;while((s+t).contains(r))r=r.substring(1)+(char)(Math.random()*128);return r;}

Try It Online

Ungolfed lambda

s ->
    t -> {
        String r = s.length() > t.length() ? s : t;
        while ((s + t).contains(r))
            r = r.substring(1) + (char) (Math.random() * 128);
        return r;
    }

This solution rotates random ASCII characters into the longer string until the required conditions are satisfied. Inputs are UTF-8 and outputs are ASCII.

I don't know the gritty details of Unicode, but it seems plausible to me that this solution could fail when an appended char joins the preceding code point to form a single code unit. If someone who knows more about this can verify this, I'll change the input domain to ASCII.

Java 8, 126 bytes

Same type as above.

s->t->{String r;for(byte[]o=(s.length()>t.length()?s:t).getBytes();(s+t).contains(r=new String(o));o[0]%=128)o[0]++;return r;}

Try It Online

Ungolfed lambda

s ->
    t -> {
        String r;
        for (
            byte[] o = (s.length() > t.length() ? s : t).getBytes();
            (s + t).contains(r = new String(o));
            o[0] %= 128
        )
            o[0]++;
        return r;
    }

This increments the first byte of the longer string, wrapping within ASCII, until the required conditions are met. Inputs and outputs are ASCII strings.

\$\endgroup\$
  • 1
    \$\begingroup\$ Given the output of your third test case, it outputs a string of length three: Try it online! \$\endgroup\$ – Stephen Aug 19 '17 at 1:35
  • \$\begingroup\$ Ah, crap. Now I'm going to have to learn how Unicode works in order to fix this without exploding the byte count... \$\endgroup\$ – Jakob Aug 19 '17 at 2:02
2
\$\begingroup\$

APL (Dyalog Unicode), 11 bytesSBCS

Full program, takes input as a 2-element nested list.

⊃¨⎕A∘~¨,⌿↑⎕

Try it online!

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

Bash, 115 .. 77 bytes

Replaces first char of the first (non-empty) input string with 1,2,3 until no match is found to either input. Try it Online!

-9, -12, -9, -8 bytes all thanks to GammaFunction

x="${1:-$2}"
for s in {1..3}"${x:1}"
{ [[ $s = @($1|$2) ]]||break;}
echo "$s"

(quite an improvement over the original...)

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

Perl 5, 79 + 1 (-p) = 80 bytes

$"=<>;chop;$_=length($,=$_)>length$"?$_:$";s/./chr$&+65+$i++/e while/^($"|$,)$/

Try it online!

\$\endgroup\$
  • 1
    \$\begingroup\$ Fails if the two strings are of different length \$\endgroup\$ – Halvard Hummel Aug 18 '17 at 23:07
  • \$\begingroup\$ I noticed that. Just revised it. \$\endgroup\$ – Xcali Aug 18 '17 at 23:08
1
\$\begingroup\$

Japt, 17 bytes

;B¬£ñl g1 çXÃkU v

Repeats the letters A-Z to the length of the longer input, removes the values in the input, and get the first item in the array.

Try it online!

Old solution, 18 bytes

;@!UøX}a@ñl g1 çBö

Try it online!

Chooses a random character from the alphabet and repeats it to the length of the longer input string, until it is not present in the input.

\$\endgroup\$
  • \$\begingroup\$ Failed for ["abcdefghijklmnopqrstuvwxyz", "AAAAAAAAAAAAAAAAAAAAAAAAAA"]. When running it multiple times, it returned "AAAAAAAAAAAAAAAAAAAAAAAAAA" (just like my Pyth answer did, until I fixed that) \$\endgroup\$ – Mr. Xcoder Aug 18 '17 at 23:48
  • \$\begingroup\$ It fails for ["D", ""]. if you run it several times you'll get "D" \$\endgroup\$ – J42161217 Aug 18 '17 at 23:50
  • \$\begingroup\$ Thanks, I figured there were some cases I hadn't tested. Fixed for only +1 byte. \$\endgroup\$ – Justin Mariner Aug 18 '17 at 23:58
  • \$\begingroup\$ Ì should work in place of g1 for a 2 byte saving (in a 2 element array g1=gJ) but there appears to be a bug with Ì when using ;. \$\endgroup\$ – Shaggy Aug 22 '17 at 10:09
  • \$\begingroup\$ @Shaggy Yeah, I think that's cause J is no longer -1 because of the ; changing it to ,. That's why I used 1 in the first place. \$\endgroup\$ – Justin Mariner Aug 22 '17 at 10:10
1
\$\begingroup\$

Python 3, 74 73 bytes

-1 byte thanks to Step Hen

def f(x,y,i=1):
 while i*10<10**len(x or y)or str(i)in x+y:i*=2
 print(i)

Prints lowest integer with the same length as the first of the inputs that has nonzero length.

\$\endgroup\$
  • \$\begingroup\$ Save a byte with i as a default function parameter: def f(x,y,i=1):. I think you can save another byte with while10*i but I'm not sure. \$\endgroup\$ – Stephen Aug 19 '17 at 0:53
  • \$\begingroup\$ You can replace while i*10<10**len(x or y)or str(i)in x+y with while i<10**~-len(x or y)or str(i)in x+y (72 bytes) \$\endgroup\$ – Mr. Xcoder Aug 20 '17 at 19:34
  • \$\begingroup\$ And you can also use recursion to save bytes: f=lambda x,y,i=1:(i<10**~-len(x or y)or str(i)in x+y)and f(x,y,i*2)or i (71 bytes) \$\endgroup\$ – Mr. Xcoder Aug 20 '17 at 19:38
1
\$\begingroup\$

Python 2, 77 bytes

a=input()
b=ord(a[0][0])+1
if b==ord(a[1][0]):b+=1
print unichr(b)+a[0][1:-1]

I think it has some potential. The idea is that it adds 1 to the 1st char in the 1st string, then checks if the other input's 1st char is the same.

**Note, ^ doesn't handle 0 length strings, so it doesn't really work at this length.

Here's a super long solution that works with 0 length

146 Bytes

a=input()
def c(i):print unichr(ord(a[i][0])+1)+a[i][1:];exit();
for x in range(2):if len(a[x-1])<1:c(x)
if a[0]==a[1]:c(1)
print a[1][0]+a[0][1:]

Any improvements would be appreciated!

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

CJam, 31 30 23 bytes

q~:A:e>,3,sf*{A\f=:+!}=

Takes printable ASCII as input. Outputs either a string of 0's, 1's, or 2's that is the same length as one of the input strings. The logic is that one of those can't be either of the input strings!

Try it Online

q~:A    e# Store input array as var 'A'
:e>,    e# Take the length of the lexicographically greater string in the input array
3,s     e# Generate "012"
f*      e# Repeat each number as many times as the longer string length, yielding something like ["000","111","222"]
{       e# Search array of number strings for first that returns true for this function
A\f=    e# Map each string in the input array to whether it equals the current number string (0,1)
:+!     e# Add up the array of bits and take the logical not. This returns true iff both array values were not equal to the current number string.
}=      e# Return the first number string that returns true.
\$\endgroup\$
  • \$\begingroup\$ Anyone have any ideas on how to return true only if both bits in the array are false (NOR)? Currently, I'm doing :+!. \$\endgroup\$ – geokavel Aug 19 '17 at 1:46
1
\$\begingroup\$

C# (Mono), 94 bytes

s=>t=>{var r=s!=""?s:t;while(r==s|r==t)r=r.Substring(1).Insert(0,(char)(r[0]+1)+"");return r;}

Try it online!

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