TransWikia.com

The Third String

Code Golf Asked by Stephen on September 5, 2020

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.

36 Answers

05AB1E, 8 7 bytes

øvAyм¬?

Uses the 05AB1E encoding. Try it online!

Correct answer by Adnan on September 5, 2020

Brachylog, 10 bytes

∋l~lℕṫ.&≡ⁿ

Try it online!

Explanation

There may be a better way to do this, but I've been fighting Brachylog strings for a while now and this solution works.

∋           For some element of the input list
 l          get its length
  ~l        That is also the length of
    ℕ       some positive integer
     ṫ      Converting that integer to a string
      .     is the output
       &    Also:
         ⁿ  It is not true, for any X in the input list
        ≡   that the output equals X

Outputs strings like "100". If "100" is already in the input list, goes to "101", etc.

Answered by DLosc on September 5, 2020

JavaScript (Node.js), 39 bytes

a=>b=>(a[0]&1^b[0]&2^7)+(a||b).slice(1)

Try it online!

Obvious source the 3rd byte

Answered by l4m2 on September 5, 2020

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

Answered by Jo King on September 5, 2020

APL (Dyalog Unicode), 11 bytesSBCS

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

⊃¨⎕A∘~¨,⌿↑⎕

Try it online!

Answered by voidhawk on September 5, 2020

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

Answered by DLosc on September 5, 2020

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.

Answered by DLosc on September 5, 2020

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

Answered by roblogic on September 5, 2020

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.

Answered by Sara J on September 5, 2020

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.

Answered by GammaFunction on September 5, 2020

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!

Answered by TheLethalCoder on September 5, 2020

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.

Answered by Olivier Grégoire on September 5, 2020

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

Answered by scottinet on September 5, 2020

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

Answered by Ed. on September 5, 2020

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.

Answered by isaacg on September 5, 2020

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"

Answered by Slow loris on September 5, 2020

ES6, 54 bytes

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

Answered by Fermyon on September 5, 2020

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.

Answered by Silvio Mayolo on September 5, 2020

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.

Answered by Conor O'Brien on September 5, 2020

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

Answered by betaveros on September 5, 2020

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

Answered by Quelklef on September 5, 2020

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.

Answered by nimi on September 5, 2020

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!

Answered by Braeden Smith on September 5, 2020

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.

Answered by Jakob on September 5, 2020

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.

Answered by benzene on September 5, 2020

CJam, 31 30 23 bytes

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

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

Answered by geokavel on September 5, 2020

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

Answered by Neil on September 5, 2020

Haskell, 41 bytes

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

Answered by Leif Willerts on September 5, 2020

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

Answered by Jonathan Allan on September 5, 2020

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.

Answered by Justin Mariner on September 5, 2020

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)

Answered by Luis Mendo on September 5, 2020

Ruby, 56 bytes

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

Answered by m-chrzan on September 5, 2020

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

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

Try it online!

Answered by Xcali on September 5, 2020

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.

Answered by Mr. Xcoder on September 5, 2020

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!

Answered by Halvard Hummel on September 5, 2020

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

Answered by J42161217 on September 5, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP