The Third String

46

3

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.

Stephen

Posted 2017-08-18T22:08:43.057

Reputation: 12 293

Related, Sandbox – Stephen – 2017-08-18T22:08:54.970

Can my code fail for MaxChar in input, but be able to output it? – H.PWiz – 2017-08-18T22:27:33.540

@H.PWiz no. if it can be outputted, it has to be able to be inputted, otherwise you could just do MaxChar.repeat(s1.length) – Stephen – 2017-08-18T22:28:25.563

That makes sense – H.PWiz – 2017-08-18T22:28:50.413

14This 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. – geokavel – 2017-08-18T22:47:34.670

Test case: abcdefghijklmnopqrstuvwxyz and aaaaaaaaaaaaaaaaaaaaaaaaaa. Mine failed for it – Mr. Xcoder – 2017-08-18T23:11:55.093

2I understand the output domain can be a subset of the input domain, yes? – Luis Mendo – 2017-08-18T23:21:58.320

@LuisMendo yes. – Stephen – 2017-08-18T23:25:09.620

1Will the two inputs ever both be an empty string? – kamoroso94 – 2017-08-19T15:53:28.393

1@kamoroso94 no, because there is guaranteed to be a valid output. – Stephen – 2017-08-19T18:28:07.407

2Nice question! I like it. – isaacg – 2017-08-20T22:16:58.287

For "1", "" may we output ""? – Quelklef – 2017-08-21T02:55:10.160

2@Quelklef No, that's not different from both inputs. – Ørjan Johansen – 2017-08-21T02:58:08.297

@ØrjanJohansen Of course. Thanks. – Quelklef – 2017-08-21T03:02:47.087

3I 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 – Slow loris – 2017-08-22T23:20:50.810

I'm pretty sure the point of @Slowloris 's request was to have the empty string as the first one. – Ørjan Johansen – 2017-08-23T01:04:21.590

Suggested test case: both input strings are longer than 256 characters. – DLosc – 2019-03-26T02:17:40.613

@DLosc added, thanks – Stephen – 2019-03-26T02:27:13.003

Answers

3

05AB1E, 8 7 bytes

øvAyм¬?

Uses the 05AB1E encoding. Try it online!

Adnan

Posted 2017-08-18T22:08:43.057

Reputation: 41 965

1Does this work when one input is the empty string? – betaveros – 2017-08-21T03:52:19.793

4

Doesn't work if the first string is empty. TIO

– Jo King – 2019-03-26T04:30:33.253

14

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

betaveros

Posted 2017-08-18T22:08:43.057

Reputation: 741

9

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

Quelklef

Posted 2017-08-18T22:08:43.057

Reputation: 441

Your "fact" is wrong, e.g. a=2, b=1. You need to add instead of subtracting. – Ørjan Johansen – 2017-08-21T03:03:48.600

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. – Ørjan Johansen – 2017-08-21T03:21:11.180

@ØrjanJohansen Oh you're right, it can equal b. But not a. – Quelklef – 2017-08-21T03:36:23.753

@ØrjanJohansen Ah, that appears to work! Good thinking! – Quelklef – 2017-08-21T03:41:21.053

@Ø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. – Quelklef – 2017-08-21T03:42:29.267

It could still break if S and F are equal after the first character. – Ørjan Johansen – 2017-08-21T03:44:58.987

Let us continue this discussion in chat.

– Quelklef – 2017-08-21T03:45:17.093

6

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

Jonathan Allan

Posted 2017-08-18T22:08:43.057

Reputation: 67 804

It returns B TIO

– Jonathan Allan – 2017-08-19T11:35:29.063

The algorithm shouldn't anyway, not sure what you did. – Jonathan Allan – 2017-08-19T11:37:58.130

nevermind my brain apparently playing tricks since I don't see any X or in there... – Erik the Outgolfer – 2017-08-19T11:39:35.473

5

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!

Halvard Hummel

Posted 2017-08-18T22:08:43.057

Reputation: 3 131

{"a","b","c"} ==> {*"abc"} (57 bytes) – Mr. Xcoder – 2017-08-18T22:35:37.247

(x[1:]or y[1:]) ==> max(x,y)[1:]? – betaveros – 2017-08-19T01:43:06.913

Or just (x or y)[1:], I think you only need to avoid the empty string. – betaveros – 2017-08-19T01:58:49.293

Incidentally, it's a shame Python 2 doesn't have starred set literals, because I really wanted to golf {*"abc"} into {*`id`}... – betaveros – 2017-08-19T20:10:51.267

Save 1 with *len(x or y) instead of +max(x,y)[1:]. – Chas Brown – 2019-03-30T22:15:06.423

4

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

J42161217

Posted 2017-08-18T22:08:43.057

Reputation: 15 931

How do I test this online again? – Stephen – 2017-08-18T22:29:37.643

added link+info – J42161217 – 2017-08-18T22:33:16.553

@Jenny_mathy Seems to fail if the first string is the empty string – Halvard Hummel – 2017-08-18T23:10:31.027

2@HalvardHummel fixed! – J42161217 – 2017-08-18T23:21:30.980

why the downvote??? – J42161217 – 2017-08-18T23:56:25.990

I downvoted because there's still a lot of easy golfing that can be done to this: try (While[f=Alphabet[]~RandomChoice~Length@#;f==#]&[#&@@Characters@{##}~MaximalBy~Length];""<>f)&. But after looking at it some more, I think it's invalid — if the two strings are equal in length there's a small chance of returning one of them, since you only check if the random string is equal to one of the two. – Not a tree – 2017-08-19T00:33:08.493

1@Notatree fixed. If you think that "easy golfing" is a reason for downvoting then you are welcome to do so – J42161217 – 2017-08-19T00:44:55.707

…I suppose that was quite harsh of me. I'm sorry. Downvote reversed. – Not a tree – 2017-08-19T00:49:20.830

you don't have to upvote either... anyways I'll try to implement your version.thanx – J42161217 – 2017-08-19T00:51:26.363

4

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

Neil

Posted 2017-08-18T22:08:43.057

Reputation: 95 035

4

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.

GammaFunction

Posted 2017-08-18T22:08:43.057

Reputation: 2 838

4

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

Jo King

Posted 2017-08-18T22:08:43.057

Reputation: 38 234

Is the incrementor a bigint type, or will this overflow for sufficiently large strings? – GammaFunction – 2019-03-26T05:45:19.520

1@GammaFunction In Perl 6, the default number type is Int, which has infinite precision – Jo King – 2019-03-26T05:49:24.023

Oh, nice. I was going to adapt this to Zsh, but it uses long long unfortunately. – GammaFunction – 2019-03-26T05:53:48.590

You can trim 6 bytes by just taking the first of 00..,111..,22.. instead of counting and sequences: https://tio.run/##K0gtyjH7n1upoJamYKvwvzots6i4REHrUUenSryORpyxQkSFtl5uYoVecn5ukmbt/@LESoU0jWglQwMDJR0gaagUq2nNBRO1BIpZAmWQxZR0FJRKUotLUATBAkAJFEFDIAAaYGAANeE/AA

– Phil H – 2019-03-26T10:22:50.760

@PhilH Good idea! I've shortened it a bit more by keeping with the sequence idea – Jo King – 2019-03-26T11:46:49.667

3

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)

Luis Mendo

Posted 2017-08-18T22:08:43.057

Reputation: 87 464

3

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.

nimi

Posted 2017-08-18T22:08:43.057

Reputation: 34 639

3

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.

Conor O'Brien

Posted 2017-08-18T22:08:43.057

Reputation: 36 228

1Fails if the first input is the empty string. – Silvio Mayolo – 2017-08-20T03:50:47.610

@SilvioMayolo fixed – Conor O'Brien – 2017-08-20T03:53:11.677

42 bytes – Reinstate Monica -- notmaynard – 2017-12-15T04:53:48.063

3

ES6, 54 bytes

a=>b=>(a[0]+b[0]|0?'a':9-(a[0]^b[0]))+(a||b).substr(1)

Fermyon

Posted 2017-08-18T22:08:43.057

Reputation: 31

Welcome to PPCG :) – Shaggy – 2017-08-22T09:57:46.217

3

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.

isaacg

Posted 2017-08-18T22:08:43.057

Reputation: 39 268

3

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.

Olivier Grégoire

Posted 2017-08-18T22:08:43.057

Reputation: 10 647

273 bytes – Nevay – 2017-08-22T11:27:16.420

2

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.

Mr. Xcoder

Posted 2017-08-18T22:08:43.057

Reputation: 39 774

2

Ruby, 56 bytes

->a,b{a,b=b,a if a<b;a[0]=([?a,?b,?c]-[a[0],b[0]])[0];a}

m-chrzan

Posted 2017-08-18T22:08:43.057

Reputation: 1 390

2

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.

Jakob

Posted 2017-08-18T22:08:43.057

Reputation: 2 428

1

Given the output of your third test case, it outputs a string of length three: Try it online!

– Stephen – 2017-08-19T01:35:06.333

Ah, crap. Now I'm going to have to learn how Unicode works in order to fix this without exploding the byte count... – Jakob – 2017-08-19T02:02:20.560

2

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.

Silvio Mayolo

Posted 2017-08-18T22:08:43.057

Reputation: 1 817

2

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"

Slow loris

Posted 2017-08-18T22:08:43.057

Reputation: 211

1You 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) – user2390246 – 2017-08-21T11:06:54.137

1You can get rid of return since this is a function, and the braces since it's a one liner. – Giuseppe – 2017-08-21T13:14:10.933

Shoot, I just realized that f("","1") yields "", which is equal to the first input... maybe this should be added as another test case – Slow loris – 2017-08-22T23:19:08.860

2

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

Ed.

Posted 2017-08-18T22:08:43.057

Reputation: 141

1I think this will fail if the first string is empty. – Ørjan Johansen – 2017-08-20T23:26:58.250

Quite right! Fixed. – Ed. – 2017-08-20T23:51:51.303

2

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

scottinet

Posted 2017-08-18T22:08:43.057

Reputation: 981

1I'm not sure this can be given a consistent input domain satisfying the rules. What if *a==255 and *b==0? – Ørjan Johansen – 2017-08-21T16:04:45.277

You're right. Fixed, at the cost of 8 bytes. – scottinet – 2017-08-22T09:33:32.017

There. I couldn't let this solution have the same bytecount than the Java one! :-) – scottinet – 2017-08-22T13:10:29.263

If you don't restrict to printable ASCII then you could use single-digit numbers. – Ørjan Johansen – 2017-08-22T16:18:19.153

Unless I misunderstood, that would be against this challenge rules. – scottinet – 2017-08-22T18:40:22.683

Hm I don't understand it that way, see Luis Mendo's question comment. You must be able to input any character you output, but not vice versa. – Ørjan Johansen – 2017-08-22T22:57:51.583

Of course, but there is also the first rule: You may chose your input domain, but it must be composed of at least printable ASCII. And I don't see characters 0 to 6 (included) as printable ASCII characters, leaving us with only 3 "printable" characters (this is debatable for chars 7 & 8). And I need at least 4 consecutive chars to force a different one for one of the provided strings. – scottinet – 2017-08-23T07:42:20.473

The first rule means that you have to accept all printable ASCII characters. You can accept whatever other characters you want, otherwise there would be nothing to choose. – Ørjan Johansen – 2017-08-23T17:05:37.857

2

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

roblogic

Posted 2017-08-18T22:08:43.057

Reputation: 554

1

Nice method! You can use = and || in the last line, and use ${x:-empty_fallback} to remove the starting ternary. Also, you do need quotes on the ending echo for the case of trailing spaces. Obligatory TIO

– GammaFunction – 2019-03-26T03:32:14.930

Thanks! Couldn't figure out how to use "empty fallback" though – roblogic – 2019-03-26T04:06:54.093

1Here's the TIO link, 94 bytes – GammaFunction – 2019-03-26T04:09:03.883

1

I like what you're going for with the shift, I got it to tie my method in two different methods.

– GammaFunction – 2019-03-26T04:12:26.787

1Whoops, I found another change: @($1|$2) pattern matching – GammaFunction – 2019-03-26T04:27:22.033

Thanks for the ideas, I never knew about fallback and @-pattern-matching

– roblogic – 2019-03-26T04:44:02.480

1Umm, I.. uh... did some more things – GammaFunction – 2019-03-27T10:42:26.800

2

APL (Dyalog Unicode), 11 bytesSBCS

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

⊃¨⎕A∘~¨,⌿↑⎕

Try it online!

voidhawk

Posted 2017-08-18T22:08:43.057

Reputation: 1 796

1

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

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

Try it online!

Xcali

Posted 2017-08-18T22:08:43.057

Reputation: 7 671

1Fails if the two strings are of different length – Halvard Hummel – 2017-08-18T23:07:45.203

I noticed that. Just revised it. – Xcali – 2017-08-18T23:08:44.960

1

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.

Justin Mariner

Posted 2017-08-18T22:08:43.057

Reputation: 4 746

Failed for ["abcdefghijklmnopqrstuvwxyz", "AAAAAAAAAAAAAAAAAAAAAAAAAA"]. When running it multiple times, it returned "AAAAAAAAAAAAAAAAAAAAAAAAAA" (just like my Pyth answer did, until I fixed that) – Mr. Xcoder – 2017-08-18T23:48:15.850

It fails for ["D", ""]. if you run it several times you'll get "D" – J42161217 – 2017-08-18T23:50:45.467

Thanks, I figured there were some cases I hadn't tested. Fixed for only +1 byte. – Justin Mariner – 2017-08-18T23:58:03.280

Ì 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 ;. – Shaggy – 2017-08-22T10:09:10.777

@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. – Justin Mariner – 2017-08-22T10:10:52.883

Ah, of course, hadn't thought of that being the problem. – Shaggy – 2017-08-22T10:11:27.033

1

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.

geokavel

Posted 2017-08-18T22:08:43.057

Reputation: 6 352

Anyone have any ideas on how to return true only if both bits in the array are false (NOR)? Currently, I'm doing :+!. – geokavel – 2017-08-19T01:46:20.917

1

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.

benzene

Posted 2017-08-18T22:08:43.057

Reputation: 257

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. – Stephen – 2017-08-19T00:53:30.023

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)

– Mr. Xcoder – 2017-08-20T19:34:55.253

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)

– Mr. Xcoder – 2017-08-20T19:38:24.080

1

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!

Braeden Smith

Posted 2017-08-18T22:08:43.057

Reputation: 61

1

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!

TheLethalCoder

Posted 2017-08-18T22:08:43.057

Reputation: 6 930

1

Python 3, 67 bytes

lambda a,b:[k for k in"abc"if k not in b[:1]+a[:1]][0]+(a or b)[1:]

Try it online!

Picks the first character of "a", "b", and "c" which neither string begins with - all three characters can't be the first character of one of two strings. The first character of a is then replaced with that character, unless a is empty, in which case the first character in b is replaced instead.

Sara J

Posted 2017-08-18T22:08:43.057

Reputation: 2 576

1

Pip, 16 bytes

T#iN#*g&iNIg++ii

Try it online!

Increments the number i until i has the same length as one of the inputs and does not equal either of the inputs, and then prints i. Takes about 30 seconds on TIO to output 100000 for length-six input.

DLosc

Posted 2017-08-18T22:08:43.057

Reputation: 21 213

1

Pip, 16 bytes

YMXgRXX9WyNg--yy

Try it online!

Different approach from my first submission (and much faster):

   g              List of command-line args     ["abc" "9999"]
    R             Replace
     XX           any character (regex `.`)
       9          with 9                        ["999" "9999"]
 MX               Get the max                   9999
Y                 Yank it into y variable
        W         Loop while
         yNg      y is in the cmdline args:
            --y    Decrement y
               y  Output y                      9998

DLosc

Posted 2017-08-18T22:08:43.057

Reputation: 21 213

-1

Haskell, 41 bytes

n[]_=[]
n _[]=[]
n(i:c)(h:t)=succ i:n c t

Leif Willerts

Posted 2017-08-18T22:08:43.057

Reputation: 1 060

4The empty string isn't a valid output if one of the inputs is an empty string... – betaveros – 2017-08-19T03:59:07.760

3It fails if the string starts with '\1114111'. – nimi – 2017-08-19T16:16:23.277