Ricbit Jam #2 - Resultado

Este Ricbit Jam convergiu bem rápido, logo nos primeiros dias várias pessoas mandaram a melhor resposta. Pelo critério de desempate, ganha quem mandou primeiro. Por uma vantagem de apenas dez minutos, o vencedor foi o Henrique Pereira (@ikkebr), parabéns!

Algumas pessoas mandaram respostas implementando o Quicksort com ZenoReduce, mas esse algoritmo não é bom na máquina de Zeno. As pessoas que conseguiram chegar no O(1) mandaram variações do Bubblesort e do Insertsort. A solução vencedora, com 76 bytes, foi a abaixo:

import zeno;zenosort=lambda x:zeno.zenoreduce(lambda r,e:sorted(r+[e]),x,[])

Não é óbvio que essa solução é O(1), afinal, ela usa o sorted() do python, que sabemos ser O(n log n). O truque é essa complexidade acaba sendo mascarada. A cada iteração ele adiciona um elemento usando o O(n log n), mas o n começa pequeno, e vai crescendo amortizado pela máquina de Zeno. No final, o tempo utilizado pelo algoritmo é o abaixo, para uma lista de tamanho n:

Uma condição suficiente para que o algoritmo seja O(1) é que essa série seja convergente. Para verificar a convergência, podemos usar o teste das razões, ou seja, o limite do módulo da razão de dois termos consecutivos tem que ser menor que um.

Como todo mundo é positivo, dá pra tirar o módulo. Também podemos jogar um 2 para fora, e a base do logaritmo cancela:

Esse limite é indeterminado da forma infinito/infinito, então dá pra usar o teorema de L'Hospital, ou seja, o limite da razão é igual ao limite da razão das derivadas:

Opa, esse limite também é da forma infinito/infinito, então dá pra usar o L'Hospital de novo:

Concluímos que o limite vale meio, logo ele é menor que um, portanto a série é convergente, e por isso o algoritmo é O(1), QED.


Ricbit Jam #2

O objetivo deste Ricbit Jam é escrever a melhor função de ordenação de listas usando ZenoReduce.

Esse é um exemplo de solução válida:

Solução válida para o Ricbit Jam #2

As soluções serão rodadas da seguinte maneira:

>>> import zeno
>>> import zenosort
>>> zeno.run(lambda:zenosort.zenosort([3,1,4,-2]))
([-2, 1, 3, 4], 0.0, 0.0)

O placar abaixo será atualizado diariamente, conforme as soluções chegarem:

Posição Nome Complexidade Tamanho
1 Henr"Ikke" Pereira O(1) 76
2 girino O(1) 76
3 Renato Cunha O(1) 76
4 Leonardo Fischer O(1) 150
5 Ricardo Bittencourt O(N log N) 95
6 Not RMS O(N log N) 312
7 Raoni Florentino da Silva Teixeira O(N log N) 382