Hoje, calcularemos a função binária mais eficiente. Mais especificamente, calcularemos a função que, quando uma expressão é criada a partir da aplicação da função na entrada constante 0 ou em sua própria saída, pode representar todos os números inteiros positivos com as expressões mais curtas possíveis, colocando maior prioridade nos números inteiros menores.
Esta função é criada da seguinte maneira:
Para cada número inteiro, começando em 1 e subindo, escolha a expressão mais curta à qual ainda não atribuímos uma saída e torne esse número inteiro a saída dessa expressão. Os laços no comprimento da expressão serão quebrados pelo argumento menor à esquerda e depois pelo argumento menor à direita. Veja como funciona:
Inicialmente, 1 não está atribuído. A expressão mais curta não atribuída é
f(0, 0)
, portanto, definiremos isso como 1.Agora, 2 não está atribuído. As expressões mais curtas não atribuídas são
f(f(0, 0), 0)
=f(1, 0)
ef(0, f(0, 0))
=f(0, 1)
. Os laços são quebrados para um argumento menor à esquerda, entãof(0, 1) = 2
.A expressão mais curta não atribuída restante é
f(f(0, 0), 0)
=f(1, 0)
, entãof(1, 0) = 3
.Agora, estamos sem expressões com apenas 2 se
f
30
s, então teremos que adicionar mais uma de cada. Rompendo laços com o argumento da esquerda, depois o argumento da direita, entendemosf(0, 2) = 4
desde entãof(0, f(0, f(0, 0))) = f(0, f(0, 1)) = f(0, 2)
.Continuando, temos
f(0, 3) = 5
,f(1, 1) = 6
,f(2, 0) = 7
,f(3, 0) = 8
,f(0, 4) = 9
, ...
Aqui está uma tabela que preenchi para os primeiros valores:
0 1 2 3 4 5 6 7 8
/---------------------------
0| 1 2 4 5 9 10 11 12 13
1| 3 6 14 15 37 38 39 40 41
2| 7 16 42 43
3| 8 17 44 45
4| 18 46
5| 19 47
6| 20 48
7| 21 49
8| 22 50
Outra maneira de ver é que cada saída tem um tamanho igual à soma dos tamanhos de suas entradas mais um. A tabela é preenchida em ordem crescente de tamanho de saída, empates quebrados minimizando a entrada esquerda e a entrada direita.
Seu desafio é, considerando dois números inteiros não negativos como entrada, calcule e produza o valor dessa função. Isso é código de golfe. A solução mais curta, em bytes, vence. As brechas padrão são proibidas.
((0, (0, (0, 0))), 0)
é lexicograficamente menor que(((0, 0), 0), (0, 0))
, no entanto, este último tem um lado esquerdo menor.Respostas:
Haskell, 110 bytes
O argumento aqui é considerado a tupla
(x,y)
. Bem parecido com a resposta acima, mas a lista de pesquisa contém apenas os pares de índices esquerdo e direito em vez das árvores.fonte
head[...]
é[...]!!0
e(p,i)<-zip(concat c)[0..]
pode ser reduzido para(i,p)<-zip[0..]$id=<<c
.id=<<
ao repertório :)Python 3, 154 bytes
Não é muito rápido nem muito golfe, mas é um começo.
fonte
Uau! Na verdade, eu consegui criar um algoritmo de computação eficiente. Eu não esperava isso no começo. A solução é bastante elegante. Deduz repetidamente mais e mais, depois retorna até o caso base de 0. Nesta resposta, a função C (n) indica os números catalães .
O primeiro passo crucial é reconhecer que existem valores C (0) = 1 de comprimento zero (ou seja, o próprio 0), C (1) = 1 valores de comprimento um (ou seja, f (0, 0)), C (2) = 2 valores de comprimento dois (f (0, f (0, 0)) ef (f (0, 0), 0)).
Isso significa que, se estamos procurando a enésima expressão, e encontramos a maior k, de modo que C (0) + C (1) + ... + C (k) <= n, então sabemos que n tem comprimento k .
Mas agora podemos continuar! Porque a expressão que procuramos é a expressão n - C (0) - C (1) - ... - C (k) na sua classe de comprimento.
Agora podemos usar um truque semelhante para encontrar o comprimento do segmento esquerdo e a classificação nessa subseção. E depois recuar sobre as classificações que encontramos!
Ele descobriu que f (5030, 3749) = 1542317211 em um piscar de olhos.
Python, não-competitivo
Estou bastante certo de que estou fazendo um monte de cálculos desnecessários e muitos passos intermediários podem ser removidos.
fonte