Altura da pilha da tigela
O objetivo deste quebra-cabeça é calcular a altura de uma pilha de tigelas.
Uma tigela é definida como um dispositivo radialmente simétrico sem espessura. Seu formato de silhueta é um polinômio uniforme. A pilha é descrita por uma lista de raios, cada um associado a um polinômio par, dado como entrada como uma lista de coeficientes (por exemplo, a lista 3.1 4.2
representa o polinômio ).
O polinômio pode ter grau arbitrário. Por uma questão de simplicidade, a altura da pilha é definida como a altitude do centro da tigela superior (consulte a ilustração do Exemplo 3 para uma ilustração).
Os casos de teste estão no formato radius:coeff1 coeff2 ...
: cada linha começa com um número flutuante que representa o raio da tigela, seguido por dois pontos e uma lista separada por espaços contendo os coeficientes das potências pares, começando com a potência 2 (parte constante zero está implícita) . Por exemplo, a linha 2.3:3.1 4.2
descreve uma tigela de raio 2.3
e o polinômio de forma 3.1 * x^2 + 4.2 * x^4
.
Exemplo 1
42:3.141
descreve uma pilha de altura zero, pois uma única tigela não tem altura.
Exemplo 2
1:1 2
1.2:5
1:3
descreve uma pilha de altura 2.0
(ver gráfico).
Exemplo 3
1:1.0
0.6:0.2
0.6:0.4
1.4:0.2
0.4:0 10
descreve uma pilha de altura 0,8 (veja a seta verde no gráfico).
Isso é código de golfe, então o código mais curto vence.
Eu tenho código de referência .
Editar:
A implementação de referência depende de uma biblioteca para calcular as raízes dos polinômios. Você pode fazer isso também, mas não precisa. Como a implementação de referência é apenas uma aproximação numérica (muito boa), aceitarei qualquer código que produza resultados corretos dentro de tolerâncias comuns de ponto flutuante.
Outra variante desse quebra-cabeça é minimizar a altura reordenando as taças. Não tenho certeza se existe uma solução rápida (acho que é NP-difícil). Se alguém tiver uma ideia melhor (ou puder provar a completude do NP), diga-me!
fonte
is_maximum
deveria ser, por exemploreturn evaluate(differentiate(shape_0), root) > 0.0
. Atualmente, avalia a raiz usandodd
(derivada da diferença entre formas), que sempre deve retornar 0 (para raízes). Devido a erros de ponto flutuante, o resultado é ocasionalmente um valor positivo próximo de 0, razão pela qual o código gera um resultado correto ou mais preciso algumas vezes. Verifique a entrada1:0.2, 1:0.1 0.2
que deve gerar0.0125
0.801
. As duas tigelas finais tocam no raio0.1
.Respostas:
Geléia ,
5453 bytesExperimente online!
Um link monádico que usa como argumento a lista de tigelas de cima para baixo no formato
[[b1_radius, b1_coef1, ...], [b2_radius, b2_coef1, ...]]
e retorna a posição y da parte inferior da tigela superior.Agora lida corretamente com tigelas que se encontram em locais diferentes do raio mínimo.
Explicação
Elo auxiliar: toma como argumento
l
à esquerda as diferenças nos coeficientes dos polinômios que representam as tigelas de 1 para cima, e seu argumentor
à direita no raio mínimo; retorna o valor máximo de y onde as duas tigelas se encontramLink principal, pega uma pilha de tigela como argumento e retorna o valor y da base da tigela superior
Referência do Python
Finalmente, aqui está uma versão TIO da referência do Python que o @pasbi incluiu para o problema principal. Lê de stdin.
fonte
(r1, p1)
e(r2, p2)
no momentomin(r1, r2)
? Nesse caso, seria uma solução errada, porque duas tigelas podem tocar entre0
emin(r1, r2))
. Você precisa encontrarmax(p1(x)-p2(x), 0)
todo o intervalo[0, min(r1, r2)]
parax
. É por isso que a solução de referência do @ pasbi calcula derivadas para encontrar o máximo local.min(r1, r2)
. Agora isso resolve o desafio adicional de @ attinatPython 3 + numpy + scipy,
248240 bytesExperimente online!
-8 bytes graças a @xnor
A função pega uma lista de
[radius, polynomial]
pares como entrada e retorna a altura da pilha.Esta solução usa mais ou menos o mesmo algoritmo que o código de referência, exceto que ele não calcula o máximo usando derivadas. Enquanto isso, ele é escrito usando funções internas
numpy
escipy
em Python. A versão ungolfed é mostrada a seguir. Isso serve como uma versão alternativa do código de referência para quem deseja uma versão mais curta para capturar a ideia rapidamente.Experimente online!
fonte
i=0
como argumento opcional.Wolfram Language (Mathematica) ,
10493 bytesExperimente online!
{radius, polynomial}
Para saída decimal em vez de simbólica, use em
NMaxValue
vez (ou apenas chameN
o resultado).fonte
R ,
451436 bytesExperimente online!
Experimente online!
Em termos gerais, uma porta R da minha resposta Jelly, embora como a base R não tenha função para encontrar as raízes dos polinômios, isso é implementado usando o método encontrado em
polynom::solve.polynomial
.Uma função que obtém uma lista de vetores numéricos de cima para baixo da pilha.
Graças a @RobinRyder por jogar fora 15 bytes!
fonte