Conundrum da bala de canhão


8

Sua tarefa é, com um número de entrada p, encontrar o menor número positivo de bala de canhão da ordem pNÃO 1.

Definição

Um número de bala de canhão (de ordem p) é um número que é ambos:

  • Um pnúmero diagonal ( consulte esta página ).
  • e um pnúmero de pirâmide -gonal.

    • O número da pirâmide nth- pdiagonal é a soma dos números do 1º ao nth- pdiagonal.
      • (por exemplo 4th square pyramid number = 1 + 4 + 9 + 16 = 30)
    • A figura abaixo representa o número da quarta pirâmide quadrada, como uma pirâmide quadrada. insira a descrição da imagem aqui

    • Para mais informações, visite este link .

O número da bala de canhão da ordem 3, por exemplo, é 10, porque é:

  • O quarto número do triângulo ( 1 + 2 + 3 + 4 = 10)
  • e o terceiro número da pirâmide triangular. ( 1 + 3 + 6 = 10)

Fórmulas

NOTA: Se você pode encontrar (ou criar) fórmulas mais úteis do que as minhas aqui, por favor poste aqui (ou me envie uma mensagem sobre o assunto do chat).

  • Se você estiver interessado, a fórmula do número nth- pdiagonal é:

insira a descrição da imagem aqui

  • E o número da pirâmide nth- pdiagonal é:

insira a descrição da imagem aqui

Especificações

  • p é garantido ser maior que 2.
  • O programa deve verificar os valores de uma solução para paté (e inclusive) 2^16. Seu programa pode fazer qualquer coisa se nenhuma solução for encontrada p.
  • Somente índices positivos para n.

Casos de teste

  • 3saídas 10(número do 4º triângulo, número da pirâmide do 3º triângulo)
  • 4saídas 4900(70º número quadrado, 24º número quadrado da pirâmide)

Isso é código-golfe, então a resposta mais curta em bytes vence.

Nota: Se você publicar uma solução, inclua uma descrição de como o código funciona.

Devo começar uma recompensa por uma solução que seja melhor e que não use minhas fórmulas?


2
Você poderia adicionar mais detalhes sobre o que é um número de bala de canhão? Não está totalmente claro em sua descrição.
James

3
É garantido que existe uma resposta para alguma n? Caso contrário, qual é o alcance que nvocê usará?
Geobits 6/07/07

@DrGreenEggsandIronMan Editado para fazer uma definição. nos nnúmeros das pirâmides -gonal e -gonal não precisam ser definidos.
Clismique

@ Geobits Editado para fazer um intervalo em vez de usar memória.
Clismique

1
@DerpfacePython TL; DR: números de balas de canhão são bastante raros. Procure você mesmo.
Rɪᴋᴇʀ

Respostas:


1

Python 3, 129 127 bytes

def f(p):
 x=2
 while 1:
  for i in range(x*x):
   if i//x*((p-2)*i//x+4-p)/2==i%x*(i%x+1)*((p-2)*i%x+5-p)/6==x:return x
  x+=1

Uma função que recebe entrada via argumento e retorna a saída.

Essa é uma força bruta extremamente ingênua e leva muito tempo até para moderadamente grande p; o tempo de execução será ridículo para qualquer coisa que se aproxime do máximo especificado para pof 2^16, mas não há razão para que o programa não funcione, com tempo suficiente.

Provavelmente existem maneiras muito mais curtas e rápidas de fazer isso, mas achei que seria bom postar algo para começar.

Como funciona

O valor de retorno xé inicializado e 2, em seguida, o programa simplesmente faz um loop sobre todos os números piramidais -gonal pe p-onal até a ordem x. Se os números piramidais -gonal pe -onal atuais p, calculados usando as fórmulas, são iguais entre si e para x, então xdeve ser o número relevante da bala de canhão e isso é retornado. Senão, xé incrementado e o programa tenta novamente o novo valor de x.

Em termos de golfe, um produto cartesiano é usado para recolher os dois loops for- pfores para os pnúmeros piramidais -gonal e -onal em um único loop, e as fórmulas foram fatoradas ainda mais para economizar alguns bytes.


Ummm ... isso pode ser um pouco tarde para dizer ... mas ... minha fórmula estava errada. Você só precisa alterar a fórmula poligonal.
Clismique

@DerpfacePython Obrigado por capturar isso.
TheBikingViking

1

JavaScript, 111 98 bytes

f=n=>{for(b=c=g=1;b++;)for(p=b*(b*3+b*b*(n-2)-n+5)/6;g<p;c++)if(p==(g=c*(c*n-c-c-n+4)/2))return p}

destroçado

f=n=>{
for(b=2,c=g=1;b<1e6;b++)    // run index b from 2 (to 100k)
    for(
        p=(b*b*3+b*b*b*(n-2)-b*(n-5))/6 // p=the b-th n-pyramidal number
        ;g<p&&c<1e6;c++)   // run while n-gonal is lower than n-pyramidal (and c below 100k)
        if(p==(
            g=(c*c*(n-2)-c*(n-4))/2     // g=the c-th n-gonal number
        )) return p                     // if they are equal, return
}

c não é reinicializado no loop interno porque o próximo p [b] é definitivamente maior que o atual g [c] (então temos que seguir em frente de qualquer maneira)

exemplos

samples=[3,4,6,8,10,11,14,17,23,26,30,32,35,41,43,50,88]
for(i in samples) document.write('n='+(n=samples[i])+': '+f(n)+'<br>');

0

C, 107 bytes

#define X(x)(1+p/2.0*x)*++x
c(p,m,n,a,b){m=n=a=b=1;p-=2;do if(a>b)b+=X(n);else a=X(m);while(a^b);return a;}

Sem jogar com parâmetros de teste:

#include <stdio.h>

#define X(x)(1+p/2.0*x)*++x
int c(int p)
{
    int m = 1, n = 1, a = 1, b = 1;
    p -= 2;
    do
        if(b < X(m))
            b += X(n);
        else
            a = X(m);
    while(a != b);
    return a;
}

int main()
{
    printf("%d\n", c(3));
    printf("%d\n", c(4));
}

Isso usa o fato de que o n-ésimo número p-gonal pode ser definido como n(1+(p-2)(n-1)/2)e o número da pirâmide é a soma dos números mencionados acima.

Eu acho que pode ser ainda mais jogado, já que não é realmente necessário que a variável aseja salva.


Espere ... o número ida sua fórmula está na sua fórmula i?
Clismique

OPA, desculpe. ideveria ser n. Eu tinha anotações diferentes espalhadas em minha pesquisa. Eu não posso imaginar o uso de um número imaginário para este problema, e eu definitivamente não pode imaginar usá-lo em C.

0

programa PHP antigo, 115 106 bytes

+16 para o PHP atual, veja abaixo

<?for($b=2;1;$b++)for($p=$b*($b*3+$b*$b*($n-2)-$n+5)/6;$g<$p;++$c)if($p==$g=$c*($c*$n-2*$c-$n+4)/2)echo$p;
  • laços para sempre
  • uso: com PHP <4.2: execute a partir do navegador <scriptpath>?n=<number>
    com PHP <5.4, adicione register_globals=1a php.ini(+18?)
  • veja minha resposta JavaScript para descrição
  • +10 para PHP> = 5.4: substitua 1por $n=$_GET[n]. Ou substitua 1por $n=$argv[1], execute php -f <filename> <number>.
  • +6 para loop finito em caso de sucesso: substitua echo$ppordie(print$p)
  • +/- 0 para a função:

    function f($n){for($b=2;1;$b++)for($p=$b*($b*3+$b*$b*($n-2)-$n+5)/6;$g<$p;++$c)if($p==$g=$c*($c*$n-2*$c-$n+4)/2)return$p;}
    

    laços para sempre se não encontrar nada. Substitua 1por $p<1e6para quebrar a 100k ou por $p<$p+1para repetir até que o número inteiro exceda. (testado com PHP 5.6)

exemplos (na função)

$samples=[3,4,6,8,10,11,14,17,23,26,30,32,35,41,43,50,88];
foreach($samples as $n)echo "<br>n=$n: ", f($n);

saída de exemplos

n=3: 10
n=4: 4900
n=6: 946
n=8: 1045
n=10: 175
n=11: 23725
n=14: 441
n=17: 975061
n=23: 10680265
n=26: 27453385
n=30: 23001
n=32: 132361021
n=35: 258815701
n=41: 55202400
n=43: 245905
n=50: 314755
n=88: 48280
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.