96
\$\begingroup\$

Challenge

Given two strings, work out if they both have exactly the same characters in them.

Example

Input

word, wrdo

This returns true because they are the same but just scrambled.

Input

word, wwro

This returns false.

Input

boat, toba

This returns true

Rules

Here are the rules!

  • Assume input will be at least 1 char long, and no longer than 8 chars.
  • No special characters, only az
  • All inputs can be assumed to be lowercase

Test Cases

boat, boat = true
toab, boat = true
oabt, toab = true
a, aa = false
zzz, zzzzzzzz = false
zyyyzzzz, yyzzzzzy = true
sleepy, pyels = false
p,p = true
\$\endgroup\$
7
  • 11
    \$\begingroup\$ 9 answers in 13 views... wow! \$\endgroup\$
    – Tom Gullen
    Commented Mar 8, 2011 at 16:44
  • 5
    \$\begingroup\$ Title request: Cod Elf, Go! \$\endgroup\$
    – user54200
    Commented Jul 9, 2016 at 12:48
  • 7
    \$\begingroup\$ "Falcon Rage, go mad!" \$\endgroup\$
    – Geobits
    Commented Oct 6, 2016 at 17:25
  • 15
    \$\begingroup\$ My name suggestion: "are they anagrams" → "manage the arrays" \$\endgroup\$ Commented Oct 31, 2017 at 4:32
  • 2
    \$\begingroup\$ Suggested test case: aaab, bbba = false \$\endgroup\$
    – Deadcode
    Commented Aug 3, 2022 at 23:56

170 Answers 170

1
2 3 4 5 6
40
\$\begingroup\$

Python, 32 bytes

f=lambda a,b,S=sorted:S(a)==S(b)
\$\endgroup\$
9
  • 3
    \$\begingroup\$ @Debanjan, This is just the same as def f(a,b):return sorted(a)==sorted(b) The trade off is that you get to replace def+return with lambda in exchange for not using any statements \$\endgroup\$
    – gnibbler
    Commented Mar 8, 2011 at 22:23
  • 1
    \$\begingroup\$ @Debanjan, I think it only saves you one character. I have used a variation here, but it works out the same length as yours because I swap a newline for a comma \$\endgroup\$
    – gnibbler
    Commented Mar 9, 2011 at 0:09
  • 1
    \$\begingroup\$ I have one question,this approach does require calling of input and print and other stripping functions right? \$\endgroup\$
    – Quixotic
    Commented Mar 9, 2011 at 0:09
  • 6
    \$\begingroup\$ @Tomas, it's not rule abuse. Some questions are deliberately openended like this one appears to be. Compare with a well specified question like this. If you don't like these answers complain to the question asker \$\endgroup\$
    – gnibbler
    Commented Feb 3, 2014 at 0:41
  • 5
    \$\begingroup\$ You don't need to include the f=. \$\endgroup\$
    – Oliver Ni
    Commented Oct 8, 2016 at 5:02
28
\$\begingroup\$

Golfscript, 3 chars?

$$=

usage:

'boat'$'baot'$=
1

'toab'$'boat'$=
1

'oabt'$'toab'$=
1

'a'$'aa'$=
0

'zzz'$'zzzzzzzz'$=
0

'zyyyzzzz'$'yyzzzzzy'$=
1

'sleepy'$'pyels'$=
0

'p'$'p'$=
1
\$\endgroup\$
8
  • 27
    \$\begingroup\$ This is an interesting interpretation of how to supply the input :) \$\endgroup\$
    – gnibbler
    Commented Mar 9, 2011 at 0:10
  • 5
    \$\begingroup\$ Explanation please :( \$\endgroup\$
    – st0le
    Commented Mar 9, 2011 at 5:41
  • 11
    \$\begingroup\$ @st0le, seriously? I don't know golfscript, but it's obviously $ (sort), $ (sort), = (compare) \$\endgroup\$ Commented Mar 9, 2011 at 8:10
  • 11
    \$\begingroup\$ Isn't this cheating a little? I mean, it isn't variable input. It has to be hard-coded. In any case, I would add 4 to the character count for the quote (') characters. \$\endgroup\$ Commented Jul 30, 2011 at 0:18
  • 7
    \$\begingroup\$ This isn't valid by our current rules. You could, however, change it to @JanDvorak's 4-byte function, which would accept input via a valid input format. \$\endgroup\$
    – Doorknob
    Commented May 17, 2016 at 19:28
21
\$\begingroup\$

J, 8

-:&(/:~)

Literaly, match (-:) on (&) sort up (/:~)

Sample use:

   'boat' -:&(/:~) 'boat'
1
   'toab' -:&(/:~) 'boat'
1
   'oabt' -:&(/:~) 'toab'
1
   'a' -:&(/:~) 'aa'
0
   'zzz' -:&(/:~) 'zzzzzzzz'
0
   'zyyyzzzz' -:&(/:~) 'yyzzzzzy'
1
   'sleepy' -:&(/:~) 'pyels'
0
   'p' -:&(/:~) 'p'
1

Where do the 64-bit integers come into play?

\$\endgroup\$
4
  • \$\begingroup\$ Is it not possible to write functions/subroutines in J? \$\endgroup\$
    – user475
    Commented Mar 8, 2011 at 15:57
  • 2
    \$\begingroup\$ @Tim Nordenfur: they're called "verbs", and take either one argument on their right as in v arg (monads) or two on both sides as in arg1 v arg2 (dyads). The one I submitted is obviously a dyad. I didn't bother to name it, since it wasn't requested and is shorter this way. Should you really want to give it a name, you'd do that like this: is_anagram_of =: -:&(/:~) and then use as 'a' is_anagram_of 'aa'. \$\endgroup\$
    – J B
    Commented Mar 8, 2011 at 16:21
  • \$\begingroup\$ It felt a bit cheap to substitute the arguments into the code, but I see now that it's essentially a dyad. Never mind. \$\endgroup\$
    – user475
    Commented Mar 8, 2011 at 16:26
  • 32
    \$\begingroup\$ J always looks like the remains of an emoticon factory explosion. \$\endgroup\$
    – st0le
    Commented Mar 9, 2011 at 6:58
19
\$\begingroup\$

Javascript, 192 157 152 147 125 bytes

Ok some of these languages are a lot more flexibile than I thought! Anyway this is the longer way I guess, but a different technique at least.

Compressed

Thanks to Peter and David for squeezing more chars out!

for(a=[j=p=2];j<123;)a[j]?p%a[++j]<1&&p++&&(j=0):(a[j]=p,j=0);function b(c,i){return c[i=i||0]?a[c.charCodeAt(i)]*b(c,++i):1}

Then do:

alert(b("hello")==b("elloh"));

Expanded Code

The compressed has had lots of changes, but this is the basic theory:

// Define dictionary of primes
a = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101];

// Returns the unique ID of the word (order irrelevant)
function b(c) {
    r = 1;
    for (i = 0; i < c.length; i++)
        r *= a[c[i].charCodeAt(0) - 97];
    return r
}

alert(b("hello") == b("hlleo"));
\$\endgroup\$
21
  • \$\begingroup\$ Great idea using primes. \$\endgroup\$
    – user475
    Commented Mar 8, 2011 at 16:06
  • \$\begingroup\$ @Tim thanks! Got it down to 157 now. \$\endgroup\$
    – Tom Gullen
    Commented Mar 8, 2011 at 16:12
  • 2
    \$\begingroup\$ You can shave a couple of characters off the dictionary initialisation using the sieve. a=[2];for(p=3,j=0;j<26;)if(a[j]){if(p%a[j++]==0){p++;j=0}}else{a[j]=p;j=0} \$\endgroup\$ Commented Mar 8, 2011 at 17:06
  • 1
    \$\begingroup\$ @Tom, depends on how well optimised the sorting routines are, given that you've limited inputs to 8 characters :P \$\endgroup\$ Commented Mar 9, 2011 at 11:13
  • 1
    \$\begingroup\$ 125 characters. Recursion and ternaries FTW: for(a=[j=p=2];j<123;)a[j]?p%a[++j]<1&&p++&&(j=0):(a[j]=p,j=0);function b(c,i){return c[i=i||0]?a[c.charCodeAt(i)]*b(c,++i):1} \$\endgroup\$ Commented Mar 9, 2011 at 14:03
14
\$\begingroup\$

Golfscript, 8 bytes

This defines a function called A

{$\$=}:A

Test cases

;
'boat' 'boat' A
'toab' 'boat' A
'oabt' 'toab' A
'a' 'aa' A
'zzz' 'zzzzzzzz' A
'zyyyzzzz' 'yyzzzzzy' A
'sleepy' 'pyels' A
'p' 'p' A
\$\endgroup\$
11
\$\begingroup\$

Haskell, 31 bytes

function - 31

import List
f=(.sort).(==).sort

program - 81 58 55

import List
g=sort`fmap`getLine
main=(`fmap`g).(==)=<<g

Usage:

$ runghc anagram.hs
boat
boat
True
$ runghc anagram.hs
toab
boat
True
$ runghc anagram.hs
a
aa
False

Kudos to lambdabot and its pointfree refactoring.

\$\endgroup\$
10
  • \$\begingroup\$ Can Haskell code that only does what's wanted under runghc, but not when compiled, still be called "program"? \$\endgroup\$
    – J B
    Commented Mar 8, 2011 at 21:29
  • 3
    \$\begingroup\$ @J B: Can Perl code that only does what's wanted under perl still be called a "program"? :-) \$\endgroup\$
    – Joey Adams
    Commented Mar 8, 2011 at 23:06
  • \$\begingroup\$ J B: Todays functional languages skew the meaning of a program making it a higher order abstraction. Rather than just a list of instruction to be executed, as haskell program can just be seen as a collection of functions, even if they are not called. \$\endgroup\$ Commented Mar 9, 2011 at 17:45
  • \$\begingroup\$ @Callum Rogers: my point is: his code behaves differently whether run under runghc or compiled, in a problem-sensitive area. The "function" is fine. The "program" does not solve the problem under anything else than runghc, and runghc is not the only legitimate way to run Haskell programs. In that context, that makes the snippet a "runghc script", not a "Haskell program". --not that I'd consider the issue important, as I said, the function is fine anyway and it's shorter. \$\endgroup\$
    – J B
    Commented Mar 9, 2011 at 21:09
  • 2
    \$\begingroup\$ x#y=sort x==sort y is 1 character shorter \$\endgroup\$
    – Rotsor
    Commented Aug 6, 2011 at 10:58
10
\$\begingroup\$

C#, 129 chars

namespace System.Linq{class X{static void Main(string[]a){Console.Write(a[0].OrderBy(_=>_).SequenceEqual(a[1].OrderBy(_=>_)));}}}

Readable:

namespace System.Linq
{
    class X
    {
        static void Main(string[] a)
        {
            Console.Write(a[0].OrderBy(_ => _)
                  .SequenceEqual(a[1].OrderBy(_ => _)));
        }
    }
}
\$\endgroup\$
1
  • \$\begingroup\$ I think you could golf a few bytes with using System.Linq; instead of namespacing it? \$\endgroup\$
    – Stackstuck
    Commented Mar 26, 2019 at 22:36
10
\$\begingroup\$

Ruby, 34 bytes

Using the IO scheme of Peter Taylors Perl solution:

p gets.chars.sort==gets.chars.sort
\$\endgroup\$
1
  • \$\begingroup\$ Throws an error: -e:1:in '<main>': undefined method 'chars' for nil:NilClass (NoMethodError) \$\endgroup\$
    – Tomas
    Commented Feb 2, 2014 at 22:53
9
\$\begingroup\$

C program, 118

t[52],i;main(c){for(;i<52;)(c=getchar())<11?i+=26:t[i+c-97]++;
for(i=27;--i&&t[i-1]==t[i+25];);puts(i?"false":"true");}
\$\endgroup\$
6
  • 1
    \$\begingroup\$ Ever considered applying for IOCCC? \$\endgroup\$ Commented Mar 9, 2011 at 3:54
  • 9
    \$\begingroup\$ @muntoo: have you seen anything in the IOCCC? This is way too readable for that. \$\endgroup\$ Commented Mar 9, 2011 at 5:39
  • \$\begingroup\$ @Martinho Yes, the IOCCC source codes are so beautiful. Symphonies. But he should at least try composing a small piece. :) \$\endgroup\$ Commented Mar 9, 2011 at 6:59
  • \$\begingroup\$ @muntoo: I didn't even know they were still active. \$\endgroup\$
    – Joey Adams
    Commented Mar 9, 2011 at 7:21
  • 1
    \$\begingroup\$ Just saw this one... Very nice. But can be shorter: t[256],i;main(c){for(;c+3;)(i=getchar())>10?t[i]+=c:(c-=2);for(i=257;--i&&!t[i-1];);puts(i?"false":"true");} - that's 108 characters. Very importantly, your c initialization trick is still employed. \$\endgroup\$
    – ugoren
    Commented Feb 29, 2012 at 16:18
7
\$\begingroup\$

JavaScript

Based on @zzzzBov's solution.

Comparison, 65 chars (40 without function)

function f(a,b){return a.split('').sort()==b.split('').sort()+""}

Comparator, 43 chars

function f(a){return a.split('').sort()+""}
\$\endgroup\$
1
  • \$\begingroup\$ Clever using the +"" to coerce to string. \$\endgroup\$
    – Casey Chu
    Commented Jun 16, 2011 at 6:01
7
\$\begingroup\$

Perl, 58 bytes

(complete program, unlike the other Perl answer which is only a function)

($c,$d)=map{[sort split//]}<>;print"@$c"eq"@$d"?true:false

49 as a function

sub f{($c,$d)=map{[sort split//]}<>;"@$c"eq"@$d"}
\$\endgroup\$
3
  • \$\begingroup\$ of course you can save 4 chars in the program by removing the " around true and false, since without using strict/warnings a bareword is a string. \$\endgroup\$ Commented Sep 17, 2011 at 17:30
  • \$\begingroup\$ Thanks! \$\endgroup\$
    – Timwi
    Commented Sep 17, 2011 at 20:21
  • \$\begingroup\$ I prefer this as ($c,$d)=map{[sort split//]}@ARGV;exit("@$c"ne"@$d") (51 chars) so it can take command line arguments and use the command line exit codes. It'd be 48 chars retaining <> with a multi-line input. \$\endgroup\$
    – Adam Katz
    Commented Aug 15, 2015 at 11:41
7
\$\begingroup\$

R, 54 bytes

function(x,y,`~`=sort,`+`=utf8ToInt)identical(~+x,~+y)

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ I'm highly intrigued by your use of utf8ToInt, not only in this answer, but in many others that I have seen. \$\endgroup\$
    – Sumner18
    Commented Dec 17, 2018 at 22:43
  • 1
    \$\begingroup\$ Have you seen tips for golfing in R? utf8ToInt and its reverse tend to make for shorter string-splitting than the conventional functions. \$\endgroup\$
    – J.Doe
    Commented Dec 18, 2018 at 0:41
6
\$\begingroup\$

Clojure - 23 chars

As an anonymous function:

#(apply = (map sort %))

Test case example:

(#(apply = (map sort %)) ["boat" "boat"])
=> true
\$\endgroup\$
2
  • \$\begingroup\$ Cool, I like it. \$\endgroup\$
    – Chiron
    Commented Dec 5, 2011 at 23:48
  • 1
    \$\begingroup\$ Nice answer. I particularly like the test strings you chose ;-) \$\endgroup\$
    – coredump
    Commented Oct 6, 2015 at 20:44
6
\$\begingroup\$

C++ (104 non-ws chars)


Based on counting sort. Note: Assumes strings of the same length, which seems to be implied (though not stated) by the question.

int u[123], i;

int a(char **c) {
    for(; c[0][i]; ) {
        u[c[0][i]]++;
        u[c[1][i++]]--;
    }

    i=123;
    while(i && !u[--i]);
    return !i;
}
\$\endgroup\$
10
  • \$\begingroup\$ In C, if you declare a variable in the global scope, it is initialized to zero. I guess this is also true for C++. \$\endgroup\$
    – Joey Adams
    Commented Mar 8, 2011 at 17:24
  • \$\begingroup\$ Local variables, on the other hand, are not initialized to zero automatically. \$\endgroup\$
    – Joey Adams
    Commented Mar 8, 2011 at 17:35
  • \$\begingroup\$ OK, I removed my caveat since I found ways to do without it. \$\endgroup\$ Commented Mar 8, 2011 at 18:09
  • 1
    \$\begingroup\$ Bzzzt. You pass the test cases, but "helle" and "hollo" are apparently the same. Easy fix: change one of the ++ to a --. Then just if (u[i++]) return 0; \$\endgroup\$ Commented Mar 9, 2011 at 6:30
  • 1
    \$\begingroup\$ I haven't tested this, but the last three lines can be written as i=123;while(i&&u[--i]);return!i; \$\endgroup\$
    – st0le
    Commented Dec 7, 2011 at 4:38
6
\$\begingroup\$

APL, 2 chars

≡⍦

This is the Multiset Match function from Nars2000, one of the leading-edge APL implementations. When applied to strings, it computes exactly the function required:

      'elvis' ≡⍦ 'lives'
1
      'alec guinness' ≡⍦ 'genuine class'
1
\$\endgroup\$
2
  • \$\begingroup\$ Just curious, how many bytes is this? 4? 6? \$\endgroup\$
    – Maltysen
    Commented Jan 30, 2015 at 2:04
  • \$\begingroup\$ It depends on the encoding. 6 bytes in UTF-8, 4 bytes in UCS-2, 2 bytes if any of the legacy single-byte APL charsets have the symbol, which I doubt. \$\endgroup\$
    – Tobia
    Commented Jan 30, 2015 at 10:22
6
\$\begingroup\$

05AB1E, 6 4 bytes

{I{Q

Try it online!

This took a while because of input difficulties. Golfed down due to pop.

Explanation:

{I{Q    Original code

{       Takes first input e.g. word and sorts -> 'dorw'
 I      Takes second input e.g. 'wrdo'
  {     Sorts second input -> 'dorw'
   Q    Compare if sorted 1 = sorted 2, then print result. 'dorw' = 'dorw', so prints 1.
\$\endgroup\$
1
  • 2
    \$\begingroup\$ I know this answer is 5+ years old, but by taking the input as pair of strings, it can be 3 bytes: €{Ë \$\endgroup\$ Commented Apr 8, 2022 at 8:27
5
\$\begingroup\$

Perl, 62 bytes

This function takes the strings as arguments and returns true or false.

sub f{my@a;for$.(1,-1){$a[ord]+=$.for split//,pop}!grep{$_}@a}

Stores the ASCII values in an array and checks if it evens out. Increments for the first word and decrements for the second word.

\$\endgroup\$
5
\$\begingroup\$

Knight, 112 bytes

;=dF;C=mB;=a 123W<96=a-a 1Id=d!E+"a"aE++"=a"a" 0";=w"+1a";C=lB;=bP:Wb;E++"=a"Ab+wAb=bGb 1Lb;=w"+~1a";Cl;=dT;CmOd

Try it online!

Knight doesn't have arrays. It does have strings, but it only allows a subset of valid ASCII character codes. So I emulated an array by constructing strings that looks like "=a{charcode} 0" and evaling it.

Knight also has blocks. A block works like a niladic function, which can change its behavior depending on global variables. This code uses two blocks: m loops over all 26 variables a97 - a122 initializing or testing something, and l handles the part of taking input and iterating over its chars to count occurrences.

; = d F                  d = False
; C = m B                define and run block m:
  ; = a 123                a = 123
  : W < 96 = a - a 1       while 96 < (a = a - 1):
    I d                      if d:
      = d ! E + "a" a          d = ! eval("a" + a)
      E + + "=a" a " 0"      else: eval("=a" + a + " 0") (aNN = 0)
                         i.e. d is false on start, so initialize all of a97..a122 to 0
; = w "+1a"              w = "+1a" (which is necessary to run l)
; C = l B                define and run block l:
  ; = b P                  b = one line of input
  : W b                    while b is not empty:
    ; E +                    eval(concatenation of
          + "=a" A b           "=aNN"
          + w A b              w+"NN") (aNN = 1 + aNN)
                             (w = "+~1a" changes this to aNN = -1 + aNN)
    : = b G b 1 L b          b = b[1:length(b)]
                         i.e. count occurrences of chars in the first line
; = w "+~1a"             w = "+~1a"
; C l                    run block l i.e. count negative occurrences in the second line
; = d T                  d = True
; C m                    run block m
                         for each of a122..a97, check if aNN is zero
                         if true, keep checking; otherwise do useless thing
: O d                    print d
\$\endgroup\$
4
\$\begingroup\$

PHP (command line, 87 characters)

function d($s){
    return array_count_values(str_split($s));
}

echo d($argv[1]) == d($argv[2]);
\$\endgroup\$
4
\$\begingroup\$

Javascript

A (very) slightly shorter version of @zzzzBov's solution, that uses .join() instead of String boxing:

function a(b,c){return b.split('').sort().join()==c.split('').sort().join()}
alert(a('abc','bca')); //true

Similarly:

function a(b){return b.split('').sort().join()}
alert(a('abc')==a('bca')); //true
\$\endgroup\$
1
  • 3
    \$\begingroup\$ this is answer ID 1337. congratz \$\endgroup\$
    – TheDoctor
    Commented Oct 30, 2015 at 19:50
4
\$\begingroup\$

Clojure REPL 41 chars

(= (sort (read-line)) (sort (read-line)))
\$\endgroup\$
1
4
\$\begingroup\$

Java

(everyone's favorite language apparently!)

173 chars:

import java.util.*;class g{public static void main(String[]p){String[]a=p[0].split(""),b=p[1].split("");Arrays.sort(a);Arrays.sort(b);System.out.print(Arrays.equals(a,b));}}

(Doesn't print newline char to save 2 chars from println)

Compile and run:

javac g.java
java -cp . g abcdef fedcba
true

Love to see a shorter one...

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

Scala in REPL (32)

readLine.sorted==readLine.sorted

Scala function (43)

def f(a:String,b:String)=a.sorted==b.sorted

Scala program (61)

object A extends App{println(args(0).sorted==args(1).sorted)}

These leverage a neat feature of Scala whereby a String can also be treated as a sequence of characters (Seq), with all the operations on Seq being available.

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

sed, 45 chars

It's even possible in my favourite - sed! Just one regular expression to solve the anagram! Just keep removing the corresponding letters:

:
s/(.)(.*,.*)\1/\2/
t
/\w/{i\false
d}
i\true

(to be invoked with -nE)

Perl, 48

1while s/(.)(.*,.*)\1/\2/;$_=/\w/?"false":"true"

To be invoked with -p.

Perl function, 39

sub f{$,while s/(.)(.*,.*)\1/\2/;!/\w/}
\$\endgroup\$
1
  • \$\begingroup\$ One less: sub f{1while s/(.)(.*,.*)\1/\2/;!/\w/} \$\endgroup\$
    – Kjetil S
    Commented Apr 13, 2022 at 16:12
4
\$\begingroup\$

Python 3, 107 97 76 64

s=sorted;a,b=input().split(', ')
print(str(s(a)==s(b)).lower())

Obviously this can be shortened if we don't take the OP's wording literally and lowercase "true" and "false"...

\$\endgroup\$
3
  • \$\begingroup\$ You can shave off a few characters if you append ;s=sorted to the first line and then replace the two instances of sorted with s in the second line. Should save... 3 characters? \$\endgroup\$ Commented Aug 6, 2015 at 17:58
  • 1
    \$\begingroup\$ Indeed. Python 3 also saves a bit of space, and is probably reasonable to use now, 5 years after this answer was posted. Also, the .strip() was redundant, given the specified inputs. \$\endgroup\$
    – Wooble
    Commented Aug 10, 2015 at 12:55
  • \$\begingroup\$ Yeah, sorry. I didn't notice how old this question was when I commented, only that it was on the frontpage. ^^; \$\endgroup\$ Commented Aug 10, 2015 at 22:39
4
\$\begingroup\$

JavaScript, 41

Comparison function (41):

a=b=>''+[...b].sort()
b=(c,d)=>a(c)==a(d)
alert(b('abc', 'cba')) // true

Comparator function (21):

a=b=>''+[...b].sort()
alert(a('abc') == a('bca')); //true

Comparator function (48):

function a(b){return String(b.split('').sort())}
alert(a('abc')==a('bca')); //true

Comparison function (78):

function a(b,c){return String(b.split('').sort())==String(c.split('').sort())}
alert(a('abc','bca')); //true

Assumes String has split and Array has sort.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ 38 bytes: c=>d=>(a=b=>''+[...b].sort())(c)==a(d) \$\endgroup\$ Commented Mar 19, 2019 at 6:17
4
\$\begingroup\$

Python, 32 bytes

p=sorted
f=lambda a,b:p(a)==p(b)
\$\endgroup\$
2
  • \$\begingroup\$ Does nothing in python. Are you sure it is a complete program that takes the input and produces the output as requested? \$\endgroup\$
    – Tomas
    Commented Feb 2, 2014 at 23:48
  • 2
    \$\begingroup\$ @Tomas It's a function \$\endgroup\$ Commented Oct 8, 2016 at 19:51
4
\$\begingroup\$

Bash, 88 characters

diff <(grep -o .<<<$1|sort) <(grep -o .<<<$2|sort)>/dev/null && echo true || echo false
\$\endgroup\$
4
\$\begingroup\$

Regex (PCRE), 65 bytes

^((?=(.))(?!(.*?\2(?=.*
(\4?+.*?\2)))*+.*\2)(?=.*
(\5?+.)).)*
\5$

Try it online! - test cases
Try it on regex101 - try it on your own

Takes the input strings delimited by newline.

This asserts that both:

  • For each character in the first string, the second string contains that character at least as many times as it occurs in the first string
  • The second string is equal in length to the first
^              # Assert that we're starting at the beginning of the first word.
(
    (?=(.))    # Match and capture a character in \2, without consuming it.
    # Assert that the second has at least as many occurrences of \2 as there
    # are subsequent occurrences of it in the first word (including the one we
    # just captured above).
    (?! # Negative lookahead - assert the following can't match, and also
        # conveniently erase whatever capture groups it creates when finished.
        (
            .*?\2     # Match up to the next occurrence of \2 in the first word
                      # (which will be the first one when this loop starts)
            (?=
                .*¶           # Skip to the second word.
                (             # \4 = the following:
                    \4?+      # previous value of \4, if any
                    .*?\2     # Match up to the first subsequent occurrence of
                              # \2 in the second word (which will be the first
                              # occurrence when this loop starts)
                )
            )
        )*+           # Loop the above possessively, locking in each iteration
                      # atomically as it matches.
        .*\2          # Assert \2 occurs again in the first word.
    )
    # Append one more character from the second word onto \5, building up \5
    # to have the same number of characters of the second word as characters
    # we have finished processing in the first word.
    (?=
        .*¶           # Skip to the second word.
        (             # \5 = the following:
            \5?+      # Previous value of \5, if any
            .         # One additional character
        )
    )
    .          # Skip over the \2 just processed in the first word.
)*             # Iterate the above as many times as possible.
¶              # Assert we've reached a newline, meaning we've processed the
               # entire first word, and advance to the second word.
\5$            # Assert that the second word is of equal length to the first.

It only takes +1 byte (66 bytes) to add support for zero-length words:

^((?=(.))(?!(.*?\2(?=.*
(\4?+.*?\2)))*+.*\2)(?=.*
(\5?+.)).)*
\5?$

Try it online! - test cases
Try it on regex101 - try it on your own

Regex (.NET), 70 66 62 bytes

^(((.))(?=(?>(?<2>\2)|.)*
((?<-2>\2)|.)*$(?(2)^)))*
(?<-3>.)*$

Try it online! - test cases
Try it on regex101 - try it on your own

This asserts that both:

  • For each character in the first string, the second string contains that character at least as many times as it occurs in the first string
  • The second string is not longer than the first

Although it is not required, this works even with zero-length words (for free; there is no golf sacrifice in doing so).

^              # Assert that we're starting at the beginning of the first word.
(
    ((.))      # Consume a character and capture it in both \2 and \3.
    
    # Assert that the second word has at least as many occurrences of \2 as
    # there are subsequent occurrences of it in the first word (including the
    # occurrence we just consumed). This only needs to be asserted for the first
    # occurrence of each character in the first word (because on each subsequent
    # occurrence, the count of subsequent occurrences will be one fewer than
    # before) but for golf reasons, it's harmless to do it for every occurrence.
    
    (?=               # Atomic lookahead
        # Step 1: Push every subsequent occurrence of \2 onto the \2 stack.
        (?>           # Atomic group - prevent backtracking from changing what's
                      # done inside it once it's been done.
                      # For each subsequent character in the first word:
            (?<2>\2)  # If it matches \2, push another copy of it onto the
                      # \2 stack, and consume the character.
        |        # or
            .         # Consume the character.
        )*            # Iterate the above as many times as possible.
        ¶             # Consume the newline to begin reading the second word,
                      # preventing the number of loop iterations in the above
                      # loop from being backtracked.
    
        # Step 2: Assert that the second word has at least as many occurrences
        # of \2 as were counted above.
        (             # For each character in the second word:
            (?<-2>\2) # If it matches \2, pop it off the \2 stack, and consume
                      # the character.
        |        # or
            .         # Consume the character.
        )*$           # Iterate the above until reaching end of string.
        (?(2)^)       # Assert that the \2 stack is empty.
    )
)*             # Iterate the above as many times as possible.
¶              # Assert we've reached a newline; advance to the second word.
(?<-3>.)*$     # Assert that this word is not longer than the first word, by
               # popping every capture from the \3 stack and matching one
               # character of the second word (it doesn't have to match \3)
               # for each.

Regex (Perl / PCRE), 71 bytes

^((?=(.))(?4)(?=.*
(\3?+.)).)*
\3$((?!(.*?\2(?=.*
(\6?+.*?\2)))*+.*\2))

Try it online! - Perl
Try it online! - PCRE2

Perl doesn't erase capture groups upon exiting from a negative lookahead. For compatibility with it, this version uses a subroutine call (?4) instead of a negative lookahead to erase the necessary capture group. The subroutine is then executed again, harmlessly, after the regex finishes and reaches the end of the string (for golf reasons, it is not hidden in a (?(DEFINE)...) block or similar construct).

Regex (PCRE / .NET), 74 bytes

^((?=(.))(?!(?>(.*?\2(?=.*
((?>\4?).*?\2)))*).*\2)(?=.*
((?>\5?).)).)*
\5$

Try it online! - PCRE2
Try it online! - .NET

This is the PCRE version ported to be compatible with .NET, replacing possessive quantifiers with atomic groups.

Regex (PCRE / Ruby), 87 bytes

^((?=(.))(?!(.*?\2(?=.*
(\5?+.*?\2))(?=.*
(\4)))*+.*\2)(?=.*
(\7?+.))(?=.*
(\6)).)*
\6?$

Try it online! - PCRE
Try it online! - Ruby

This is a port of the 65 byte PCRE version, using back-and-forth copying of \4\5 and \6\7 to avoid use of nested backreferences, which aren't supported by Ruby.

For a reason I have yet to determine, this doesn't work on Pythonregex, even its latest version.

Regex (Perl / PCRE / Ruby / .NET), 147 bytes

^((?=(.))(?!(?>(.*?\2(?=((?!.*\2)|.))(?=.*
((?!.*$\4)(?>\6?).*?\2|(?=.*$\4)(?=(?>\6?).*?\2)))(?=.*
(\5)))*).*\2)(?=.*
((?>\8?).))(?=.*
(\7)).)*
\7$

Try it online! - Perl
Try it online! - PCRE2
Try it online! - Ruby
Try it online! - .NET

This is a rather interesting challenge for writing a regex polyglot.

Supporting both Perl and Ruby/.NET is rather difficult. The problem is finding a way to erase the capture group that is created inside a negative lookahead in the PCRE version. Erasing capture groups in situations like this can be a challenge, and to support this combination of regex engines, we can't use negative lookahead (Perl doesn't erase it), a subroutine call (because Ruby's syntax is incompatible with Perl, and .NET doesn't have them), a branch reset group (neither Ruby nor .NET support them), or capture group aliasing or explicit erasure (only .NET has those).

So we must signal to the place where the capture is normally made, to erase it when it needs to be erased. The method I settled upon here is rather convoluted, but it works. (It would be shorter with a lookaround conditional, but we can't use one, as Ruby doesn't have them, and .NET's syntax for them is different.) This post is already pretty long, so here's a link to the commented version.

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

VBScript

172 characters

wscript.echo "boat, boat         = " & s("boat, boat")
wscript.echo "toab, boat         = " & s("toab, boat")
wscript.echo "oabt, toab         = " & s("oabt, toab")
wscript.echo "a, aa              = " & s("a, aa")
wscript.echo "zzz, zzzzzzzz      = " & s("zzz, zzzzzzzz")
wscript.echo "zyyyzzzz, yyzzzzzy = " & s("zyyyzzzz, yyzzzzzy")
wscript.echo "sleepy, pyels      = " & s("sleepy, pyels")
wscript.echo "p,p                = " & s("p,p")

function s(a):b=split(replace(a," ",""),","):c=0:for x=1 to len(b(0)):if instr(b(1),mid(b(0),x,1)) then c=c+1 
next:if len(b(1))-c=0 then s=true else s=false
end function

I was kinda suprised I could get it under 200.

\$\endgroup\$
1
  • \$\begingroup\$ 131 characters if I pass the values seperatly. function s(a,b):c=0:for x=1 to len(a):if instr(b,mid(a,x,1)) then c=c+1 next:if len(b)-c=0 then s=true else s=false end function \$\endgroup\$
    – user775
    Commented Mar 9, 2011 at 14:40
1
2 3 4 5 6

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.