In 1987, Portuguese poet Alberto Pimenta took the sonnet Transforma-se o amador na cousa amada (The lover becomes the thing he loves), by the 16th-century poet Luís de Camões, and rearranged the letters of each line to produce a new sonnet, Ousa a forma cantor! Mas se da namorada (Dare the form, songster! But if the girlfriend).

Transforma-se o amador na cousa amada,
Por virtude do muito imaginar;
Não tenho logo mais que desejar,
Pois em mim tenho a parte desejada.

Se nela está minha alma transformada,
Que mais deseja o corpo de alcançar?
Em si sómente pode descansar,
Pois consigo tal alma está liada.

Mas esta linda e pura semideia,
Que, como o acidente em seu sujeito,
Assim co'a alma minha se conforma,

Está no pensamento como ideia;
[E] o vivo e puro amor de que sou feito,
Como matéria simples busca a forma.

— Luís de Camões (16e eeuw)

ousa a forma cantor! mas se da namorada
nua d'imagem, tido rio por vir tu
não tens, oh rola joga, sem que ide
ia e mente passem, admito, d'harpejo,

nada, terno mar, falsamente ilhas. amas
desejando amor que cale cio, parcas
rimas e os desencantos pedem
odi et amo, caos, sigla. ali plantas

setas em ideia, ainda mel, puras,
semente que caído sujeito como eu,
a lama minha informam. com acessos

te penso e cato o mínimo. Se nada
muda, vê que frio e pó e riso e voto ou
ímpio amor mat'o ser e busca famas.

— L.C. (Alberto Pimenta, 1987)

Here's Camões' (curiously apposite) original poem, translated by Richard Zenith:

The lover becomes the thing he loves
by virtue of much imagining;
since what I long for is already in me,
the act of longing should be enough.

If my soul becomes the beloved,
what more can my body long for?
Only in itself will it find peace,
since my body and soul are linked.

But this pure, fair demigoddess,
who with my soul is in accord
like an accident with its subject,

exists in my mind as a mere idea;
the pure and living love I'm made of
seeks, like simple matter, form.

Carlota Simões and Nuno Coelho of the University of Coimbra calculated that the letters in Camões' sonnet can be rearranged within their lines in $$5.3 \times 10^{312}$$ possible ways. Interestingly, after Pimenta's anagramming there were two letters left over, L and C, which are the initials of the original poet, Luís de Camões. This is what they said about this observation:

It seems that, in some mysterious and magical way, Luís de Camões came to reclaim the authorship of the second poem as well.

Assignment

An anagram is a word or phrase formed by rearranging the letters of a different word or phrase, using all the original letters exactly once. Anagrams only take into account the letters and their number of occurrences. Other characters that appear in the other word or sentence are ignored. We also make no distinction between uppercase and lowercase letters. For example,

An Eagle lands on Earth's moon, making a first small permanent footprint.

is an anagram of

That's one small step for a man, one giant leap for mankind. — Neil Armstrong

In other words, we consider the letters of a word or a sentence as a multiset: a modification of the concept of a set that, unlike a set, allows for multiple instances for each of its elements.

The number of instances of an element $$e$$ in a multiset $$X$$ is called the multiplicity of that element in the multiset (denoted as $$m_X(e)$$). For example, in multiset $$X = \{a, a, b, b, c, b\}$$ the elements have multiplicities $$m_X(a) = 2$$, $$m_X(b) = 3$$ and $$m_X(c) = 1$$. By definition, the multiplicity $$m_X(d)$$ of an element $$d$$ that does not belong to multiset $$X$$ is equal to $$0$$. The cardinality of a multiset $$X$$ (denoted as $$|X|$$) is computed as the sum of the multiplicities of all its elements. For example, the multiset $$X = \{a, a, b, b, c, b\}$$ has cardinality $$|X| = 6$$.

Define a class Multiset that can be used to represent multisets whose elements consist of the letters of a word or a sentence. The word or the sentence (str) must be passed when creating a multiset (Multiset). Multisets are immutable.

Each multiset $$X$$ (Multiset) must have a property letters that refers to a dictionary (dict) that maps each letter $$e$$ (str; in uppercase) in the word or the sentence onto the number (int) of occurrences of that letter in the word of the sentence (i.e. the multiplicity $$m_X(e)$$). This dictionary may never have any keys with zero multiplicity.

Each multiset $$X$$ (Multiset) must have a methode multiplicity that takes a letter $$e$$ (str). The method must return the multiplicity $$m_X(e)$$. No distinction should made between uppercase and lowercase letters.

If a multiset $$X$$ (Multiset) is passed to the built-in function str, a description (str) of the multiplicity $$m_X(e)$$ of each letter $$e$$ in $$X$$ must be returned. The letters must be listed in alphabetic order. Look at the example below to see how the description should be formatted.

If a multiset $$X$$ (Multiset) 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 multiset (Multiset) with the same letters and multiplicities as $$X$$, with the letters of the multiset in alphabetic order one after the other (in uppercase).

If a multiset $$X$$ (Multiset) is passed to the built-in function len, its cardinality $$|X|$$ must be returned.

For two multisets $$X$$ and $$Y$$ (Multiset), the six comparison operators must get the following meaning:

operator meaning
X == Y $$m_X(e) = m_Y(e)$$ for each letter $$e$$ in $$X$$ or in $$Y$$
X != Y $$m_X(e) \neq m_Y(e)$$ for at least one letter $$e$$ in $$X$$ or in $$Y$$
X <= Y $$m_X(e) \leq m_Y(e)$$ for each letter $$e$$ in $$X$$ or in $$Y$$
X < Y $$m_X(e) \leq m_Y(e)$$ for each letter $$e$$ in $$X$$ or in $$Y$$ and $$X \neq Y$$
X > Y $$m_X(e) \geq m_Y(e)$$ for each letter $$e$$ in $$X$$ or in $$Y$$ and $$X \neq Y$$
X >= Y $$m_X(e) \geq m_Y(e)$$ for each letter $$e$$ in $$X$$ or in $$Y$$

The sum $$X + Y$$ of two multisets $$X$$ and $$Y$$ (Multiset) must yield a new multiset $$Z$$ (Multiset), with $$m_Z(e) = m_X(e) + m_Y(e)$$ for each letter $$e$$ in $$X$$ or in $$Y$$.

The difference $$X - Y$$ of two multisets $$X$$ and $$Y$$ (Multiset) must yield a new multiset $$Z$$ (Multiset), with $$m_Z(e) = m_X(e) - m_Y(e)$$ for each letter $$e$$ in $$X$$ or in $$Y$$. It must always hold that $$m_X(e) - m_Y(e) \geq 0$$ for each letter $$e$$ in $$X$$ or in $$Y$$. If that is not the case, the operation must raise an AssertionError with the message invalid operation.

Example

>>> multiset = Multiset('ELECTION RESULTS')
>>> multiset.letters
{'E': 3, 'L': 2, 'C': 1, 'T': 2, 'I': 1, 'O': 1, 'N': 1, 'R': 1, 'S': 2, 'U': 1}
>>> multiset.multiplicity('T')
2
>>> multiset.multiplicity('e')
3
>>> multiset.multiplicity('X')
0
>>> multiset
Multiset('CEEEILLNORSSTTU')
>>> print(multiset)
C x 1, E x 3, I x 1, L x 2, N x 1, O x 1, R x 1, S x 2, T x 2, U x 1
>>> len(multiset)
15

>>> Multiset('ELECTION RESULTS') == Multiset("lies - let's recount")
True
>>> Multiset('ELECTION RESULTS') != Multiset('illegal votes')
True
>>> Multiset('REELECTIONS') <= Multiset('ELECTION RESULTS')
True
>>> Multiset('candidate') < Multiset('DECONTAMINATED')
True
>>> Multiset('bacteriological') > Multiset('BALLOT')
True
>>> Multiset('swing state') >= Multiset('GIANTESS')
True

>>> Multiset('ELECTION') + Multiset('RESULTS')
Multiset('CEEEILLNORSSTTU')
>>> Multiset('ELECTION') + Multiset('RESULTS') == Multiset("LIES - LET'S RECOUNT")
True
>>> Multiset('misinterpreted') - Multiset('president')
Multiset('EIMRT')
>>> Multiset('misinterpreted') - Multiset('president') == Multiset('merit')
True
>>> Multiset('REPUBLICANS') - Multiset('DEMOCRATS')
Traceback (most recent call last):
AssertionError: invalid operation

Epilogue

In 2014, when designer Nuno Coelho challenged his multimedia students to render the transformation Alberto Pimenta made of the poem by Luís de Camões, Joana Rodrigues offered this:

Sources