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?

clismique
fonte
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.

TheBikingViking
fonte
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>');
Titus
fonte
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.


fonte
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
Titus
fonte