Kanonenkugel-Rätsel

8

Ihre Aufgabe ist es, mit einer eingegebenen Nummer pdie kleinste positive Kanonenkugelnummer der Reihenfolge zu finden p, die NICHT 1 ist.

Definition

Eine Kanonenkugelnummer (in der Reihenfolge p) ist eine Nummer, die beides ist:

  • Eine p-gonale Zahl ( siehe diese Seite ).
  • und eine p-gonale Pyramidenzahl.

    • Die nth- pgonale Pyramidenzahl ist die Summe der 1. bis nth- pgonalen Zahlen.
      • (zB 4th square pyramid number = 1 + 4 + 9 + 16 = 30)
    • Das Bild unten zeigt die 4. quadratische Pyramidenzahl als quadratische Pyramide. Geben Sie hier die Bildbeschreibung ein

    • Weitere Informationen finden Sie unter diesem Link .

Die Kanonenkugelnummer der Ordnung 3 ist beispielsweise 10, weil es ist:

  • Die vierte Dreieckszahl ( 1 + 2 + 3 + 4 = 10)
  • und die dritte dreieckige Pyramidenzahl. ( 1 + 3 + 6 = 10)

Formeln

HINWEIS: Wenn Sie hier nützlichere Formeln als meine finden (oder erstellen) können, posten Sie diese bitte hier (oder senden Sie mir eine Nachricht in der Frage-Chat-Sache).

  • Wenn Sie interessiert sind, lautet die Formel für die nth- pgonale Zahl:

Geben Sie hier die Bildbeschreibung ein

  • Und die nth- pgonale Pyramidenzahl ist:

Geben Sie hier die Bildbeschreibung ein

Technische Daten

  • p ist garantiert größer als 2.
  • Das Programm muss Werte für eine Lösung für pbis zu (und einschließlich) prüfen 2^16. Ihr Programm kann alles tun, wenn keine Lösungen gefunden werden p.
  • Nur positive Indizes für n.

Testfälle

  • 3Ausgänge 10(4. Dreiecksnummer, 3. Dreieckspyramidenzahl)
  • 4Ausgänge 4900(70. Quadrat Nummer, 24. Quadrat Pyramide Nummer)

Dies ist Code-Golf, also gewinnt die kürzeste Antwort in Bytes.

Hinweis: Wenn Sie eine Lösung veröffentlichen, geben Sie bitte eine Beschreibung der Funktionsweise des Codes an.

Sollte ich ein Kopfgeld für eine Lösung starten, die besser ist und meine Formeln nicht verwendet?

Clismique
quelle
2
Könnten Sie etwas mehr Details darüber hinzufügen, was eine Kanonenkugelnummer ist? Es ist nicht ganz klar aus Ihrer Beschreibung.
James
3
Ist garantiert, dass es für jeden eine Antwort gibt n? Wenn nicht, welchen Bereich werden nSie verwenden?
Geobits
@DrGreenEggsandIronMan Bearbeitet, um eine Definition zu erstellen. n-gonale und n-gonale Pyramidenzahlen sollten nicht definiert werden müssen.
Clismique
@Geobits Bearbeitet, um einen Bereich zu erstellen, anstatt Speicher zu verwenden.
Clismique
1
@DerpfacePython TL; DR: Kanonenkugelnummern sind ziemlich selten. Sieh es dir selbst an.
Rɪᴋᴇʀ

Antworten:

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

Eine Funktion, die Eingaben über Argumente entgegennimmt und die Ausgaben zurückgibt.

Dies ist eine äußerst naive rohe Kraft, die selbst für mäßig große Personen sehr lange dauert p. die Ausführungszeit für etwas Annäherung an das gegebene Maximum für lächerlich pvon 2^16, aber es gibt keinen Grund , warum das Programm nicht funktionieren würde, da genügend Zeit.

Es gibt wahrscheinlich viel kürzere und schnellere Möglichkeiten, dies zu tun, aber ich dachte, es wäre gut, etwas zu posten, um dies in Gang zu bringen.

Wie es funktioniert

Der Rückgabewert xwird auf initialisiert 2, und dann pdurchläuft das Programm einfach alle -gonalen und p-gonalen Pyramidenzahlen bis zur Reihenfolge x. Wenn die aktuellen p-gonalen und p-gonalen Pyramidenzahlen, die anhand der Formeln berechnet wurden, einander und bis gleich sind x, xmuss dies die relevante Kanonenkugelnummer sein, und diese wird zurückgegeben. Andernfalls xwird inkrementiert und das Programm versucht erneut, den neuen Wert von zu ermitteln x.

In Bezug auf das Golfen wird ein kartesisches Produkt verwendet, um die beiden for-Schleifen für die p-gonalen und p-gonalen Pyramidenzahlen zu einer einzigen Schleife zusammenzufassen, und die Formeln wurden weiter faktorisiert, um einige Bytes zu sparen.

TheBikingViking
quelle
Ähm ... das ist vielleicht etwas zu spät, um es zu sagen ... aber ... meine Formel war falsch. Sie müssen nur die polygonale Formel ändern.
Clismique
@DerpfacePython Danke, dass du das verstanden hast.
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}

ungolfed

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 ist nicht in der inneren Schleife , weil das nächste p [b] ist auf jeden Fall größer als das aktuelle g [c] reinitialisiert (so haben wir bewegen auf sowieso)

Beispiele

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
quelle
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;}

Ungolfed mit Testparametern:

#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));
}

Dies nutzt die Tatsache, dass die n-te p-Gonalzahl definiert werden kann als n(1+(p-2)(n-1)/2)und die Pyramidenzahl die Summe der oben genannten Zahlen ist.

Ich denke, es kann weiter gespielt werden, da es nicht wirklich notwendig ist, eine Variable azu speichern.


quelle
Warten Sie ... ist die iin Ihrer Formel die imaginäre Zahl i?
Clismique
Ups, tut mir Leid. isoll sein n. Ich hatte eine andere Notation in meiner Forschung. Ich kann mir nicht vorstellen, eine imaginäre Zahl für dieses Problem zu verwenden, und ich kann mir definitiv nicht vorstellen, sie in C zu verwenden.
0

altes PHP-Programm, 115 106 Bytes

+16 für aktuelles PHP, siehe unten

<?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;
  • Schleifen für immer
  • Verwendung: mit PHP <4.2: Aus dem Browser ausführen mit <scriptpath>?n=<number>
    mit PHP <5.4, hinzufügen register_globals=1zu php.ini(+18?)
  • Eine Beschreibung finden Sie in meiner JavaScript-Antwort
  • +10 für PHP> = 5.4: ersetzen 1durch $n=$_GET[n]. Oder ersetzen 1mit $n=$argv[1], führen php -f <filename> <number>.
  • 6 für die Finite - Schleife auf Erfolg: Ersetzen Sie echo$pmitdie(print$p)
  • +/- 0 für Funktion:

    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;}
    

    Schleifen für immer, wenn es nichts findet. Ersetzen Sie 1durch $p<1e6, um bei 100k zu brechen, oder durch, $p<$p+1um eine Schleife zu erstellen , bis ein ganzzahliger Überlauf auftritt. (getestet mit PHP 5.6)

Beispiele (zur Funktion)

$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);

Beispiele Ausgabe

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
quelle