# Ondenação de Panqueca Rápida

Ao contrário de outros problemas de ordenação, a operação cara não é a comparação de valores, mas virar as panquecas. Neste exercício, vamos explorar outro algoritmo que tenta reduzir a quantidade de viradas da pilha. O engraçado é que este algoritmo mostrado primeiro por Bill Gates, antes de inventar o Windows.

A ideia básica é aumentar as sequências de panquecas ordenadas, não necessariamente a começar do fundo. Dizemos que uma sequência de panquecas ordenadas constitui um bloco enquanto uma panqueca que não é parte de um bloco é dita livre. O algoritmo então considera o panqueca mais de cima (de raio `t`) e busca pelas panquecas `t+1` ou `t-1` (a vizinhança considerada é `t+o`). Oito casos podem acontecer:

- Caso a: tanto `t` quanto `t+o` são livres. elas são então juntadas numa virada.

- Caso b: `t` é livre e `t+o` é o primeiro de um bloco. Eles são juntados numa virada.

- Caso c: `t` é livre mas tanto `t-1` quanto `t+1` são últimos elementos de blocos. Os blocos e `t` são mesclados juntos em 4 viradas. Cuidado, se `t-1` ou `t+1` não existir (pois `t` é 0 ou max), apenas duas viradas são obrigatórias.

- Caso d: `t` está num bloco mas `t+o` é livre. Eles são mesclados numa virada.

- Caso e: `t` está num bloco e `t+o` é o primeiro elemento de um bloco. Eles são mesclados numa virada.

- Caso f: `t` está num bloco e `t+o` é o último elemento de outro bloco. Eles são mesclados em 3 viradas como segue.

- Caso g: `t` está num bloco de comprimento k+1 (o último elemento é `t+ko`), `t+(k+1)o` é tanto livre ou o último elemento é outro bloco. Ambos os blocos são mesclados em 2 viradas:

- Caso h: `t` está num bloco de comprimento k+1 (o último elemento é `t+ko`), `t+(k+1)o` é o primeiro elemento de outro bloco (a diferença com o caso g é que `t+(k+1)o` é agora o primeiro elemento do bloco dele). Ambos os blocos são mesclados em 2 viradas:

- Caso i: `t` está num bloco de comprimento `n` (este bloco contém todas as panquecas). Se `t` não for 1, a pilha toda destá virada. O algoritmo então pára.

Cada iteração aumenta o tamanho dos blocos, então o algoritmo eventualmente pára em todos os casos. Uma análise mais aprofundada mostrará que leva no máximo `(5n+5)/3` passos para ordenar a pilha. O que é melhor que o algoritmo simplório, que precisa de 2n-3 passos.

## É a sua vez

Agora tem quase toda a informação necessária para implementar este algoritmo por si só. Temos apenas que remover as últimas ambiguidades para garantir que implemente o mesmo algoritmo que a correção. Se vários casos se aplicam à sua situação, deve usar o primeiro que foi dado. Por exemplo, se tanto o caso a quanto o caso b se aplicam (e.g., com `t-1` no a e `t+1` no caso b), deve aplicar as viradas do caso a. Se um dado caso se aplica tanto para `t+1` quanto para `t-1`, então deve aplicá-lo a `t+1`.

Observe que este é de certa forma mais difícil que os outros exercícios que fizemos até agora, logo não se surpreenda se precisar de mais tempo para terminar. Mas não desista, pode conseguir!

Primeiro escreva algumas funções auxiliares tais como `isFirst()` ou `isFree()`. Isto vai simplificar o seu algoritmo principal, que vai poder ser escrito de forma muito similar à explicação acima com um conjunto de condições if. Fatorizar o código desta forma às vezes ajuda a tornar o seu código mais legível.

Para depurar um mundo depois do outro e evitar que as mensagens de todos os mundos fiquem misturadas, pode escrever a sua função de depuração apenas se o método `isSelected()` retorna true. Isto acontecerá apenas para a entidade que estiver selecionada na interface gráfica, que é provavelmente o mundo que está a depurar no momento. Isto vai ajudar a dividir a dificuldade em partes e a depurar a situção uma após a outra.
Em particular, escrever textualmente o estado do mundo cada vez que entrar no loop principal pode ajudar.