38
\$\begingroup\$

Write a program that takes 2 strings as input, and returns the longest common prefix. This is , so the answer with the shortest amount of bytes wins.

Test Case 1:

"global" , "glossary"
"glo"


Test Case 2:

"department" , "depart"
"depart"

Test Case 3:

"glove", "dove"
""
\$\endgroup\$
7
  • 3
    \$\begingroup\$ Do you want a complete programs that inputs from STDIN and prints to STDOUT, or are functions OK? \$\endgroup\$
    – xnor
    Commented Nov 3, 2015 at 19:35
  • 3
    \$\begingroup\$ Can we assume the input won't have newlines? Which characters will the input have? \$\endgroup\$
    – Downgoat
    Commented Nov 3, 2015 at 23:59
  • 7
    \$\begingroup\$ General note: People using a regex based solution should not copy other people's regex answers without testing them yourself; this does not work in all regex engines. In particular, it gives different (both incorrect) answers in nvi and vim. \$\endgroup\$
    – Random832
    Commented Nov 4, 2015 at 16:38
  • 2
    \$\begingroup\$ All of the examples given are in lowercase, but do we need to worry about case sensitivity? For example, should global and GLOSSARY return glo or ''? \$\endgroup\$ Commented Nov 5, 2015 at 16:08
  • 2
    \$\begingroup\$ Can it return the length? \$\endgroup\$
    – S.S. Anne
    Commented Mar 13, 2020 at 17:45

76 Answers 76

1 2
3
1
\$\begingroup\$

Nekomata, 5 bytes

ᵃp=al

Attempt This Online!

ᵃp=al
ᵃp      Non-deterministically choose a prefix of both inputs
  =     Check if the two prefixes are equal
   al   Find the last possible solution, which is the longest
\$\endgroup\$
1
\$\begingroup\$

R, 71 bytes (the function-only version: 49 bytes)

A recursive approach with regex:

s=scan(,"");`?`=\(a,b)`if`(regexpr(b,a)-1,a?sub(".$","",b),b);s[1]?s[2]

Attempt This Online!

  1. Checks if one string matches the beginning of another one.
  2. If true, the substring is output.
  3. Else remove the last character from the substring, pass to the function and call it again.

Matching substrings:

# R, 80 bytes

s=scan(,"");a=s[1];b=s[2];`+`=\(x)substring(x,1,1:nchar(a));max((+a)[+a==+b],"")

Attempt This Online!

Creates all possible sequential substrings that start from the 1st character for the both strings, subset for those that match and output the longest one.

An attempt to use a built-in abbreviate

# R, 48 bytes

sub(".$","",max(abbreviate(scan(,""),1,F,,,,F)))

Attempt This Online!

Note: unfortunately, this is not a valid answer, as it would fail if the provided strings contain a " ", "\t" or similar. We assume that, if not otherwise specified, an input string might contain at least a space symbol.

\$\endgroup\$
0
\$\begingroup\$

K, 45 bytes

{*|(*v)@{&y~'x}.#[&/#:'v;]'v:{#[;x]'1+!#x}'x}

Takes input as a 2-element list.

\$\endgroup\$
0
\$\begingroup\$

Swift, 34 bytes

import UIKit "global".commonPrefixWith("glossary")

But with Swift 2 it is actually more like: "global".commonPrefixWithString("glossary",options:.CaseInsensitiveSearch)

\$\endgroup\$
0
\$\begingroup\$

C#, 112 bytes

class P{static void Main(string[]a){try{for(int i=0;a[0][i]==a[1][i];)System.Console.Write(a[0][i++]);}catch{}}}

Newlines and indentation for clarity:

class P{
    static void Main(string[]a){
        try{
            for(int i=0;a[0][i]==a[1][i];)
                System.Console.Write(a[0][i++]);
        }
        catch{}
    }
}
\$\endgroup\$
0
\$\begingroup\$

Minkolang 0.10, 21 bytes

(od" "=,)x(0gdo=?.O1)

Expects input as two words, space-separated, like so: department depart. Try it here.

Explanation

(od" "=,)      Loops through input until a space is encountered
x              Dumps extraneous space
(0gdo=   1)    Loops through second word and compares letters
      ?.O      Halts if two letters are not equal, outputs them otherwise
\$\endgroup\$
0
\$\begingroup\$

pb, 105 bytes

^w[B!32]{>}>w[B!0]{t[B]vb[1]<[X]w[B!0]{>}b[T]w[B!1]{>}b[0]^>}v<[X]<t[0]w[T=0]{>t[B]^t[T-B]v}w[B!0]{b[0]>}

Takes two words separated by a single space. (I can save a byte by using a tab instead but that feels like cheating.)

In pb, the area that can be written to is thought of as a 2D space, with (0, 0) in the upper left. Additionally, input is initially kept at Y=-1. This program copies the second word of the input to Y=0 (starting at (0, 0)). Then, each letter is compared to the letter immediately above it until one is found that doesn't match. The rest of the word is erased and the desired output is already on the canvas so it's printed when execution halts.

Ungolfed:

^w[B!32]{>}>       # Go to the first letter of the second word
w[B!0]{            # For each letter in the second word:
    t[B]             # Save the letter to T
    vb[1]            # Put a flag below that letter so it can be found later
    <[X]w[B!0]{>}    # Go to the first empty space on Y=0
    b[T]             # Write the contents of T
    w[B!1]{>}b[0]    # Go back to the flag and erase it
    ^>               # Restart loop from next letter
}

v<[X]<             # Go to (-1, 0)
t[0]               # Set T to 0
w[T=0]{            # While T is 0:
    >t[B]            # Save the next letter of the second word to T
    ^t[T-B]v         # Subtract the equivalent letter of the first word from T

    # If they were the same, T is 0 and the loop continues.
}

w[B!0]{b[0]>}      # Erase the rest of the second word
\$\endgroup\$
0
\$\begingroup\$

Ruby, 44 characters

->a,b{i=0;i+=1while a[i]&&a[i]==b[i];a[0,i]}

Sample run:

2.1.5 :001 > ->a,b{i=0;i+=1while a[i]&&a[i]==b[i];a[0,i]}["global , "glossary"]
 => "glo"

2.1.5 :002 > ->a,b{i=0;i+=1while a[i]&&a[i]==b[i];a[0,i]}["department", "depart"]
 => "depart"

2.1.5 :003 > ->a,b{i=0;i+=1while a[i]&&a[i]==b[i];a[0,i]}["glove", "dove"]
 => ""
\$\endgroup\$
0
0
\$\begingroup\$

PHP, 49 bytes

<?=substr($t=$argv[1],0,strspn($t^$argv[2],"\0"));

Replace \0 with the actual byte.

\$\endgroup\$
0
\$\begingroup\$

Regex, 12 bytes

(^.*).*$\n\1

each input string is separate line. https://regex101.com/r/bTf1ud/1

\$\endgroup\$
0
\$\begingroup\$

Powershell + Regex, 48 bytes

$m=$args-join"`n"-match"(^.*).*`n\1";$Matches[1]

one line input strings only.

Powershell pure, 58 56 bytes

param($a,$b)for($i=0;$a[$i]-eq$b[$i]){$c+=$a[$i++]};"$c"

Test script:

$f = {
param($a,$b)for($i=0;$a[$i]-eq$b[$i]){$c+=$a[$i++]};"$c"
}

"glo" -eq (&$f "global" "glossary")
"depart" -eq (&$f "department"  "depart")
"" -eq (&$f "glove" "dove")

Output:

True
True
True
\$\endgroup\$
0
\$\begingroup\$

C# (Visual C# Compiler), 62 bytes

(a,b)=>Concat(a.Zip(b,(x,y)=>x==y?x:'$').TakeWhile(x=>x!='$'))

Try it online!

Zip! This byte count includes only the lambda expression, and some necessary using static directives are not counted.

It is assumed that no word will contain the magical char value $ (otherwise program may fail). Can use \0 instead (but that is longer to type).

\$\endgroup\$
0
\$\begingroup\$

AWK, 52 bytes

{while((x=substr($1,++i,1))~substr($2,i,1))printf x}

Attempt This Online!

{while((x=substr($1,++i,1)) # grab each char from first string
~substr($2,i,1))            # compare to each char of second
printf x}                   # print match
\$\endgroup\$
0
\$\begingroup\$

JavaScript (Node.js), 41 bytes

f=([a,...A],[b,...B])=>[a]==b?a+f(A,B):''

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Red, 50 bytes

func[a b][copy/part a find a first difference a b]

Try it online!

copy/part a                              ; copy the head of the first string
            find a                       ; that ends at the position
                   first                 ; of the first symbol
                         difference a b  ; in the special difference of the two strings
\$\endgroup\$
-1
\$\begingroup\$

Java, 152 bytes

String a="aa",b="ab";char[]c=a.toCharArray(),d=b.toCharArray();int e=0,f=Math.min(c.length,d.length);for(;e<f&&c[e]==d[e];e++);return new String(c,0,e);
\$\endgroup\$
0
1 2
3

Your Answer

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

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