Discussion
· May 3, 2022

Code Golf: Anagram Detector

An anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.
For example, the word anagram itself can be rearranged into nag a ram, also the word binary into brainy and the word adobe into abode. Wikipedia

You will receive two strings returning true if the two arguments given are anagrams of each other.
As usual shortest solution wins.

Input

"Listen", "Silent"

Output

1

Note

Rules

  1. The signature of the contest entry MUST be:
Class codeGolf.Anagram
{

ClassMethod Detector(a As %String, b As %String) As %Boolean
{
  ; your code here
}

}

  1. It is forbidden to modify class/signature, including but not limited to:
  • Adding inheritance
  • Setting default argument values
  • Adding class elements (Parameters, Methods, Includes, etc).
  1. It is forbidden to refer to non-system code from your entry. For example, this is not a valid entry:
ClassMethod Detector(a As %String, b As %String) As %Boolean
{
  q ##class(myPackage.myClass).test(a)
}
  1. The use of $ZWPACK and $ZWBPACK is also discouraged.
Discussion (33)1
Log in or sign up to continue

Well,  I won't win any prizes but I just wanted to rejoice in writing my first classmethod in objectscript.

Here is my less than elegant solution

ClassMethod Detector(a As %String, b As %String) As %Boolean
{
  SET a=$CHANGE(a," ","")
  SET a=$ZCVT(a,"l")
  SET b=$CHANGE(b," ","")
  SET b=$ZCVT(b,"l")
  SET c = ""
  FOR i = 1 :1 :$L(a)
  {
    SET p = $F(b,$E(a,1))
    if p { SET $E(b,p-1)="" } else { set c=c_$E(a,1) }
    set $E(a,1)=""
  }
  if ($L(a) + $L(b) + $L(c) ) { q 0 } else { q 1 }
}

}
 
Example

Output (tested on IRIS 2021.2CE):

USER>##class(dc.golf.Anagram).Detector("apple""pale")
 
<UNDEFINED>zDetector+2^dc.golf.Anagram.1 *a

If I change Undefined, then there is no error, but the result is incorrect:

USER>d $system.Process.Undefined(2)
 
USER>##class(dc.golf.Anagram).Detector("apple""pale")
"apple":5 - "pale":4
0

The code works correctly if change the signature of the method (ProcedureBlock/PublicList/new), but this is a violation of the conditions of the task.

Here is the code for a 69 character answer

/// 73 characters:
/// f x=a,b{f i=65:1:90{s $li(x(x),i)=$l($zcvt(x,"u"),$c(i))}} q x(a)=x(b)
/// 
/// but this one is 69:
/// 
/// loop ascii number from "A" to "Z" and "[", that's 65 to 91
/// if count of each letter in each string is different then quit loop
/// if loop reached 91 then loop completed and letter counts must be same in both strings
/// if loop didn't reach 91 then must be counts must be different
ClassMethod Detector(As %String, As %String) As %Boolean
{
 i=65:1:91{q:$$r(a)'=$$r(b)i=91
r(x)$l($zcvt(x,"u"),$c(i))
}
 

Excellent work.yes

You have come up with an additional optimization different from mine. Your code can be improved to 66.

 
size = 68
 
size = 67
 
size = 66

I should pay more attention to the $$$MACROs in future!

$ZU(28 is great, it's a shame that Intersystems don't document enough $ZU functions?

The FOR loops that range from 0 to 90/91 don't work with anagrams that contain different numbers of spaces because i=32 checks spaces. E.g. w ##class(CodeGolf.Anagram).Detector("New York Times","monkeys write")

Ah! I stand corrected. Just read %SYSTEM.Util  ALPHAUP removes spaces!