Take the 2-minute tour ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

Your task is simple. Determine if one string equals the other (not address, the value) without the use of equality operators (such as ==, ===, or .equal()) or inequality (!=, !==) anything similar for other languages. This means anywhere! You may not use these operators anywhere in the code. You may however, you use toggles such as !exp as you're not directly comparing the exp != with something else.

In addition, you may not use any functions such as strcmp, strcasecmp, etc.

As for comparison operators (>=, <=, >, <), they are also disallowed. I realize that some answers include this, but I'd really like to see more answers that don't borderline the equality operator.


An example using PHP is shown:

<?php

$a = 'string';
$b = 'string';

$tmp = array_unique(array($a, $b));

return -count($tmp) + 2;

Simply return true or false (or something that evaluates in the language to true or false like 0 or 1) to indicate if the strings match. The strings should be hardcoded seen in the above example. The strings should not be counted in the golf, so if you declare the variable before hand, don't count the declaration.

share|improve this question
1  
Is it necessary to output the result, or simply write a function to return a bool? If writing a complete program is required, that could make-or-break answers in languages with (relatively) significant boilerplate to create a functioning executable like Java and C# (such is the nature of the beast, but this challenge has little in the way of concrete guidelines, leaving much to interpretation/choice). And how are we to take the strings? Hardcoding, reading from STDIN, pass as command-line arguments? –  Tony H. Mar 12 at 14:23
    
Is this [code-golf] or a [popularity-contest]? It can't be both. –  Gareth Mar 12 at 14:23
    
Sorry, I have modified my questions to reflect both comments. –  Dave Chen Mar 12 at 14:32
    
So inequality is allowed? –  user80551 Mar 12 at 14:41
    
If the strings are to be hardcoded more than once(each) , do i have to count their length? –  user80551 Mar 12 at 15:13

75 Answers 75

Python 49 45 18 22 15 14

( + 3 if string variables are considered)

print{a:0,b:1}[a]

The string should be hard coded at the two occurrences of a and one occurrence of b surrounded by quotes.

a and b should be pre-initialized to the strings.


Python shell, 9

( + 3 if string variables are considered)

{a:0,b:1}[a]

Output in shell

>>> a = 'string'
>>> b = 'string'
>>> {a:0,b:1}[a]
1
>>> a = 'string'
>>> b = 'stringgg'
>>> {a:0,b:1}[a]
0
>>> {'string':0,'string':1}['string']
1
>>> {'stringggg':0,'string':1}['stringggg']
0
>>> 

Explanation

Creates a dict(hash table) with the key of first and second string. If second string is the same, the value of first is replaced by that of second. Finally, we print the value of first key.

EDIT: OP allowed 0/1 instead of False/True as well as using pre-initialized variables.

share|improve this answer
    
@manatwork Golfscript and perl below use 0/1, can't I use that? –  user80551 Mar 12 at 15:30
    
@manatwork Done –  user80551 Mar 12 at 15:31
    
I am counting 16 instead of 13, for your second solution. –  Abhijit Mar 12 at 17:29
    
@Abhijit the a and b are not to be included, the strings should be hard-coded there, that's why I added + 2*len(str1) + len(str2) + 6 (') –  user80551 Mar 12 at 17:30
    
+1 for clevernesse but this is by far not the shortest anymore ;) –  avalancha Mar 14 at 7:13

Python (17 11):

b in a in b

(Checks if b is contained in a and a is contained in b, if that wasn't clear from the code.)

Alternative python: (8 7)

derived from Tom Verelst's Go solution:

b in[a]

Bonus: this works for any type.

EDIT:

Wait a second, just read that you can also directly program in the strings, and don't have to count quotes... (or at least, that what golfscript does). So... Python on par with golfscript? Oh my!

Alternative alternative Python (5 4):

(thanks Claudiu)

"string"in["string"]

original:

"string" in["string"]

Alternative Alternative Alternative Bendy-ruly Python (2):

"string"is"string"

Nothing was said about comparison keywords (This is not a serious submission, just something that occurred to me...)

share|improve this answer
2  
You could use b in a in b. The and a is not necessary... –  George H Mar 13 at 0:21
2  
Now it is duplicate of willem's answer. –  manatwork Mar 13 at 9:00
    
You could get it down to seven characters by removing the whitespace between in and [a]. i.e. b in[a] should work. –  user3002473 Mar 13 at 19:43
    
Oh, didn't know that. Thanks :) –  ɐɔıʇǝɥʇuʎs Mar 13 at 19:59
    
Impressive! Also didn't know that –  willem Mar 15 at 11:05

JavaScript, 11 10

Strings have to be stored in a and b.

!(a>b|a<b)

Edit: thanks Danny for pointing out, | is enough instead of ||

share|improve this answer
4  
No, I am using greater than and less than operators. Those were not forbidden in the contest. –  user2270404 Mar 12 at 17:02
2  
+1. This is going to work identically in many other languages too. –  Paul Mar 12 at 17:04
3  
I may be wrong but can't you remove one |? –  Danny Mar 12 at 17:09
3  
Definitely a rules oversight - comparison functions are banned, as are equality and inequality operators, but comparison operators aren't mentioned. –  user2357112 Mar 13 at 5:52
2  
@philcolbourn Yes, rules changed yesterday but answer is 2 days old. –  Bakuriu Mar 15 at 11:17

Ruby, 11

s = 'string'
t = 'string'
!!s[t]&t[s]

Checks if each string is contained within the other.

share|improve this answer
1  
!(a<b||b<a) would be the same... –  David Herrmann Mar 12 at 15:48
    
except you can't use <> –  philcolbourn Mar 15 at 9:09

Python - 11 (without the strings)

>>> a = 'ss'
>>> b = 's'
>>> a in b in a
False
share|improve this answer
    
In the same spirit:a<=b<=a which is only 7 characters. Although I don't know whether the comparison <= would be considered an "inequality". From the question it appears that any comparison that is not an equality check is okay, which would allow <=. –  Bakuriu Mar 13 at 12:50
    
yeah, thats a nice one @Bakuriu, and I agree, its not totally clear when the rules are violated or not. 'in' after all alsoome how contains an equal statement. –  willem Mar 15 at 11:12

GolfScript (5 chars)

'string1''string1'].&,(

Fairly straightforward port of the PHP reference implementation. Leaves 0 (=false) on the stack if the strings are the same, or 1 (=true) if they're different.

share|improve this answer
    
doesn't work for me: 1 if the string are the same, and 2 if they're different. 'string1''string1'].&,1& works –  guy777 Mar 13 at 16:40
    
@guy777, this assumes that the stack is empty at the start. The question is rather vague on program fragments. You're probably testing it as a whole program and starting with an empty string on the stack from stdin. –  Peter Taylor Mar 13 at 16:48

C++, 63 58 56

const char* a = "string";
const char* b = "string";
int main(){while(*a**b*!(*a^*b))++a,++b;return!(*a^*b);}
share|improve this answer
2  
Could you get away with auto instead of const char*? –  aldo Mar 12 at 17:40
    
I think so yes, but since the rules say the string variables aren't counted towards the character count I didn't bother to golf them. –  mattnewport Mar 12 at 18:25
    
Could you fold increments into the while test and leave the body empty? And if you go for c instead of c++, remove int at the beginning. –  orion Mar 13 at 16:02
    
I don't see any way to reduce the character count by folding the increments into the while test without hitting the same bug of accessing a string past the end I pointed out in Abhijit's C answer. You only want to increment a and b if both tests pass (neither a nor b is pointing to the null terminator and a is equal to b). There's probably a way to improve on this but I haven't been able to find it! –  mattnewport Mar 13 at 16:28

coreutils: uniq -d

Just enter your two strings as the standard input of a pipe and uniq -d | grep -q . will print nothing but will have a return value of success or error. If you want to print the boolean, just replace with uniq -d | grep -c .

How many characters? I let you count; uniq -d|grep -q . with no extra spaces has 17 characters in it, but since the whole job is performed by uniq, I would say this solution is a 0-character one in... uniq own language!

Actually, uniq -d will print one line if the two strings are identical, and nothing if the are different.

share|improve this answer

Javascript (45 bytes):

Here is another solution in Javascript.

var a='string',b='string',c=!a.replace(b,'');

The space is important.

c should be true.

share|improve this answer
    
Only !a.replace(b,'') is counted. So character count should be 16. Actually, some people even count it 14, since you can specify the string directly. –  n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ Mar 17 at 8:07

PHP - 49 characters

!(strlen($a)^strlen($b)|strlen(trim($a^$b,"\0")))
share|improve this answer
    
Couldn't something like this work: !strlen(str_replace($a,'',$b)); It should return 1 if two strings are equal? –  DKasipovic Mar 17 at 14:40
    
@D.Kasipovic Interesting, but I think it fails for $a == 'foo' and $b = 'foofoo' :) –  Jack Mar 17 at 16:10
    
True, how about this then, it limits replace to one !strlen(preg_replace("/{$a}/", '', $b, 1)); and is 45 characters? –  DKasipovic Mar 17 at 18:29
    
I suppose you could use anchors instead, but more importantly it would require preg_quote() as well :) –  Jack Mar 18 at 0:49

APL (8 9)

Update: the old one does not work for strings of different lengths.

{∧/∊⌿↑⍺⍵}
  • ↑⍺⍵: make a matrix with on the first line and on the second line, filling blanks with spaces.
  • ∊⌿: For each column, see if the upper row contains the lower row (as in the old version).
  • ∧/: Take the logical and of all the values.

Old one:

{∧/⍺∊¨⍵}
  • ⍺∊¨⍵: for each combination of elements in and , see if the element from contains the element from . Since in a string these will all be single characters, and a string contains itself, this is basically comparing each pair of characters.
  • ∧/: take the logical and of all the values (if all the characters match, the strings are equal)
share|improve this answer

Python - 12

not({a}-{b})

This solution uses sets. Subtracting equal sets will result in an empty set, which has a boolean value of False. Negating that will result in a True value for a and b being equal strings.

>>> a="string1"
>>> b="string2"
>>> not({a}-{b})
False

>>> a="string"
>>> b="string"
>>> not({a}-{b})
True

Edit: Thanks to Peter Taylor for pointing out the unnecessary whitespace.

share|improve this answer
    
What output does this give for a="s", b="ss"? –  Peter Taylor Mar 13 at 15:33
    
@PeterTaylor: Since "s"!="ss", it will output False. Case sensitivity is also preserved. It even works for a="", b="s". The code does not convert strings to sets, but creates sets containing the strings. –  Varicus Mar 13 at 16:25
    
Ah, {} isn't the same as set(). You can save 1 char by removing the whitespace. –  Peter Taylor Mar 13 at 16:31
    
@PeterTaylor: Thanks for pointing out the unnecessary whitespace. {a} is equivalent to set([a]). –  Varicus Mar 13 at 22:14
    
How about not {a}-{b}? –  Winston Ewert Mar 28 at 6:11

C — 62

e(char*p,char*q){for(;*p&*q&&!(*p^*q);q++,p++);return!(*p^*q);}

Tested. Call as e(str1, str2)

Come to think of it, if you don't count the char*p,char*q, which seems only fair, it's only 49 bytes :)

share|improve this answer
    
Welcome to the site! For code-golf challenges, we encourage you to trim as many bytes from your code as you can, and post the byte count in your answer header. Check out the Tips for Golfing in C thread for some good ideas. –  Jonathan Van Matre Mar 13 at 18:04
    
You don't really need np and nq. One loop will do, because if you reach the end of one string before the other they will have a different value. –  Peter Taylor Mar 13 at 18:06
    
Thanks. I realize that. I was working on my shortened version (above). Going back to see if I can shorten it further. –  Emmet Mar 13 at 18:17
    
*p&*q may stop the loop too early (e.g. '0'&'A'==0) –  ugoren Mar 17 at 9:13
    
@ugoren: If *p=='0' & *q=='A', we want the loop to stop early, as we know the strings are not equal. –  Emmet Mar 17 at 13:30

Strings have to be stored in a and b. Will not work if either is null.

C#, 53

string.IsNullOrEmpty(a.Replace(b,"")+b.Replace(a,""))

C#, 28

a.Contains(b)&&b.Contains(a)
share|improve this answer

Haskell -- 9

elem a[b]

Note that this, just like many entries here, is just an expression. This is not a Haskell program.

share|improve this answer

PHP

I assume you're prohibited to use any comparison operators. So < or > are included.

The idea is to use bitwise XOR. In different languages this operator has different syntax - I'll show an example for PHP. There it's available with ^. Unfortunately, its behavior with strings isn't as good as it could be, so you'll need to check string length before. That is because in PHP, xor will strip the longer string down to the length of the shorter string.

Next thing is to work with strings properly, because a single xor will not produce a result, available for further operations in PHP. That's why unpack() was used. So, the code would be:

return !(strlen($a)^strlen($b)) & !array_filter(unpack('c*', $a^$b))

It's longer than option with < / > but it won't use them. Also, the important thing is about PHP type juggling (so empty array will be cast to false). Or maybe there's a simpler way to check if an array contain non-zero members (Edit: while I've been typing this, there's a good catch with trim() in another answer, so we can get rid of array operations)

But I believe there are languages, where we can do just a ^ b - literally, getting the result. If it's 0 (treated from all resulted bytes) - then our strings are equal. It's very easy and even more simple than < or > stuff.

share|improve this answer

PHP

    $string = 'string';
    isset( ${'string'} );

This script may not have any utility, but atleast this provides a way to compare strings.

PHP

Aother one:

    $string = 'something';
    $text   = 'something';
    return count( array( $string => 1 , $text => 1 ) ) % 2;
share|improve this answer
1  
Wow very lovely. And doing it like this can make it possible to use any string (with spaces and unicode). –  Dave Chen Mar 15 at 3:37

Prolog 7

e(A,A).

This makes use of the pattern matching feature in Prolog to unify the 2 arguments to the predicate, which effectively tests for equals equivalence when there is no unbound variable.

Sample usage:

?- e("abcd", "Abcd").
false.

?- e("abcd", "abcd").
true.

Technically speaking, the behavior of this solution is that of unification operator =/2, rather than that of ==/2, which checks for term equivalence. The difference shows when unbound variables are involved. In this solution, when unbound variable is supplied, the predicate will return true when unification is successful. In comparison, ==/2 will compare order of term without unification.

share|improve this answer

Java (250 characters for golfed version at bottom).

Strings are not hardcoded, but this is a trivial change.

   public boolean areEqual(String a, String b) {
    int[] q = new int[1];
    int i = 0;
    try {
        while (true) {
            noOp(q[(int) a.charAt(i) - (int) b.charAt(i)]);
            i++;
        }
    } catch (Exception e) {
        try {
            a.charAt(i);
        } catch (Exception e2) {
            try {
                b.charAt(i) {catch(Exception e3){
                    return true;
                }
                }
            }


            return false;
        }
        return true;
    }
}

public void noOp(int i) {
}

Traverses both strings, using the difference in chars to select an array index (which is 0-based). No in-loop comparisons or Math.max used.

Golfed for use under certain circumstances (instantiated class, used from same package):

boolean a(String a,String b){boolean t=true,f=false;int[]q={1};int i=0;try{while(t){q[(int)a.charAt(i)-(int)b.charAt(i)];i++;}}catch(Exception e){try{a.charAt(i);}catch(Exception z){try{b.charAt(i){catch(Exception g){return t;}}}return f;}return t;}}
share|improve this answer
    
Any purpose for noOp? –  Cole Johnson Mar 13 at 23:24
    
@ColeJohnson Just old coding practice from a very stringent CS teacher. Some odd JVMs might try to optimize out as well. –  hexafraction Mar 13 at 23:27

Mathematica / Wolfram Language, 15 bytes

2 - Length[{a} ∪ {b}]

Pretty self explanatory, sets each string as a set, then checks the length of the union of the two sets. If the strings are the same, returns 1, otherwise returns 0. If I'm allowed to return '2' for "different" and '1' for "same", subtract two bytes.

share|improve this answer

Python

It's long and it's not beautiful, but this is my first entry!

def is_equal(a,b):
    i=0
    a,b=list(a),list(b)
    if len(a)>len(b):
        c=a
        lst=b
    else:
        c=b
        lst=a
    try:
        while i<len(c):
            for j in c:
                if j not in lst[i]:
                    return False
                i+=1
    except IndexError:
        return False
    return True
share|improve this answer

grep 14 characters

Of course, I only count the grep code; the two strings are on two consecutive lines in the input (either a pipe or a file or even an interactive session).

$ echo -e 'string\nstring' | grep -cPzo "(?s)^(\N*).\1$"
1
$ echo -e 'string\nstring1' | grep -cPzo "(?s)^(\N*).\1$"
0
$ echo -e 'string1\nstring' | grep -cPzo "(?s)^(\N*).\1$"
0
share|improve this answer

Matlab: 12 chars (after the strings are in variables)

~(x*x'-y*y')

The code including assignments would be:

x='string1'
y='string2'
~(x*x'-y*y')
share|improve this answer

The very crazy way

Just for the fun, but many ways for making it fail if one thinks about it. More over, don't forget the strings will be EXECUTED by the shell.

$ echo -e 'string\nstring1' | sed -e '1s/^/#define /' | cpp | sh 2>/dev/null && echo true
$ echo -e 'string\nstring' | sed -e '1s/^/#define /' | cpp | sh 2>/dev/null && echo true
true
$ echo -e 'string1\nstring' | sed -e '1s/^/#define /' | cpp | sh 2>/dev/null && echo true

A good counter-example is comparing "string" as first string and "rm -Rf /" as a second string; just check as root and see: it will say "true" though both strings obviously aren't the same.

share|improve this answer

Java - 193

new int[]{0,1,0}[new BigInteger(a.getBytes()).subtract(new BigInteger(b.getBytes())).signum()+1]

No comparison operators at all, not even a < or >.

share|improve this answer

JavaScript [18 bytes]

(_={})[a]=1,!!_[b]

OR

!!((_={})[a]=_)[b]

This will return true if a == b and false if a =/= b. The logic behind is creating an object with a value of a as a property and returning 1 or undefined in case if a property of b value exists or doesn't exist in that object.

share|improve this answer
    
The rules say you're allowed to return an object that evaluates to true or false, so the !! is not necessary –  James_pic Mar 20 at 14:30
    
@James_pic Yeah, but otherwise it will return 1 or undefined (or object/undefined for the second case). –  VisioN Mar 20 at 14:33
    
I interpreted the rules as saying that truth-y and false-y values would do in place of true and false, so I'd think that 1 or undefined were good enough. –  James_pic Mar 20 at 14:35
    
@James_pic I just wanted to be on the safe side :) If so, then 18-2 = 16 bytes. –  VisioN Mar 20 at 14:37

JavaScript [15 bytes]

![a].indexOf(b)

This will return true if a == b and false if a =/= b. The script is looking for the value of b in the array that holds a single element of value of a.

share|improve this answer

C++: 104 105 characters

#include<string>
#include<set>
template<typename T>
int f(T a,T b){std::set<T>S={a};return S.count(b);}

EDIT: Saved a character by making it a template function.

Function itself is 51 characters. Other C++ answers already posted are shorter, but I wanted to try one that wasn't also pure C. In fact, this requires C++11. For earlier versions of C++ you can replace std::set<T>S={a}; with std::set<T>S(&a,&a+1); at the expense of an extra 5 characters.

share|improve this answer

Java - 162 147 characters

The idea is to compare the difference of each byte, same bytes will have difference 0. The program will throw java.lang.ArrayIndexOutOfBoundsException for when bytes are different (try to access a negative index) or when strings are of different length. It will catch the exception and return 0 (strings not equal), or return 1 otherwise (strings equal).

Compressed:

String a = "12345";
String b = "12345";
byte[]x=a.getBytes(),y=b.getBytes();int z,i=a.length()-b.length();try{for(byte d:x){z=d-y[i];z=x[-z*z];i++;}}catch(Exception e){return 0;}return 1;

Normal:

String a = "12345";
String b = "12345";
byte[] byteArrA = a.getBytes();
byte[] byteArrB = b.getBytes();

int byteDifference = 0;
int i = a.length() - b.length();

try {
    for (byte aByte : byteArrA) {
        byteDifference = aByte - byteArrB[i];
        byteDifference = byteArrA[-byteDifference*byteDifference];
        i++;
    }
} catch (Exception e){
    return 0;
}

return 1;
share|improve this answer
    
Comparison operators exist in the loop. –  hexafraction Mar 13 at 23:17
    
Thank you @hexafraction, I updated answer to not include them. –  Hopper Hunter Mar 14 at 0:59

Groovy 347

def compare(str1,str2){
    def str1val = 0
    def str2val = 0

    MessageDigest md5 = MessageDigest.getInstance("MD5")
    md5.digest(str1.getBytes("UTF-8")).each{ str1val += it*2 }
    md5.digest(str2.getBytes("UTF-8")).each{ str2val += it*2 }

    if(!(str1val-str2val)) {
        return true    
    } else {
        return false
    }
}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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