const A_LCASE = 97;
const A_UCASE = 65;
export function isIsogram(word) {
let letter_flags = 0;
for (const letter of [...word]) {
if (letter >= 'a' && letter <= 'z') {
if ((letter_flags & (1 << (letter.charCodeAt(0) - A_LCASE))) != 0)
return false;
else letter_flags |= 1 << (letter.charCodeAt(0) - A_LCASE);
} else if (letter >= 'A' && letter <= 'Z') {
if ((letter_flags & (1 << (letter.charCodeAt(0) - A_UCASE))) != 0)
return false;
else letter_flags |= 1 << (letter.charCodeAt(0) - A_UCASE);
}
}
return true;
}
This solution uses the ASCII value of the letter to set the corresponding bit position.
Some constants are defined for readability in the function.
The ASCII value for a
is 97
.
The ASCII value for A
is 65
.
-
Spread syntax is used to make an
Array
of the characters in theword
. - The
string
loops through its characters and looks for a character beinga
throughz
orA
throughZ
. - If a letter is found, then its ASCII value is taken by the
charCodeAt
method.
charCodeAt
actually returns the UTF-16 code unit for the character, which is an integer between 0
and 65535
.
For the letters a
-z
and A
-Z
, the UTF-16 number is the same value as the ASCII value.
- If the lowercase letter is subtracted by
97
, thena
will result in0
, because97
minus97
equals0
.z
would result in25
, because122
minus97
equals25
. Soa
would have1
shifted left 0 places (so not shifted at all) andz
would have1
shifted left 25 places. - If the uppercase letter is subtracted by
A
, thenA
will result in0
, because65
minus65
equals0
.Z
would result in25
, because90
minus65
equals25
. SoA
would have1
shifted left 0 places (so not shifted at all) andZ
would have1
shifted left 25 places.
In that way, both a lower-cased z
and an upper-cased Z
can share the same position in the bit field.
So, for an unsigned thirty-two bit integer, if the values for a
and Z
were both set, the bits would look like
zyxwvutsrqponmlkjihgfedcba
00000010000000000000000000000001
We can use the bitwise AND operator to check if a bit has already been set.
If it has been set, we know the letter is duplicated and we can immediately return false
.
If it has not been set, we can use the bitwise OR operator to set the bit.
If the loop completes without finding a duplicate letter (and returning false
), the function returns true
.