A_LCASE = 97
Z_LCASE = 122
A_UCASE = 65
Z_UCASE = 90
def is_isogram(phrase):
letter_flags = 0
for ltr in phrase:
letter = ord(ltr)
if letter >= A_LCASE and letter <= Z_LCASE:
if letter_flags & (1 << (letter - A_LCASE)) != 0:
return False
else:
letter_flags |= 1 << (letter - A_LCASE)
elif letter >= A_UCASE and letter <= Z_UCASE:
if letter_flags & (1 << (letter - A_UCASE)) != 0:
return False
else:
letter_flags |= 1 << (letter - 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. Python doesn't enforce having real constant values, but using all uppercase letters is the naming convention for a Python constant. It indicates that the value is not intended to be changed.
-
The ASCII value for
a
is97
. -
The ASCII value for
z
is122
. -
The ASCII value for
A
is65
. -
The ASCII value for
Z
is90
. -
A
for
loop is used to iterate the characters in the input phrase. -
The
ord()
function is used to get the ASCII value of the letter. -
The
if
statements look for a character beinga
throughz
orA
throughZ
. -
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 a 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
.