Imagine a necklace with lettered beads that can slide along the string. Here's an example of a necklace whose beads spell the word JESSICA.
In this example we could take the leftmost bead J of the necklace and slide it around to the other end to spell the word ESSICAJ. We could also take the two rightmost beads CA and slide them to the other end to spell the word CAJESSI.
Define a class Necklace that can be used to represent necklaces. A string (str) with the letters on the beads must be passed when creating a necklace (Necklace).
If a necklace (Necklace) is passed to the built-in function str, a string (str) spelling the letters on its beads must be returned. If a necklace (Necklace) is passed to the built-in function repr, a string representation (str) must be returned that reads as a Python expression that creates a new necklace (Necklace) having the same letters on its beads as the necklace passed to the function repr. If a necklace (Necklace) is passed to the built-in function len, the number of beads (int) along its string must be returned.
We must be able to call at least the following methods on a necklace $$n$$ (Necklace):
A method slide that takes a number $$m \in \mathbb{Z}$$ (int). If $$m \geq 0$$ the method must slide the leftmost bead to the other end of the necklace $$m$$ times. If $$m < 0$$ the method must slide the rightmost bead to the other end of the necklace $$|m|$$ times, with $$|m|$$ the absolute value of $$m$$. The method must return a reference to necklace $$n$$.
A method forms that takes no arguments. The method must return a set containing all words (str) that could possibly be spelled by sliding beads from one end to the other end of necklace $$n$$. All these words must be spelled in uppercase, irrespective of the use of uppercase and lowercase letters on the beads of necklace $$n$$. The method may not change the order of the beads along the string of necklace $$n$$.
A method normal_form that takes no arguments. The method must return the word (str, in uppercase) that comes first in lexicographic order among all words that could possibly be spelled by sliding beads from one end to the other end of necklace $$n$$. This word is called the normal form of necklace $$n$$. The method may not change the order of the beads along the string of necklace $$n$$.
Make sure the built-in operator == can be used to check if two necklaces $$n_1$$ and $$n_2$$ (Necklace) are the same. This is the case if necklace $$n_1$$ could be transformed into necklace $$n_2$$ by sliding some beads from one end to the other end of the necklace. However, when comparing the two necklaces, the order of the beads along the strings of $$n_1$$ and $$n_2$$ may not changed and no distinction must be made between uppercase and lowercase letters.
Make sure the built-in operator + can be used to add a necklace $$n$$ (Necklace) and an integer $$m \in \mathbb{Z}$$ (int): both $$n + m$$ and $$m + n$$. The result is a new necklace (Necklace) that is obtained by sliding a bead from one end to the other end of the necklace $$|m|$$ times, as with the method slide. However, when adding $$n$$ and $$m$$, the order of the beads along the string of $$n$$ may not change. If the built-in operator + is used to add a necklace $$n$$ (Necklace) and an object that is not an integer (int), an AssertionError must be raised with the message invalid operation.
>>> necklace = Necklace('Jessica')
>>> necklace
Necklace('Jessica')
>>> print(necklace)
Jessica
>>> len(necklace)
7
>>> necklace.slide(1)
Necklace('essicaJ')
>>> necklace
Necklace('essicaJ')
>>> necklace.slide(-2)
Necklace('aJessic')
>>> necklace.slide(11)
Necklace('sicaJes')
>>> necklace.forms() # doctest: +SKIP
{'SICAJES', 'ESSICAJ', 'AJESSIC', 'JESSICA', 'CAJESSI', 'SSICAJE', 'ICAJESS'}
>>> necklace
Necklace('sicaJes')
>>> necklace.normal_form()
'AJESSIC'
>>> necklace == Necklace('Louise')
False
>>> Necklace('Louise') == Necklace('Elouis')
True
>>> necklace = Necklace('Emily')
>>> necklace
Necklace('Emily')
>>> necklace + 1
Necklace('milyE')
>>> necklace
Necklace('Emily')
>>> -2 + necklace
Necklace('lyEmi')
>>> necklace + 9
Necklace('yEmil')
>>> necklace + 'spam'
Traceback (most recent call last):
AssertionError: invalid operation
According to legend, when the pirate Olivier Levasseur1 was hanged in 1730, he flung a necklace into the crowd, crying,
Find my treasure, the one who may understand it!
The necklace (supposedly) contained this cryptogram, which people have been trying to decipher ever since. The will of fellow pirate Bernardin Nageon de L'Estang (allegedly) refers to
considerable treasure … buried on my dear île de France (now Mauritius)
and the puzzle may or may not be related to carvings found in the rocks at Bel Ombre2 beach in the Seychelles by L'Estang's descendant Rose Savy in 1923.
Does any of this add up to anything? Who knows? Nick Pelling has a good skeptical discussion here3, including an interpretation of the cryptogram as a pigpen cipher4.